【问题标题】:instanceof, scopes and objectsinstanceof、范围和对象
【发布时间】:2013-12-05 14:12:31
【问题描述】:

有人可以向我解释一下这种行为吗?

'use strict'

var fooFactory = function() {

    function foo() {
        var name = "foo object";

        function getName() {
            return name;
        }

        return {
            getName: getName
        }
    }

    function getFoo() {
        return new foo;
    }

    return {
        getFoo: getFoo,
        foo: foo
    }
};

var factory = new fooFactory();

var bar = factory.getFoo();

console.log("is " + bar.getName() + " instance of foo: " + (bar instanceof factory.foo)); 
// outputs "is foo object instance of foo: false"

我不明白,为什么 foo 对象不是我在 fooFactory 中声明的 foo 构造函数的实例。

【问题讨论】:

    标签: javascript scope instanceof


    【解决方案1】:

    您从foo 函数显式返回一个对象。该对象不是foo 的实例。因此bar 不是foo 的实例。这就是我将重写您的代码的方式:

    var foo = fooFactory();
    
    var bar = new foo;
    
    console.log("is " + bar.getName() + " instance of foo: " +
        bar instanceof factory.foo);
    
    function fooFactory() {
        return function () {
            var name = "foo object";
    
            this.getName = function () {
                return name;
            };
        };
    }
    

    之所以会这样写,原因如下:

    1. 不应使用new 调用工厂函数。只有构造函数应该用new 调用。此外,即使您确实使用new 调用fooFactory,也绝对没有区别,因为无论如何您都明确地返回了一个对象文字。事实上它会更慢。
    2. 与其返回一个带有构造函数的对象和另一个实例化构造函数的函数,不如简单地返回新创建的构造函数本身吗?由于您的工厂名为fooFactory,我假设它返回foo,而不是具有foo 属性的对象。
    3. 如果您要创建一个函数并将其用作构造函数,则不要显式地从它返回一个对象。当您使用 new 调用函数时,JavaScript 会自动创建该函数的 prototype 的新实例,并将其绑定到函数内部的 this。只要您没有从构造函数显式返回对象,this 就会自动返回。

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      为了澄清 Aadit 的答案,问题在于这一行:

      return {
          getName: getName
      }
      

      删除它并将“getName”更改为“this.getName”,您的函数将按预期工作。

      var fooFactory = function() {
      
          function foo() {
              var name = "foo object";
      
              // changed!
              this.getName = function() {
                  return name;
              }
      
              // no return
          }
      
          function getFoo() {
              return new foo;
          }
      
          return {
              getFoo: getFoo,
              foo: foo
          }
      };
      
      var factory = new fooFactory();
      
      var bar = factory.getFoo();
      
      console.log("is " + bar.getName() + " instance of foo: " + (bar instanceof factory.foo)); 
      // true!
      

      【讨论】:

        【解决方案3】:

        删除函数 foo() 中的 return 语句

        返回 { 获取名称:获取名称 }

        new运算符隐式返回函数foo的子实例,

        但您确实明确返回对象{ getName: getName }

        { getName: getName } is not child of function foo

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-07
          • 2015-11-05
          • 2013-04-11
          相关资源
          最近更新 更多