在前面学习java有一个概念叫做继承,方便我们对父类方法、变量等的调用。对前端的学习我们需要让对象可以访问和继承其他对象的属性和方法,就需要了解原型对象,以及原型链。
一、原型
构造函数通过原型分配的函数是所有对象所共享的。每一个构造函数都有一个prototype属性,指向另一个对象,所以我们也称为原型对象。
因此我们可以把不变的方法,直接定义在prototype对象上,方便所有对象的实例共享这些方法,节约内存。
构造函数和原型对象中的this 都指向实例化的对象
二、原型对象
在JavaScript中,当我们创建一个函数, 那么浏览器就会在内存中创建一个对象,而且每个函数都默认会有一个属性 prototype 指向了这个对象。这个对象就是该函数的原型对象,简称函数的原型。这个原型对象 默认会有一个属性 constructor 指向了这个函数。
示意图如下:
代码示例:
<script>
//公共的属性写到构造函数里
function f(uname,age){
this.uname=name;
this.age=age;
}
//向原型里添加方法
//公共的方法添加到原型对象里
f.prototype.sing=function () {
console.log('唱歌');
}
// 实例化对象
const people1=new f('tim',20);
const people2=new f('tom',30);
people1.sing();
people2.sing();
console.log(people1.sing() === people2.sing())
</script>
三、对象原型
当我们实例化时,为什么可以共享对象原型里的方法?
对象都会有一个属性_ _proto_ _ 指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto 原型的存在。对象原型指向原型对象。
示意图如下:
代码演示:
<script>
function people(){
}
const p1=new people();
console.log(p1.__proto__);
//原型对象指向对象原型
console.log(p1.__proto__===people.prototype);
//示例对象里有constructor属性指向构造函数
console.log(p1.__proto__.constructor===people);
</script>
四、原型链
1、什么是原型链?
每个对象都有一个_ _proto_ _指向其原型对象,而原型对象本身也是一个对象,也具有自己的原型对象,这样就形成了一个对象与其原型对象之间的链接,构成了原型链。
2、代码示例
<script>
console.log(Object.prototype)
function people(){
}
const p1=new people();
console.log(p1.__proto===people.prototype)
console.log(people.prototype.__proto===Object.prototype)
</script>
3、示意图
当我们访问对象的属性或方法时,JavaScript 引擎首先会在对象自身查找,如果找到则返回对应的值;如果在对象自身找不到,引擎会沿着原型链往上一级一级地查找,直到找到该属性或方法的定义或者到达原型链的顶端(即 Object.prototype),如果还没有找到,则返回 undefined。