首先看一个构造函数
function Cat(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
// 不能使用匿名函数,多个对象会存储多个方法。影响性能
this.eat = catEat
}
function catEat () {
console.log(this.name + '吃吃吃')
}
let c1 = new Cat('小花', 3, '母')
let c2 = new Cat('小绿', 1, '公')
// 此时返回为true
console.log(c1.catEat === c2.catEat)
每一个构造函数都有一个属性: 原型,或者说原型对象
function Cat(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Cat.prototype.catEat = function () {
console.log(this.name + '吃吃吃')
}
let c1 = new Cat('小花', 3, '母')
let c2 = new Cat('小绿', 1, '公')
c1.catEat()
c2.catEat()
// 此时返回为true
console.log(c1.catEat === c2.catEat)
console.dir(c1);
此时,我们可以得出结论。通过Cat对象创建的实例对象,可以访问到Cat.prototype成员
c1.proto 等于 Cat.prototype 属性
当调用对象的属性或者方法时,先去找对象本身的属性/方法 ,如果对象没有该属性或者方法。此时去调用原型中的属性或者方法。如果对象本身没有该属性或者方法,原型中也没有该属性或者方法,此时会报错
对于 对象,原型,构造函数的关系, 我们可以通过一张图表示出来
思考:
原型的构造函数是什么? 原型的原型是什么?
let o = c1.__proto__
console.log(o.__proto__.constructor)
console.log(o.__proto__.__proto__)
原型对象的proto 为 一个 object 对象,而object 的 原型对象为null。
思考:
当我们构造方法中设置prototype属性时,一个实例对象修改此属性,会对其他实例对象有影响吗?
function Cat(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Cat.prototype.color = 'white'
let c1 = new Cat('小花', 3, '母')
let c2 = new Cat('小绿', 1, '公')
c1.color = 'yellow'
console.log(c1.color)
console.log(c2.color)
console.dir(c1)
console.dir(c2)
得出结论,只有当获取属性时。受到原型影响,设置属性时,只会为c1创建属性,此时不再访问proto属性。
只有获取收到影响。