小咸儿在学习JavaScript高级的时候,发现一个有趣的事情,那就是原型链,首先在讲明原型链是什么的情况前,先来说说原型对象。
在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。
例如:
<script type="text/javascript">
var o={
say:function(){
alert("您好,我是"+this.name+",我今年"+this.age+"岁了,我是"+this.sex+"生");
},
get_Name:function(){
return this.name;
},
};
set_Name:function(value){
this.name=value;
}
var Person=function(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
};
Person.prototype=o;
var p1=new Person("赵晓虎",19,"男");
p1.say();
</script>
在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)。
JavaScript的原型继承的本质:将构造函数的原型对象指向由另外一个构造函数创建的实例。 |
在大概了解原型对象是什么了之后,接下来就来看看原型链是什么?
JavaScript中的每个对象,都有一个内置的proto属性。这个属性是编程不可见的(虽然ES6标准中开放了这个属性,然而浏览器对这个属性的可见性的支持不同),它实际上是对另一个对象或者null的引用。
当一个对象需要引用一个属性时,JavaScript引擎首先会从这个对象自身的属性表中寻找这个属性标识,如果找到则进行相应读写操作,若没有在自身的属性表中找到,则在proto属性引用的对象的属性表中查找,如此往复,直到找到这个属性或者proto属性指向null为止。
这个proto的引用链,被称作原型链。
首先先来看一下图是怎么说的:
注释:
对象有原型,那么原型也是对象,原型也有原型。所有的函数是对象,继承自Function.prototype。Function.prototype是对象,继承自Object.prototype。Object.prototype是对象,继承自null。 |
obj是对象,继承自Object.prototype。Function是对象,继承自Function.prototype;Function是函数,继承自Function.prototype; |
接下来看一个原型链的例子:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<meta charset="utf-8" />
<script>
var o = { name: "我是祖宗" };
var f1 = function () {
// this.name = "我是亚当"; 页面显示我是祖宗
};
f1.prototype = o;
var foo1 = new f1();
var f2 = function () {
// this.name = "夏娃"; 页面显示我是亚当
}
var foo2 = new f2();
foo2.__proto__ = foo1;
var f3 = function () {
// this.name = "我是人类"; 页面显示我是夏娃
};
f3.prototype = foo2;
var foo3 = new f3();
alert(foo3.name);
</script>
</head>
<body>
</body>
</html>
首先写完之后,都没有注释之前显示:
接下来,链中的内容全部注释之后,显示链头内容:
原型链也有些像之前学习的原型链模式,真是一通百通,不过对于代码的熟练度还需要提升。