Javascript 对构造函数原型方法不使用'new'关键字会改变原始对象

Javascript 对构造函数原型方法不使用'new'关键字会改变原始对象,javascript,Javascript,给定以下代码,我将记录Person原型的2个实例 function Person(name) { this.name = name } person = new Person('bob'); person2 = new person.constructor('tom') console.log(person); console.log(person2); 有趣的是,如果我们省略新关键字,如以下示例所示: function Person(name) { this.name = name

给定以下代码,我将记录Person原型的2个实例

function Person(name) {
  this.name = name
}

person = new Person('bob');
person2 = new person.constructor('tom')
console.log(person);
console.log(person2);
有趣的是,如果我们省略新关键字,如以下示例所示:

function Person(name) {
  this.name = name
}

person = new Person('bob');
person2 = person.constructor('tom')
console.log(person);
console.log(person2);
实际上,构造函数似乎正在重新运行,并使用新参数对对象进行变异。这是怎么回事

没有new关键字,person2就不会返回任何内容。这个人的名字属性现在是“汤姆”


如果before为true,则不带new关键字的构造函数会对原始对象进行变异,是否存在希望再次调用对象上的构造函数的用例?

如果调用ES5构造函数时不带new关键字,即called而不是constructed,并且没有return语句,它将返回未定义

此外,您正在通过person.constructor'tom'调用带有person的构造函数作为函数调用的上下文,这相当于,因此它将覆盖您初始化的第一个实例的名称

当ES5成为最新的规范时,一个相关的模式是使用自校正构造函数,通过使用检查来方便地避免误用构造函数。在本例中,它不会被捕获,但如果您调用了人称“tom”而不是新的人称“tom”,则会被捕获,后者更常见:

函数人名{ 如果!此Person实例返回新Personname; this.name=名称; } console.lognewperson'bob';
控制台。logPerson'tom' 如果调用ES5构造函数时没有new关键字,即调用而不是构造,并且它没有return语句,那么它将返回undefined

此外,您正在通过person.constructor'tom'调用带有person的构造函数作为函数调用的上下文,这相当于,因此它将覆盖您初始化的第一个实例的名称

当ES5成为最新的规范时,一个相关的模式是使用自校正构造函数,通过使用检查来方便地避免误用构造函数。在本例中,它不会被捕获,但如果您调用了人称“tom”而不是新的人称“tom”,则会被捕获,后者更常见:

函数人名{ 如果!此Person实例返回新Personname; this.name=名称; } console.lognewperson'bob'; 控制台。logPerson'tom' 来自MDN关于新运营商的信息:

新操作符创建用户定义的对象类型的实例或 具有构造函数的内置对象类型之一 新关键字做以下4件事

它用稀薄的空气创造了一个全新的物体。 它将此对象链接到另一个对象 步骤1中新创建的对象作为此上下文的 如果函数不返回它自己的对象,则返回它自己的对象 如果在不使用新运算符的情况下调用构造函数,则它的操作与任何其他对象方法一样。

来自MDN,关于新运算符:

新操作符创建用户定义的对象类型的实例或 具有构造函数的内置对象类型之一 新关键字做以下4件事

它用稀薄的空气创造了一个全新的物体。 它将此对象链接到另一个对象 步骤1中新创建的对象作为此上下文的 如果函数不返回它自己的对象,则返回它自己的对象 如果在不使用new运算符的情况下调用构造函数,它的操作与任何其他对象方法一样。

如果不使用new,Person只是一个常规函数。调用它将使用一个参数,并在此参数上设置name属性。以这种方式调用它指的是您刚刚创建的实例。该函数不返回任何内容,因此它本质上是一个setter

您偶尔会在继承模式中看到构造函数的这种用法:

函数超类名{ this.name=name } 函数、城市、名称{ 这个城市 //使用超类构造函数设置属性: SuperClass.callthis,name } //操纵原型 马克,我是新来的孩子 当您不使用new时,Person只是一个常规函数。调用它将使用一个参数,并在此参数上设置name属性。以这种方式调用它指的是您刚刚创建的实例。该函数不返回任何内容,因此它本质上是一个setter

您偶尔会在继承模式中看到构造函数的这种用法:

函数超类名{ this.name=name } 函数、城市、名称{ 这个城市 //使用超类构造函数设置属性: SuperClass.callthis,name } //操纵原型 马克,我是新来的孩子
logme只是一个猜测,但如果您使用

对象作为一个单体,并希望通过构造函数改变其中的一些值。为什么不在这种情况下使用实例方法呢?正如我所说的,我只是猜测,我真的没有一个具体的例子。也许其他人会。我想这一切都应该从构造函数的定义开始。然后我们讨论为什么我们要将其用于其预期用途以外的用途。这就是构造函数在没有new关键字的情况下所做的吗?只是猜测,但如果您将对象作为一个单独的对象使用,并且希望通过构造函数来更改其中的某些值,那么为什么不在这种情况下使用实例方法,就像我所说的,我只是猜测,我真的没有一个具体的例子。也许其他人会。我想这一切都应该从构造函数的定义开始。然后我们讨论了为什么我们希望将其用于其预期用途以外的用途。但是,这就是没有新关键字的构造函数所做的吗?太棒了,没有新关键字的构造函数有使用案例吗?我很难称之为用例,甚至称之为不好的实践,但是是的,这种行为是由语言规范很好地定义的。太棒了,没有new关键字的.constructor是否有一个用例?我几乎不会把它称为一个坏习惯,但是是的,这种行为是由语言规范很好地定义的。在这种情况下,它改变了对象,.constructor是否有任何用例?Andrew Kim所说的-无需重复。在这种情况下,哪些会改变对象,是否有.constructor的用例?Andrew Kim所说的-无需重复。