js原型链:
原型和原型链是js中的难点也是重点,个人觉得这个的确是一个很难的知识点,我也思考了很久,明白了原型和原型链会让我们在后面不管是学习还是工作都会更加高效。
上次我们说了原型的一些知识点,现在来补充一下原型链的知识点,
所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
所有函数拥有prototype属性(显式原型)(仅限函数)
原型对象:拥有prototype属性的对象,在定义函数时就被创建
举个例子:
Person.prototype.name = 'sunny';
function Person() {
}
var person = new Person();
我们创建了一个构造函数Person(),在这个构造函数创建前就带有了原型:prototype,当我们访问person.name的时候,它就会看看自己的函数内部有没有name这个属性,如果没有,那么就会去它 的原型上查找。
在 Person.prototype里面其实还有一个隐式属性,就是constructor–>对象的构造函数,可以手动更改constructor里面的属性。
当我们查看Person.prototype.constructor时候,它就会查看队像的构造函数,就是
function Person() {
}
所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型):
__proto__里面放的就是原型
在我们用new创建对象时,函数里面有三段式:
举个例子:
function Person(){
// var this = {
// __proto__ :Person.prototype
}
var person = new Person();
用new创建对象时,在构造函数内部就会有一个隐式的对象this,在隐式对象this里面就有一个属性__proto__,属性值就是原型:Person.prototype,所以当要访问构造函数的某一个属性或者方法,如果自己没有,就会去它的原型里面去找。
原型链:访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。根据原型链可以确定继承关系。由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”
举个例子:
Grand.prototype.lastname = "Deng";
function Grand(){
}
var grand = new Grand();
Father.prototype = grand;
function Father(){
this.name = 'he';
}
var father = new Father();
Son.prototype = father;
function Son(){
this.hobbit = 'smoking';
}
var son = new Son();
创建三个构造函数,分别是 Grand()、Father()、Son(),
Father.prototype = grand;
Son.prototype = father;
原型链就是从下往上一步一步继承。
下面一张图片可以让我们更好的理解prototype、proto、constructor三者的关系:
绝大多数对象的最终都会继承自Object.prototype