16
function F() {
    return function() {
        return {};
    }
}

var f = new F();
f instanceof F; // returns false

据我了解,如果我想instanceof工作,我需要this从构造函数返回。但我希望构造函数返回一个函数,我不能分配给this.

那么,这真的是不可能的,还是可以以某种方式完成,f = new F()返回一个函数并仍然f instanceof F返回 true?

4

4 回答 4

8
function F() {
    var r = function() {
        return {};
    };

    r.__proto__ = this.__proto__;
    return r;
}

var f = new F();
f instanceof F;
true
f();
Object

仅适用于具有__proto__

于 2012-04-26T21:05:59.153 回答
5

您当然可以instanceof F通过设置使所有功能看起来都是F.prototype = Function.prototype;.

不幸的是,ECMAScript 似乎不允许您创建函数子类。

但是,您可以使用已弃用的__proto__属性在 Gecko 中执行此操作:

function F() {
    function f() {
        return {};
    }
    f.__proto__ = F.prototype;
    return f;
 }
 F.prototype.__proto__ = F.__proto__;
于 2012-04-26T21:09:26.910 回答
1

对于今天遇到此问题的任何人,使用 ES6/2015 可以使用新语法来避免已弃用的__proto__属性;Object.setPrototypeOf. 请注意,MDN 警告说这是一个缓慢/昂贵的操作。

function F() {
    const f = function() {
        return {};
    }
    Object.setPrototypeOf(f, F.prototype);
    return f;
}

var f = new F();
f instanceof F; // returns true
f(); // returns {}

另请注意,如果您想在构造函数中初始化值,它会变得有点奇怪。您需要将它们设置为您将返回的函数的道具,但稍后对原型的添加会将它们引用为“this”。例如

function F() {
    const f = function() {
        return {};
    }
    f.favoriteBand = 'The Books';
    Object.setPrototypeOf(f, F.prototype);
    return f;
}
F.prototype.getFavoriteBand = function(){ return this.favoriteBand; }

var f = new F();
f.getFavoriteBand() // returns 'The Books'
于 2016-04-04T22:51:26.740 回答
0

在您的示例中, F 不是构造函数,它是一个返回匿名构造函数的函数,然后您调用 new 。instanceof 通过查看原型链来工作,因此您的代码不起作用,因为您没有正确设置原型。

这个页面很好地解释了 JavaScript 构造函数以及如何子类化。

看看下面的代码,看看它是否有帮助。

function F() {
    this.whoami = 'F';
    this.whatami = 'F';

}

function Sub() {
 this.whoami = 'G';
}

Sub.prototype = new F();

function G() {
    return new Sub;
}

var f = new G();
console.log(f instanceof F); // returns false
console.log(f.whoami);
console.log(f.whatami);
​
于 2012-04-26T21:04:39.293 回答