原型和原型链 - pod4g/tool GitHub Wiki
关于原型和原型链的一点儿感想
每一个对象都有__protp__
属性,每一个函数都有prototype
属性,对象的__proto__
和这个对象的构造函数的prototype
指向的是同一个对象,这个对象我们称之为原型对象
function Person(name, age) {
this.name = name
this.age = age
this.say = function () {
console.log('name:', this.name)
console.log('age:', this.age)
}
}
let person = new Person('云崇', 29)
person.__proto__ === Person.prototype
为什么有了prototype
,还要有__proto__
呢?
这就是程序设计的冗余性,因为如果只有prototype
的话,一个对象,就不能方便地访问自己的原型对象,只能使用这个对象的构造器.prototype
的形式进行访问,很不方便
由于原型对象
也是对象
,故其也有__proto__
,所以这就形成了一条链,我们称之为原型链
原型对象含有一个constructor
,会指回向构造器
两个与原型有关的api
Object.create
创建一个新对象,并把新对象的__proto__
指向传入的参数
const p = { name: 'yunchong', age: 29 }
const p2 = Object.create(p)
console.log(p2.name) // yunchong
console.log(p2.age) // 29
p2.__proto__ === p
在这个api出来以前,我们是怎么干的呢?
const p = { name: 'yunchong', age: 29 }
function Person() {}
Person.prototype = p
const p2 = new Person()
console.log(p2.name) // yunchong
console.log(p2.age) // 29
p2.__proto__ === p
其实Object.create
就是上述代码的语法糖,直接又方便地创建以一个以某个对象作为原型的对象而不用写一大坨代码
我们也常常使用Object.create(null)
来创建超轻量级的对象,轻量是因为其没有原型
Object.getPrototypeOf
上面说过,__proto__
可以访问到对象的原型对象
,但是这个__proto__
毕竟不是es规范规定的,以后如果删除掉(或者不在暴露出去),那么其实es也提供了一个api来拿到__proto__
const p = { name: 'yunchong', age: 29 }
const p2 = Object.create(p)
const prototypeObject = Object.getPrototypeOf(p2)
prototypeObject === p2.__proto__
prototypeObject === p
p2.__proto__ === p