一、原型 prototype
和__proto__
- 每个对象都有一个
__proto__
属性指向它的prototype
原型对象 - 每个构造函数都有一个
prototype
原型对象 prototype
原型对象里的constructor
指向构造器本身
那么我们为啥要引入原型对象prototype
这个概念呢?
实际上通过构造函数创建对象时,可能有一些属性或者方法是不用修改的,比如下面这个程序
function Person(name,age) {
this.name = name;
this.age = age;
this.say = function() {
console.log("我会说话");
}
}
var xm = new Star("小明",18);
var xl = new Star("小亮",19);
console.log(xm.say === xl.say); //false
结果是false
,说明他俩的say
方法不是同一个,也就是占用不同的内存空间。而我们的原型对象很好的解决了这一问题,实现了对属性和方法的共享。
那么我们可以将程序修改成下面这样
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function() {
console.log("我会说话");
}
var xm = new Star("小明",18);
var xl = new Star("小亮",19);
console.log(xm.say); //我会说话
那么我们xm
对象本身没有这个方法,是咋找到的呢?
大家可以回看上面,对象都会有一个属性__proto__
指向构造函数的prototype
原型对象,之所以我们对象可以使用构造函数的prototype
原型对象的属性和方法,就是因为有__proto__
原型的存在
console.log(xm.__proto__ === Person.prototype)//true
可以通过__proto__
找到say
方法
二、原型链
JS原型链查找机制
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾null
。