给出以下代码,我将记录Person原型的2个实例
function Person(name) {
this.name = name
}
person = new Person('bob');
person2 = new person.constructor('tom')
console.log(person);
console.log(person2);
有趣的是,如果我们像下面的示例一样省略new
关键字:
function Person(name) {
this.name = name
}
person = new Person('bob');
person2 = person.constructor('tom')
console.log(person);
console.log(person2);
实际上似乎重新构造了构造函数,并使用新参数对对象进行了变异。这是怎么回事吗?
如果没有new
关键字,则什么也不会返回到person2
。并且person
的名称属性现在为'tom'
。
如果before为true,则不带new
关键字的构造函数会使原始对象发生突变,是否存在用例需要再次在对象上调用构造函数的情况?
答案 0 :(得分:3)
如果在没有new
关键字的情况下调用ES5构造函数(即,调用了 而不是 constructed ),则它没有{{1 }}语句,它将返回return
。
此外,您正在通过this
undefined
调用person
作为函数调用的dot notation上下文的构造函数,这等效于{{3} },因此它将覆盖您初始化的第一个实例的名称。
当ES5是最新规范时,一种相关的模式在某种程度上曾经很常见,那就是通过使用person.constructor.call(person, 'tom')
检查来避免滥用该构造函数,从而使用自校正构造函数。在这种情况下不会被捕获,但是如果您调用person.constructor('tom')
而不是Person('tom')
会被捕获,这会更常见:
new Person('tom')
答案 1 :(得分:2)
当您不使用new
时,Person
只是一个常规函数。调用它将接受一个参数,并在name
上设置this
属性。以这种方式调用this
是指您刚刚创建的实例。该函数不返回任何内容,因此本质上是一个setter。
您偶尔会在继承模式中看到这种对构造函数的使用:
function SuperClass(name) {
this.name = name
}
function ChildClass(city, name) {
this.city = city
// use the superClass constructor to set properties:
SuperClass.call(this, name)
}
// manipulate prototype
let me = new ChildClass("Anchorage", "Mark")
console.log(me)
在其他情况下利用此功能可能会使您不必要地混淆,因为您只能创建专用的setter函数。
答案 2 :(得分:1)
来自MDN的有关new
运算符的信息:
new运算符创建用户定义对象类型的实例,或者 具有构造函数的内置对象类型之一 函数。new关键字执行以下4件事
- 它凭空创造了一个全新的物体。
- 它将这个对象链接到另一个对象
- 步骤1中新创建的对象作为此上下文传递
- 如果函数未返回其自身的对象,则返回该
如果在不使用new运算符的情况下调用构造函数,则该构造函数的操作就像其他Object方法一样。