JavaScript 中:`function Person(){}`、`const person = Person()` 和 `const person = new Person()` 的区别?
TL;DR
function Person(){}
:JavaScript 中的函数声明。它可以作为常规函数或构造函数使用。const person = Person()
:将Person
作为常规函数调用,而不是构造函数。如果Person
旨在用作构造函数,这将导致意外行为。const person = new Person()
:创建Person
的新实例,正确利用构造函数来初始化新对象。
方面 | function Person(){} | const person = Person() | const person = new Person() |
---|---|---|---|
类型 | 函数声明 | 函数调用 | 构造函数调用 |
用法 | 定义一个函数 | 将 Person 作为常规函数调用 | 创建 Person 的新实例 |
实例创建 | 未创建实例 | 未创建实例 | 创建新实例 |
常见错误 | N/A | 误用作构造函数,导致 undefined | 无(正确使用时) |
函数声明
function Person(){}
是 JavaScript 中的标准函数声明。当用 PascalCase 编写时,它遵循旨在用作构造函数的函数的约定。
function Person(name) {this.name = name;}
此代码定义了一个名为 Person
的函数,该函数接受一个参数 name
并将其分配给从此构造函数创建的对象的 name
属性。当在构造函数中使用 this
关键字时,它指的是新创建的对象。
函数调用
const person = Person()
只是调用该函数的代码。当您将 Person
作为常规函数调用(即,不使用 new
关键字)时,该函数的行为不像构造函数。相反,它执行其代码,如果未指定返回值,则返回 undefined
,并将其分配给作为实例的变量。如果该函数旨在用作构造函数,则这样调用是一个常见的错误。
function Person(name) {this.name = name;}const person = Person('John'); // Throws error in strict modeconsole.log(person); // undefinedconsole.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
在这种情况下,Person('John')
不会创建新对象。person
变量被赋值为 undefined
,因为 Person
函数没有显式返回值。尝试访问 person.name
会抛出错误,因为 person
是 undefined
。
构造函数调用
const person = new Person()
使用 new 运算符创建 Person
对象的实例,该实例继承自 Person.prototype
。另一种方法是使用 Object.create
,例如:Object.create(Person.prototype)
和 Person.call(person, 'John')
初始化对象。
function Person(name) {this.name = name;}const person = new Person('John');console.log(person); // Person { name: 'John' }console.log(person.name); // 'John'// Alternativeconst person1 = Object.create(Person.prototype);Person.call(person1, 'John');console.log(person1); // Person { name: 'John' }console.log(person1.name); // 'John'
在这种情况下,new Person('John')
创建一个新对象,Person
中的 this
指的是这个新对象。name
属性在新对象上被正确设置。person
变量被分配了 Person
的新实例,其 name 属性设置为 'John'
。对于备用对象创建,Object.create(Person.prototype)
创建一个新对象,并将 Person.prototype
作为其原型。Person.call(person, 'John')
初始化对象,设置 name
属性。
后续问题
- 函数构造函数和 ES6 类语法之间有什么区别?
Object.create
的一些常见用例是什么?