为什么使用原型?
构造函数在new多个对象时,调用相同方法时,会开辟不同的地址(因为方法是引用类型,引用地址存放在栈中,再通过地址引向堆中,地址不同,但堆内储存的数据是相同的),储存他们的数据,造成浪费内存的问题,为解决浪费内存问题,就要使用函数的原型
JavaScript规定,每个函数都有一个prototype属性,指向另一个对象。这个prototype就是一个对象,这个对象的属性和方法,都会被构造函数所拥有。
因此,把公共的方法,定义在prototype对象上,这样所有对象的实例就可以共享这些方法,这也就是原型的作用:共享方法
<script>
class Father {
constructor(uname) {
this.uname = uname
this.say = function() {
console.log('hello');
}
}
}
var son = new Father('张三')
var son1 = new Father('李四')
console.log(son);
console.log(son1);
console.log(son.say === son1.say);
</script>
因此实例化构造函数创建的对象的地址是不一样的
<script>
class Father {
constructor(uname) {
this.uname = uname
}
}
Father.prototype.say = function(){
console.log('hello');
}
var son = new Father('张三')
var son1 = new Father('李四')
console.log(son.say);
console.log(son1.say);
console.log(son.say === son1.say);
</script>
把公共方法添加在构造函数的prototype(原型)对象里面,实现方法共享,减少栈内的储存空间
地址已相同。
为什么上面的代码,构造函数新创建的对象没有继承构造函数的方法,又怎么可以调用它的say方法?
对象都会有一个属性—proto—指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数的prototype原型对象的属性和方法,就是因为对象有—proto—原型的存在
对象的—proto—构造函数的prototype是相等的
什么是原型链?
每个函数都有一个prototype原型属性,每个对象都有一个—proto—原型,
当访问对象到某个属性时,会先从这个对象的本身属性上查找,如果没找到,则会去他的—proto—属性上找,即他的构造函数的prototype,如果还没找到,就就会再在构造函数的prototype的__proto__中查找,(即Object.prototype)这样一层一层向上查找就会形成一个链式结构,我们称原型链