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

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

Anlaştığım kadarıyla, çalışmak için instanceof istiyorsam, this yapıcıdan geri dönmem gerekiyor. Ancak kurucunun bir işlev döndürmesini istiyorum ve this'a atayamıyorum.JavaScript yapıcısı işlev döndürür ve miras bırakabilir mi?

Yani, bu gerçekten imkansız mı, yoksa bir şekilde f = new F() için bir işlev döndürmek ve yine de f instanceof F doğru dönmek için yapılabilir mi?

+7

Bir işlev, bir işlev bir nesne olduğu için döndürebilirsiniz. Ama açıkçası, F'nin instagramı, doğru olmadığı için doğru olmaz. –

+1

Felix: Tatolojilerin totolojik olduğu gibi mi? :) –

+0

Neden instanceof çalışmasını istiyorsunuz? Genellikle zararlı olarak kabul edilir. – zetlen

cevap

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

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

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

Sadece Elbette tüm fonksiyonlar F.prototype = Function.prototype; ayarlayarak instanceof F gibi görünen yapabilir __proto__

+0

Çok teşekkürler. Bu yapacak. – Sixtease

0

Sizin örneğinizde F bir kurucu değil, daha sonra arayacağınız anonim bir kurucu döndüren bir işlevdir. instanceof prototip zincirine bakarak çalışır, bu yüzden kodunuz çalışmaz çünkü prototipleri doğru şekilde kurmadınız.

Bu page, JavaScript Constructors öğelerini ve nasıl abone kalacağını iyi bir şekilde anlatmaktadır.

Aşağıdaki koda bakın ve yardımcı olup olmadığını görün.

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

tarayıcılarda çalışır.

Maalesef, ECMAScript'in bir işlev alt sınıfı oluşturmanıza izin vermediği anlaşılıyor.

Bununla birlikte kaldırılan __proto__ özelliğini kullanarak Gecko bunu yapabilirsiniz: herkes için

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

Esailia daha hızlıydı, dolayısıyla cevabı kabul edildi. Yine de teşekkürler! – Sixtease

+0

@Sixtease Yeterince adil, ama yazdığı cevabın size örn. “.apply” veya “.call” nesnesinde, çünkü yaptığım ekstra çizgiye sahip değil. – Neil

+0

@Neil, tam olarak ne F.prototype .__ proto__ = F .__ proto__; yapıyor? Yapmazsam ne olur? – esp

1

, bu bugün karşısında geliyor ES6/2015 Eğer kaldırılmış __proto__ özelliğini önlemek için kullanabileceğiniz yeni bir yazım var; Object.setPrototypeOf. MDN warns'un bunun yavaş/pahalı bir işlem olduğunu unutmayın.

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

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

Ayrıca, kurucudaki değerleri başlatmak istiyorsanız biraz garipleştiğini unutmayın. Onları iade edeceğiniz işleve sahne olarak ayarlamanız gerekir, ancak daha sonra prototip için eklemeler bunları 'bu' olarak referans gösterecektir. Örneğin.

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' 
İlgili konular