JavaScript构造函数可以返回函数并保持继承吗?

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?

7
函数是一种对象,因此可以返回一个函数。但显然,f instanceof F不会成立,因为这是错误的。 - Felix Kling
1
Felix:就像重言式是重言式一样? :) - Niklas B.
为什么你想让 instanceof 起作用呢?它通常被认为是有害的。 - zetlen
6
问题仍然是:你想要实现什么目标? - Niklas B.
似乎不需要从构造函数中返回此内容以使instanceof正常工作。请参见此处的示例:http://jsfiddle.net/ukttM/ - Lior
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__ 的浏览器中使用。


5

如果您将F.prototype = Function.prototype;设置为代码中的所有函数,那么所有函数看起来都属于instanceof F

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

但是,在Gecko中,您可以使用已弃用的__proto__属性来实现此目的:

function F() {
    function f() {
        return {};
    }
    f.__proto__ = F.prototype;
    return f;
 }
 F.prototype.__proto__ = F.__proto__;

Esailia更快,因此他的答案被接受了。无论如何还是谢谢! - Sixtease
@Sixtease 好的,但请注意他的答案不会让你在他的对象上使用例如.apply.call,因为他没有我所拥有的额外行。 - Neil
@Neil,F.prototype.proto = F.proto; 到底是做什么的?如果我不这样做会发生什么? - esp
@esp 抱歉,我记不起来了。 - Neil

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'

-1
在你的例子中,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);
​

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接