instanceof,范围和对象

时间:2013-12-05 14:12:32

标签: javascript scope instanceof

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

'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构造函数的实例。

3 个答案:

答案 0 :(得分:5)

您明确地从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调用构造函数。此外,即使您使用fooFactory调用new,它也绝对没有区别,因为您无论如何都明确返回了对象文字。事实上它会慢一点。
  2. 不是使用构造函数返回一个对象而是另一个实例化构造函数的函数,而不是简单地返回新创建的构造函数本身?由于您的工厂名为fooFactory,我认为它返回foo而不是具有foo属性的对象。
  3. 如果您要创建一个函数并将其用作构造函数,则不要显式返回该对象。使用new调用函数时,JavaScript会自动创建该函数的prototype的新实例,并将其绑定到函数内的this。只要您没有从构造函数显式返回对象,就会自动返回函数this
  4. 希望有所帮助。

答案 1 :(得分:1)

为了澄清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!

答案 2 :(得分:0)

删除函数foo()

中的return语句
  

返回{               getName:getName           }

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

但你做了明确的返回对象{ getName: getName }

{ getName: getName } is not child of function foo