2012-04-26 76 views
12
function F() { 
    return function() { 
     return {}; 
    } 
} 

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

據我所知,如果我需要instanceof工作,我需要從構造函數返回this。但我想要構造函數返回一個函數,我不能分配到thisJavaScript構造函數可以返回函數並保持繼承嗎?

那麼,這是真的不可能或者可以以某種方式完成,因爲f = new F()返回一個函數,仍然f instanceof F返回true?

+7

您可以返回一個函數,因爲函數是一個對象。但很明顯,'f instanceof F'不會是真的,因爲它不是真的。 – 2012-04-26 20:44:05

+1

菲利克斯:同義反復都是同義的嗎? :) – 2012-04-26 20:45:42

+0

爲什麼你想要instanceof工作?它通常被認爲是有害的。 – zetlen 2012-04-26 20:46:11

回答

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

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

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

只能在瀏覽器與__proto__

+0

非常感謝。這會做。 – Sixtease 2012-04-26 21:21:44

0

在你的例子中,F不是一個構造函數,它是一個函數,它返回一個匿名構造函數,然後再調用它。 instanceof通過查看原型鏈來工作,因此您的代碼無法正常工作,因爲您尚未正確設置原型。

這個page對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); 
​ 
5

當然,你可以把所有的功能似乎通過設置F.prototype = Function.prototype;instanceof F

不幸的是,它看起來好像ECMAScript不允許你創建一個函數子類。

您可以使用過時的__proto__財產但是這樣做在壁虎:

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

Esailia更快,因此他的答案被接受。不管怎麼說,還是要謝謝你! – Sixtease 2012-04-26 21:21:22

+0

@Sixtease足夠公平,但請注意他寫的答案不會讓你'.apply'或'.call',因爲他沒有額外的線路。 – Neil 2012-04-26 23:16:56

+0

@Neil,究竟是什麼F.prototype .__ proto__ = F .__ proto__;是在做?如果我不這樣做會發生什麼? – esp 2014-10-20 20:42:02

1

要有人來今天這個跨越,用ES6/2015年有新的語法,你可以用它來避免過時__proto__財產; Object.setPrototypeOf。請注意,MDN warns這是一個慢/昂貴的操作。

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'