2

这是一个新手查询。我经历了几篇类似的帖子,但它们对我的帮助还不够。这篇文章有 2 个查询,但因为它们的根似乎相同,所以将它们放在一起。

我遇到了以下代码片段:

var Server = module.exports.Server = function Server(listener) {
  if (!(this instanceof Server)) return new Server(listener);
  //other code
}

module.exports.createServer = function(listener) {
  return new Server(listener);
};

我无法理解 if (!(this instanceof Server)) ;this 什么时候不能在这里指向 Server 的使用?

我尝试对此进行快速测试:

var createTest = function(){
    console.log(this.toString());
    return new Test();
};

var Test = function Test(){
    console.log(this instanceof Test);
    console.log(this.toString());
    if (!(this instanceof Test)) 
    {
        return new Test();
    }
}

var tester = createTest();

输出:

[object global]
true
[object Object]

这进一步让我困惑为什么 this.toString 打印 [object Object] - 它不应该是 [object Test] 吗?

谢谢 !

4

2 回答 2

5

这是一个用来使new可选的成语。例如:

function TraditionalTest() {
}
function IdiomaticTest() {
    if(!(this instanceof IdiomaticTest)) return new IdiomaticTest();
}

console.log(new TraditionalTest());  // [object Object]
console.log(TraditionalTest());      // undefined
console.log(new IdiomaticTest());    // [object Object]
console.log(IdiomaticTest());        // [object Object]

至于为什么是[object Object]而不是[object Test],我不知道为什么它是这样定义的,但这就是它的定义方式

调用该toString方法时,将执行以下步骤:

  1. 如果this值为undefined,则返回“ [object Undefined]”。
  2. 如果this值为null,则返回“ [object Null]”。
  3. 令 O 为调用 ToObject 并将this值作为参数传递的结果。
  4. classO的 [[Class]] 内部属性的值。
  5. [object返回作为连接三个字符串“ ”、“”和“ ”的结果的字符串值]

[[Class]] 在规范中被多次引用,但它只表示内置类型:

  • Arguments
  • Array
  • Boolean
  • Date
  • Error
  • Function
  • JSON
  • Math
  • Number
  • Object
  • RegExp
  • String
于 2012-10-10T04:22:20.063 回答
1

该测试确保为这两种用途创建了一个新的服务器实例:

new module.exports.Server()

并为:

module.exports.Server()

在第二个中,this指针将是全局对象,因此不会是一个 instanceof Test。在这种情况下,代码意识到构造函数只是被直接调用而new没有创建新对象。由于这不是构造函数的预期用途,因此它new通过调用 a 并返回结果来强制使用 a。

于 2012-10-10T04:22:15.497 回答