2015-11-05 46 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