最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

oop - Can JavaScript constructor return function and keep inheritance? - Stack Overflow

programmeradmin1浏览0评论
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?

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?

Share Improve this question edited Apr 26, 2012 at 21:05 Sixtease asked Apr 26, 2012 at 20:41 SixteaseSixtease 7908 silver badges18 bronze badges 5
  • 7 You can return a function, since a function is an object. But obviously, f instanceof F would not be true, since it is not true. – Felix Kling Commented Apr 26, 2012 at 20:44
  • 1 Felix: The same way that tautologies are tautological? :) – Niklas B. Commented Apr 26, 2012 at 20:45
  • Why do you want instanceof to work? It's generally considered harmful. – zetlen Commented Apr 26, 2012 at 20:46
  • 6 The question remains: What do you want to achieve? – Niklas B. Commented Apr 26, 2012 at 20:46
  • It seems that there's no need to return this from the constructor in order for the instanceof to work. see here for an example – Lior Commented Jan 31, 2013 at 22:05
Add a comment  | 

4 Answers 4

Reset to default 8
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__

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__;

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'

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);
​
发布评论

评论列表(0)

  1. 暂无评论