一.原型链的代码讲解
<!-- 原型链 -->
// 创建函数
const animal = function(name,age){
this.name = name;
this.age = age;
//创建函数对象(缺点:耗内存。原因:每构造一个对象,这个函数就要被创建一次,例如创建一万个对象,这个函数就要被反复创建一万次,会消耗巨大的内存)
this.func = function func(){
console.log(this.name + "的年龄是" + this.age);
}
}
// 构造对象dog01
const dog01 = new animal("旺旺",4);
console.log(dog01);
console.log(dog01.name);//输出dog01的年龄
dog01.func()//调用对象dog01中的func的属性/函数
// 为减小内存消耗(在原型链上面直接添函数的优点),可在原型链上面直接给animal构造函数添加函数属性,例如添加函数属性func02
animal.prototype.func02 = function(){ //向原型链添加属性的方式(在原型链上面直接添加的属性一般是函数)
console.log("我是直接在原型链上面添加的属性");
}
//调用一下直接在原型链上面直接添加的func02安函数属性
dog01.func02();//console的结果:我是直接在原型链上面添加的属性
// 在使用构造函数(例如我们创建的animal)创建出来的对象(dog01对象),通过dog01对象进行调用animal中的func02方法(func02方法是直接添加在原型链上面的)
dog01.func02();//后台结果:我是直接在原型链上面添加的属性。
console.log(animal.prototype);
/**
* 为什么dog01对象可以访问animal.prototype上的东西?
* 原因一:对象dog01 是 构造函数animal 创建出来的对象
* 原因二: 见本文下面的四.底层原理图 和五.原型链的理解
*
* */
二. Console结果图
三. 相关介绍
四. 底层原理图(以上述代码为例子)
五. 原型链的理解
当我们使用一个方法或者属性时,首先会在自身中查找。
若自身中有,则直接使用。
若自身中没有,则在原型对象中去找。(例如:dog01.__ proto__.xxx)
若自身的原型对象中没有,则原型中的原型去找(例如:dog01.__ proto__.__ proto__),直到找到Object对象的原型,Object对象的原型没有原型(到此时,若还没有找到,就会返回undefined)。就好像在一条链上依次找似的。
一般来说, console.log(dog01.__proto__.__proto__.__proto__) 返回的是undefined。