前言
我们从上一章深入理解原型对象、原型链(一)知道:foo.__proto__ === Foo.prototype
function Foo(name){
this.name=name
}
//在原型对象上定义方法
Foo.prototype.say = function(){
console.log(123)
}
var foo = new Foo('张三')
var foo2 = new Foo('李四')
foo.say(); // 123
foo2.say(); // 123
foo.__proto__.say2 = function(){console.log(456)} //在原型对象上定义方法
foo.say2(); // 456
foo2.say2(); // 456
我们发现由于 Foo.prototype === foo.__proto__都是原型对象,在原型对象上定义方法,实例对象都能访问。
function Bar(age){this.age=age}
function Zing(sex,height){this.sex=sex;this.height = height}
var foo3 = new Foo('王五')
var bar = new Bar(18)
var zing = new Zing('男',80)
bar.__proto__ = zing;
foo3.__proto__ = bar;
foo3.sex // 男
我们打印下foo3
发现:
foo有自身的属性name和指向Bar的[[Prototype]]// chrome浏览器显示的是Zing,但通过foo3.__proto === bar得知,属性指向应该是Bar,应该是chrome浏览器显示bug。foo3.__proto__Bar有自身的属性age和指向Zing的[[Prototype]]foo3.__proto__.__proto__Zing有自身的属性sex和height和指向Object构造器是Zing的[[Prototype]]foo3.__proto__.__proto__.__proto__指向Zing.prototypefoo3.__proto__.__proto__.__proto__指向Object.prototypefoo3.__proto__.__proto__.__proto__.__proto__指向null
foo3.age = '9'
bar.sex = '女'
foo3.hello() //由于原型链上没找到该属性,报错
发现:如果在上一层的原型对象中发现了属性就无法再访问下一层属性。
小节:
对象在访问属性时,先访问自身属性,如果有直接返回,没有就访问下一级原型对象的属性,直到访问到Object.prototype,如果还没有,直接会报错,这样就能解释了为啥对象都会有hasOwnProperty这些方法,就是因为这些方法都是定义在Object上,而对象又都是Object的子类.
应用
定义实例属性、方法
function Person(name){this.name = name}
Person.prototype.sayHello = function(){
console.log('hello' + this.name)
}
委托
// 基础值
var obj = {
sayHello() {
console.log('hello')
},
saySorry(){
console.log('sorry')
}
}
var o = {};
var u = {};
Object.setPrototypeOf(o,obj); //等同于 o.__proto__ = obj;
o.sayHello(); // hello
o.saySorry(); // sorry
// 同理
Object.setPrototypeOf(u,obj);
u.sayHello(); // hello
u.saySorry(); // sorry
// 这样 我们可以将obj这个对象里的方法抽象出来作为公共方法,如果其他对象用到该方法,可以直接委托.