目录
constructor和__proto__和prototype:
原型对象:
其作用是:共享方法,节省内存。
简单理解就是每一个构造函数内置了一个prototype,这其实就是一个存储公用数据的对象存取空间。
function Person(name,age,address) {
this.name=name
this.age=age
this.address=address
}
Person.prototype={
eat:function () {
console.log('I can eat!')
},
sing:function () {
console.log('I can sing!')
}
}
let person1=new Person('a',16,'JS,NJ')
let person2=new Person('b',18,'JS,YC')
let person3=new Person('c',10,'JS,ZJG')
person1.eat()
person2.eat()
person3.sing()
这样我们就可以很完美的解决方法实例化导致内存空间缩减的情况了。
constructor和__proto__和prototype:
constructor用于指向对象的构造函数,而__proto__指向构造函数的原型对象,prototype就是构造函数的原型对象。
继承:
使用原型对象来存储公用部分对象。详细如下:
//公共部分声明
let PersonCommonPart = {
head: 1,
body: 1,
hands: 2,
legs: 2,
eat: function () {
console.log('I can eat!')
},
sing: function () {
console.log('I can sing!')
}
}
function Chinese() {
this.skin = 'yellow'
}
Chinese.prototype = PersonCommonPart
function Asian() {
this.skin = 'black'
}
Asian.prototype = PersonCommonPart
let c1 = new Chinese()
console.log(c1)
let a1 = new Asian()
console.log(a1)
运行结果:
但是上面这种方法会出现constructor丢失的情况,所以我们需要在继承的时候再添加加回来。
下面是完整写法:
let PersonCommonPart = {
head: 1,
body: 1,
hands: 2,
legs: 2,
eat: function () {
console.log('I can eat!')
},
sing: function () {
console.log('I can sing!')
}
}
function Chinese() {
this.skin = 'yellow'
}
console.log(Chinese.prototype)
//用于继承
Chinese.prototype = PersonCommonPart
//用于指回构造函数自身
Chinese.prototype.constructor=Chinese
function Asian() {
this.skin = 'black'
}
//意义同上
Asian.prototype = PersonCommonPart
Asian.prototype.constructor=Asian
let c1 = new Chinese()
// console.log(c1)
let a1 = new Asian()
// console.log(a1)
console.log(Chinese.prototype)
console.log(c1.__proto__)
到这里,我们的思路对了,但是还是有一点问题,我发现当我对chinese的原型对象进行查看时,其constructor是指向asian的。这是因为我们使用原型对象继承时的公用部分对象是实例化的对象,而且使用了赋值方法,这样用于chinese的原型对象就被在asian继承时替换掉了。所以我们还需要将公用部分对象改为构造方法。
原型链:
原型链是由原型对象的组成的链状结构,用于检索实例对象的原型对象链。
整个原型链是用于实例调用方法时,在自己的原型对象中找不到,然后再找下一层逐层找直到为null时停止。