一个例子深入理解JavaScript原型链

JavaScript原型链

1.原型链的产生

JavaScrip可以采用构造器(constructor)生成一个新的对象,每个构造器都拥有一个prototype属性,而每个通过此构造器生成的对象都有一个指向该构造器原型(prototype)的内部私有的链接(proto),而这个prototype因为是个对象,它也拥有自己的原型,这么一级一级指导原型为null,这就构成了原型链.

2.例子加深理解

function ClassA(){
}
ClassA.prototype.name = 'A';
ClassA.prototype.sayName = function(){
    alert(this.name);
}

function ClassB(){ 
}

ClassB.prototype = new ClassA();

var b1 = new ClassB();
b1.sayName();//A 

b1对象上未定义sayName方法,但其构造器ClassB的原型prototype上定义了sayName方法。通过原型链(主要是__proto__属性),b1也拥有sayName方法。

function ClassA(){
}
ClassA.prototype.name = 'A';
ClassA.prototype.sayName = function(){
    alert(this.name);
}
var ClassB = new ClassA();
ClassA.sayName();// Uncaught TypeError: ClassA.sayName is not a function

访问ClassA.sayName时,基于原型链不应该访问 ClassA.prototype.sayName 吗?为什么本题没有访问ClassA.prototype.sayName呢?
其实这个问题问的就是错误的,JavaScript的原型链实际是靠__proto__形成的,而非prototype。所以查找原型链,查找的是__proto__,而非prototype。函数的prototype不属于自身的原型链。

3.原型链的实现代码

function getProperty(obj, prop) {
    if (obj.hasOwnProperty(prop)) //首先查找自身属性,如果有则直接返回
        return obj[prop]
    else if (obj.__proto__ !== null)
        return getProperty(obj.__proto__, prop) //如何不是私有属性,就在原型链上一步步向上查找,直到找到,如果找不到就返回undefind
    else
        return undefined
}

4.总结:
1).原型链的形成真正是靠__proto__ 而非prototype,当JS引擎执行对象的方法时,先查找对象本身是否存在该方法,如果不存在,会在原型链上查找,但不会查找自身的prototype。
2).一个对象的__proto__记录着自己的原型链,决定了自身的数据类型,改变__proto__就等于改变对象的数据类型。
3).函数的prototype不属于自身的原型链,它是子类创建的核心,决定了子类的数据类型,是连接子类原型链的桥梁。
4).在原型对象上定义方法和属性的目的是为了被子类继承和使用。

参考文章:
1.JS核心系列:浅谈 原型对象和原型链

此条目发表在JavaScript分类目录。将固定链接加入收藏夹。

发表评论

邮箱地址不会被公开。 必填项已用*标注