理解Javascript原型链

时间:2015-11-05 16:20:46

标签: javascript inheritance prototype-chain

如果我有一个String实例,并且我修改了它的构造函数原型,那么每个String实例的原型都有该属性(如预期的那样)。

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

但是,如果我修改了String构造函数的构造函数原型,那么这不再有效:

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

如果我使用String。 proto 语法,则相同。为什么是这样?我的印象是,在寻找房产时,JavaScript会在原型链上一路走来。如果我向String.constructor.prototype添加一个属性,那么String将不具有该属性,但其父对象将是正确的?因此,String的所有实例也应该有权访问该属性。我的想法在哪里错了?

2 个答案:

答案 0 :(得分:1)

  

但是,如果我修改了String构造函数的构造函数的原型,那么这不再有效:

构造函数是一个函数,因此任何构造函数的构造函数都是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

原始字符串的对象值是-a String,其中对象,它是原型链的末尾。

答案 1 :(得分:1)

如果要创建长于1的原型链,为了支持从超类继承,通常的做法是将构造函数的原型设置为一个本身继承自原型的类实例。以下示例演示了这一点:

void Get1stVec(Polygon* poly, Vec2* &vec )
                                    ^^^^
{
    Vec2* tmp = &poly->verts.at(0); // tmp gets a valid pointer here.
    vec = tmp;
}

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

请注意,它会跟随原型链上升2个级别,以便从a inherited from c1's prototype, via c2's prototype b inherited from c2's prototype c stored directly in y 访问a

这是你想知道怎么做的?