2015-11-05 44 views
0

如果我有一個String實例,並修改其構造函數的原型,那麼每個String實例的原型都具有該屬性(如預期的那樣)。瞭解Javascript原型鏈

"test string".constructor.prototype.thing = function() {return this;} 
console.log("new string".thing());//prints "new string" 

但是,如果我修改字符串構造函數的構造函數的原型,那麼這將不再有效:如果

String.constructor.prototype.thing = function() {return this;} 
console.log("new string".thing());//returns "new string".thing() is not a function 

同樣的事情,我使用的字符串。 proto語法。爲什麼是這樣?當我在尋找一個屬性時,我的印象是,JavaScript將一直沿着原型鏈向上。如果我將屬性添加到String.constructor.prototype,那麼String將不具有該屬性,但其父對象將更正?因此,String的所有實例都應該有權訪問該屬性。我的思想在哪裏錯了?

+0

可能有[\ _ \ _ proto \ _ \ _ VS的重複。原型在JavaScript](http://stackoverflow.com/questions/9959727/proto-vs-prototype-in​​-javascript) – rockerest

回答

1

但是,如果我修改字符串構造函數的構造函數的原型,那麼這將不再有效:

構造函數是一個函數,所以任何構造函數的構造函數是Function

這意味着「String構造函數的構造函數的原型」是Function.prototype

如果你添加了一些東西到Function.prototype它將顯示爲任何函數的成員,而不是任何字符串的成員。


你可以玩Object.getPrototypeOf得到一個想法。

$ (Object.getPrototypeOf(Object("")) 
String {length: 0, [[PrimitiveValue]]: ""} 
$ Object.getPrototypeOf(Object.getPrototypeOf(Object(""))) 
Object {} 
$ Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object("")))) 
null 

基本字串的對象值爲-一個String其中是安對象是原型鏈的末端。

+0

我看到 - 所以與我的代碼,我可以從任何函數訪問新的屬性,但因爲實例的字符串不是函數,它們不會繼承這個屬性? – dz210

+0

@ dz210,沒錯。所有* o *都是它們構造函數的實例,以及它們的每個原型的構造函數,但不是它們的構造函數的構造函數。 –

1

如果您想要創建長度超過一個的原型鏈,爲了支持從超類繼承,正常的方法是將構造函數的原型設置爲本身從原型繼承的類實例。下面的例子說明了這一點:

function c1(b) { 
    this.b = b; 
} 
c1.prototype = {a:111}; 

x = new c1(222); 

function c2(c) { 
    this.c = c; 
} 
c2.prototype = x; 

y = new c2(333); 

alert(y.a + ", " + y.b + ", " + y.c); 

y這三個變量是:

a inherited from c1's prototype, via c2's prototype 
b inherited from c2's prototype 
c stored directly in y 

注意,它遵循的原型鏈中達2級,從y訪問a

這是你想知道該怎麼做?

+0

不完全 - 我想知道的是爲什麼使用__proto__屬性沒有導致預期的行爲。 – dz210