测验

JavaScript 中:`function Person(){}`、`const person = Person()` 和 `const person = new Person()` 的区别?

主题
JavaScriptOOP
在GitHub上编辑

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 mode
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined

在这种情况下,Person('John') 不会创建新对象。person 变量被赋值为 undefined,因为 Person 函数没有显式返回值。尝试访问 person.name 会抛出错误,因为 personundefined

构造函数调用

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'
// Alternative
const 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 的一些常见用例是什么?

延伸阅读

在GitHub上编辑