首页 > 解决方案 > 不带new关键字调用构造函数的两种情况比较

问题描述

function Person(name, age, gender) {
  this.name = name; // run
}

function PersonSafe(name) {
  if (!(this instanceof arguments.callee))
    return new PersonSafe(name)

  this.name = name; // run
}

var qux = Person('qux');
console.log('Person qux: ', qux);
console.log('[[global]] name: ', name);

var quxSafe = PersonSafe('qux');
console.log('PersonSafe qux: ', quxSafe);

在此处输入图像描述

在没有关键字的情况下constructor调用的两种情况的比较。 我不知道为什么运行这两个代码的结果不同。of和函数不同,但和将执行 的行 ( )是相同的。那么......为什么结果不同?new


bodyPerson()PersonSafe()
this.name = name;quxquxSafe

标签: javascriptconstructor

解决方案


当您将函数作为构造函数调用时此处Person为. 该对象也将在构造函数的末尾隐式返回。Person.prototypethis

相反,当您使用时new,不会创建这样的对象;您只是在调用一个普通函数,其中的this值将取决于函数的调用上下文。在这里,因为没有调用上下文(被调用的函数不是对象的一部分),this所以函数内部要么是全局对象(在 sloppy 模式的情况下),要么是undefined(在严格模式的情况下)。

如此var qux = Person('qux');运行this.name = namethis全局对象在哪里。

使用PersonSafe,您正在检查this是构造函数的一个实例(this具有构造函数原型的内部原型) - 如果没有调用new,该测试将失败,因为this将是全局对象或undefined.

请注意,arguments.callee在严格模式下是禁止的,并且几乎总是应该使用严格模式。考虑替换为new.target

function PersonSafe(name) {
    if(!(new.target))
        return new PersonSafe(name)

    this.name = name; // run
}

var quxSafe = PersonSafe('qux');
console.log('PersonSafe qux: ',quxSafe);


推荐阅读