'this'何时不是定义函数的实例?

时间:2014-02-03 13:19:30

标签: javascript new-operator instanceof

我想了解以下Javascript代码:

var Query = function(config, values, callback) {

  // use of "new" optional
  if(!(this instanceof Query)) { return new Query(config, values, callback); }

  ...

};

如果有人拨打new Query(...),何时以及为什么this不会成为查询的实例?为什么这段代码会测试这种可能性?它解决了什么问题?

3 个答案:

答案 0 :(得分:2)

这是称为“自我调用构造函数”的JavaScript模式(选中JavaScript Patterns)。

如果调用函数Query

Query();

然后this将不是Query的实例。 该代码确保无论Query如何被调用,将使用构造函数Query创建新对象。

例如:

function foo() {
}

console.log(foo());           //undefined
console.log(foo.call(null));  //undefined
console.log(foo.apply(null)); //undefined
console.log(new foo());       //object, instance of foo

但是如果:

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

console.log(foo());           //object, instance of foo
console.log(foo.call(null));  //object, instance of foo
console.log(foo.apply(null)); //object, instance of foo
console.log(new foo());       //object, instance of foo

答案 1 :(得分:1)

此代码仅防止在有人忘记添加new时可能出现的错误:在这种情况下它的工作方式相同。

我经常看到这种模式。在我看来这很糟糕:你不应该试图防止错误地滥用你的API,特别是因为它可能会让那些知道new的人更加模糊用户代码。这不像new是一个特别高级的JavaScript功能......最好是失败,而不是让各种看似无效的用户代码神奇地有效。

答案 2 :(得分:1)

此代码可以将Query构造函数与newnew语句一起使用,如果您将使用

var bla = Query();

this将会window,它会在Query函数中进行检查并调用new Query(),这次this instanceof Query将返回true