首先搞明白几条规则:
1.任何函数都有prototype属性,叫显式原型,是一个对象。
2.实例化对象有一个隐式原型 __proto__ 的属性值,指向它的构造函数的显式原型 prototype 属性值。也是一个对象。
接下来我们放代码解释:
Person.prototype.name = '蜗牛'
function Person(){
//当new时会发生的过程
//var this = {
// __proto__:Person.prototype //这就解释了为什么子对象可以访问到父对象的属性和方法
//}
//return this
}
var person = new Person()
console.log(person.__proto__ === Person.prototype); //true
console.log(person.__proto__.name); //蜗牛
console.log(person.name); //蜗牛
接下来我们看看子对象的__proto__的指向是否可以改变
Person.prototype.name = '蜗牛'
function Person(){ }
var obj = {
name:'wn'
}
person.__proto__ = obj
console.log(person.name)//wn
看结果就知道,已经修改了person的原型指向,指向了另一个对象obj,就不需要去Person原型上找了
如果我修改父对象原型上的值,请问子对象的值会改变吗
Person.prototype.name = '蜗牛'
function Person(){
}
var person = new Person()
Person.prototype.name = '静静'
console.log(person.name)// 蜗牛
结果发现并没有改变,可想而知,对象实例化后是独立的
那么子对象可以修改父对象的值吗?
Person.prototype.name = '蜗牛'
function Person(){
}
var person = new Person()
person.name = '静静'
console.log(Person.prototype.name)//蜗牛
console.log(person.__proto__.name)//蜗牛
console.log(person.name) //静静
显而易见子对象无法修改到父对象的属性,子对象就会新添一个属性name,覆盖了继承过来的name,该现象叫屏蔽,说的通俗一点就是子对象重写了继承过来的元素
总之,最重要的一点就是 实例化对象的__proto__===构造函数的prototype ,下面的代码可以很好的说明了
function Person(){ }
var person1 = new Person()
var person2 = new Person()
person1.__proto__.age = 18 //相当于: Person.prototype.age = 18
person2.__proto__.sex = '女' //相当于: Person.prototype.sex = '女
console.log(person1.age) //18
console.log(person2.age) //18
console.log(person1.sex) //女
console.log(person2.sex) //女
console.log(Person.prototype.age)//18
console.log(Person.prototype.sex) //女