Can JavaScript constructor return function and keep inheritance?

一个人想着一个人 提交于 2019-12-03 19:51:53

问题


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

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

As far as I understand, if I want instanceof to work, I need to return this from the constructor. But I want the constructor to return a function, and I cannot assign to this.

So, is this really impossible or can it be done somehow, for f = new F() to return a function and still f instanceof F to return true?


回答1:


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

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

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

Only works in the browsers with __proto__




回答2:


You could of course make all functions appear to be instanceof F by setting F.prototype = Function.prototype;.

Unfortunately it looks as if ECMAScript doesn't allow you to create a function subclass.

You can however do it in Gecko using the deprecated __proto__ property:

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



回答3:


To anyone coming across this today, with ES6/2015 there's new syntax you can use to avoid the deprecated __proto__ property; Object.setPrototypeOf. Note that MDN warns that this is a slow/expensive operation.

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

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

Note also that it gets a little weird if you want to initialize values in the constructor. You need to set them as props on the function you will return, but later additions to the prototype will reference them as 'this'. e.g.

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'



回答4:


In you your example F is not a constructor it is a function that returns an anonymous constructor which you then call new upon. instanceof works by looking at the prototype chain, so your code doesn't work because you haven't setup up the prototypes correctly.

This page has a good explain of JavaScript Constructors and how to subsclass.

Take a look at the following code and see if it helps.

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);
​


来源:https://stackoverflow.com/questions/10341127/can-javascript-constructor-return-function-and-keep-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!