从对象返回函数会破坏instanceof

时间:2012-05-10 15:11:43

标签: javascript oop

这个小宝石让我有点头疼。假设我创建了一个返回函数的对象,如下所示:

function Bar(prop) {
    this.prop = prop;
    var that = this;
    return function() {
        this.prop = that.prop;
    }
}

var bar = new Bar();
console.log(bar instanceof Bar)​;
正如您所见,

Bar()会返回一个函数。现在,Bar() instanceof Bar返回false,这不是我想要的。如何查看new Bar()Bar的实例?这甚至可能吗?

2 个答案:

答案 0 :(得分:3)

从构造函数返回任何对象将使用该对象,而不是返回由构造函数自动生成的实例。这有点抽象,所以这里有一个例子来说明我的观点:

function Foo() {}
function Bar() {
    return new Foo();
}
f = new Foo();
console.log(f instanceof Foo); //true
b = new Bar();
console.log(b instanceof Bar); //false
console.log(b instanceof Foo); //true

JavaScript中的所有内容都是一个对象,包括函数,因此foo.bar函数返回一个函数的事实意味着当你调用new foo.bar()时,你将收到{{1}返回的函数而不是新的foo.bar实例。


虽然我并不是100%肯定你正在尝试做什么,但可以检查函数是作为对象初始化程序调用还是作为函数简单地使用{{ 1}}在上下文中。此模式通常用于强制对象初始化:

foo.bar

这允许将instanceof作为函数调用,并仍然返回一个新的function Foo(...arguments...) { if (!(this instanceof Foo)) { return new Foo(...arguments...); } //do stuff } 实例:

Foo

答案 1 :(得分:0)

不完全确定你为什么要做你正在做的事情,但我知道问题是什么。

在'test'的范围内,this.bar是函数bar(prop),而不是由于执行此函数而返回的函数,如果这是有意义的。但是,new this.bar('hi')将首先执行bar('hi'),它返回一个匿名函数,然后作为构造函数。

换句话说,您正在将从匿名函数创建的实例与不同的函数进行比较,因此instanceof正确地返回false。

以下日志“真实”但可能不是您要找的:

function foo() {
    this.test = function() {
        var cls = this.bar('hi');
        console.log(new cls() instanceof cls);
    };

    this.bar = function bar(prop) {
        this.prop = prop;
        var that = this;
        return function() {
            this.prop = that.prop;
        }
    }
}

var test = new foo();
test.test();