2013-05-13 16 views
6

Doğal nesnelerle, Javascript'te yapıcı zinciri mirası hakkında bir şey özlemiş gibi görünüyor. Örneğin:Yerel nesnelerden devralma

myerror.message bu açıklamalardan sonra "" olarak tanımlanır Neden
function ErrorChild(message) { Error.call(this, message); } 
ErrorChild.prototype = Object.create(Error.prototype); 
var myerror = new ErrorChild("Help!"); 

? Hata yapıcısının bunu "Yardım!" Olarak tanımlamasını beklerdim. Ben yapıyordu anlar gibi (ve Error.prototype.message varsayılan değerini geçersiz):

var myerror = new Error("Help!") 

Çok teşekkürler! Basit iş çevresinde

cevap

4

: Working fiddle

function ErrorChild(name, message) { 
    // Error.call(this); this is not needed 
    this.name = name; 
    this.message = message; 
} 

ErrorChild.prototype = Object.create(Error.prototype); 
ErrorChild.prototype.constructor = ErrorChild; 

var myerror = new ErrorChild("test", "Help!"); 
document.body.innerHTML += myerror.message; 

yukarıda beklenen davranış kesilmez. throw myerror, doğru name ve message görüntülendiğinde.

ECMA5 Dil Şartname itibaren sorun

:

15.11.1 Fonksiyonu Olarak Aranan Hata Oluşturucu Hatası bir fonksiyonu olarak yerine yapıcı olarak adlandırılır

, yeni bir Error nesnesi oluşturur ve başlatır. Böylece Hata (...) işlev çağrısı, aynı argümanlarla yeni Hata (...) nesne oluşturma ifadesine eşdeğerdir.

sorun

: Error.call(this), new Error eşdeğerdir. Ancak new Error örneği, name veya message'u ayarlamayacaktır. new Error, "" ile message'u varsayılan olarak başlatacaktır.

15.11.4.3 Error.prototype.message # Ⓣ Error Error.prototype.message öğesinin başlangıç ​​değeri boş String'tir.

Testi (proof)

iç Eğer senin ErrorChild Eklemek idi:

var test = Error.call(this, message); 
console.dir(test); 
console.log(test instanceof Error); // true; 
console.log(test.message); // "Help!"; 

test ECMA5 spec yansıtır. Uygun bir message ayarlanmış bir Error örneği.

Sonuç:

Error.call(arguments); otomatik new Error(arguments); kapsamı için tercüme Çünkü kaybolur, böylece özellikler this nesne üzerinde başlatıldı asla.

Object.create(Error.prototype) kullanıldığında, message özelliği varsayılan değeri boş Dize alır.

+0

Sorun [bir fonksiyonu olarak 'Error' çağırarak] olmasıdır (http: //es5.github .io/# x15.11.1) kurucuyu çağırıyor gibi davranıyor ('yeni Error') – C5H8NNaO4

+0

Naah, sorunun açıklanması için cevabınızı güncellediğinizde beklediğimi düşündüm; şimdi ben de cevap verdi: D – C5H8NNaO4

+0

Evet Ben Yanıt ^^ sonra (bu için +1), 10 saniye sonra, oldukça ilginç bir soru * (yine de birkaç kez sordu) * Düzenlediğiniz fark ettim * Bir communinity wiki wold Böyle bir soru (neden bunu cw olarak değil)? Evet, ama problemi oldukça iyi karşıladıklarını düşünüyorum. =) – C5H8NNaO4

1

Sorun değil devralma zinciri, daha ziyade gerçektir ki

nedenle bir new Error Nesne, kurucu çağırmak başlatmasını olarak calling Error as a function davranacağını ararken senin new ErrorChild yürütülen kod aslında eşdeğer

function ErrorChild(message) { 
new Error (message) 
} 
etmektir

Bekleyin. Ancak bu sadece değil (ve aynı zamanda kurucunuz tarafından değil) kullanılan yeni bir Hata Nesnesi oluşturur. Ve sadece unutulur.

Yani bu aslında , gerçek ErrorChild örneğinizi değiştirmez.

nedenle erişen message özelliklerinin araştırılması Error.protyotype devraldığı ErrorChild.prototype gölgesinde biridir ve bu nedenle içeren message 'ın varsayılan değer bir boş dize ""

Ama sadece yapabilirsiniz 'mimik' Hata Nesne .

yalnızca Error standart özelliklerini karşılamak için toString method's defined behaviour ve 2 özelliklerini

name

  • message ihtiyaç gibi.

    Sadece Error.prototype için kurucular prototip ayarlamak Ve elle name ve message atayabilir.

    function ErrorChild (name,message) { 
        this.name = name; 
        this.message = message; 
    } 
    ErrorChild.prototype = Error.prototype; 
    

    Artık bir new ErrorChild (...) örneğini oluşturabilirsiniz.

    Hangi yapabilirsiniz log etrafında throw ve catch ->

    throw new ErrorChild("CustomError","Help") //Uncaught CustomError: Help

    İşte bir JSBin Demo