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

时间:2014-03-05 23:36:52

标签: javascript

构造的用法是什么:function F() { if (!(this instanceof F)) { return new F() }; ... }

我在Node的pty.js中找到了这个。这是原始代码:

function Terminal(file, args, opt) {
  if (!(this instanceof Terminal)) {
     return new Terminal(file, args, opt);
  }

  var self = this
     , env
     , cwd
     , name
     , cols
     , rows
     , term;
-------------------SKIP-----------------------------------
  Terminal.total++;
  this.socket.on('close', function() {
     Terminal.total--;
     self._close();
     self.emit('exit', null);
  });

  env = null;
}

3 个答案:

答案 0 :(得分:42)

这意味着如果在没有new运算符的情况下调用函数,它将自动返回一个新实例。

例如,如果你没有这个保护措施,并且做了这个......

var t = Terminal();

...然后执行thisTerminal()将指向window(或您的全局对象,非常喜欢的浏览器人/ gal),绝对

通过确定this实际上是Terminal的实例,我们可以继续。否则,安全措施将返回一个新对象。

然后我们可以简单地使用两种形式......

var t = Terminal(); // Will be same as `new Terminal()`

答案 1 :(得分:10)

即使在没有F的情况下调用new,也只是为了确保它能够正常工作。

当您使用F致电new时,该功能this是新实例。

然后,如果this不是F!(this instanceof F))的实例,则表示F未使用new调用。在这种情况下,F会调用自身,现在使用new

答案 2 :(得分:9)

除了这个主题中的重要解释之外,看看幕后发生了什么是很有趣的。 ECMAScript规范(Javascript所基于的地方)defines 全局对象。这在不同的执行环境中以不同方式实现。在典型的浏览器中,它是window对象,而在Node.js中,它是root对象。每个功能都定义在野外#34; (未附加到用户创建的对象)将成为全局对象的属性。在Node.js中,您可以尝试:

> function Test() {};
> root.Test
[Function: Test]

现在,this变量指向该函数所属的对象。所以在上面的例子中:

> function Test() { 
... console.log(this === root); 
... };
> Test()
true

您的函数Terminal也是如此。如果您运行它,this将指向全局对象,当然Terminal的实例!

使用new运算符调用函数时,会返回一个对象,该对象可以访问一个名为constructor的属性,该属性将指向该函数。它等同于:

> var instance = {};
> instance.constructor = Terminal;
> instance.constructor();

因此,当条件失败并且终端函数通过new Terminal()行运行时,this将指向新创建的实例,其中 类型为Terminal!< / p>

如果您想获得更多技术,instance本身没有constructor属性。它相反(通过原型链*)链接到私有对象**(由运行时创建),其具有指向终端函数的constructor属性。该私有对象由函数通过prototype属性指向返回D.Crockford伪代码中显示如下:

Terminal.prototype = {constructor: Terminal};

再次,当您使用new调用该函数时,这只是

*如果找不到属性,对象将在__proto__属性指向的对象处查找。

**(想象一下名为_Terminal的对象,你无法按名称访问)