每个JS对象(null除外)都和另一个对象相关联,这“另一个对象”就是原型,每个对象都从原型上继承属性。
[[prototype]]表示对象内部的私有属性,这是ES规范的表示法。注意:图中最后一个p对象如果是null,则该对象没有原型属性。
获取对象的原型属性:
可以使用Object.getPrototypeOf(someObj)获取某个对象的原型
原型属性不能通过.或[]访问,直接访问是undefined
对象的原型属性:proto
可以直接设置对象的proto设置对象的原型,但是这样不够美观,下划线开头意味着是个私有属性,开发人员都有一定的抵触
ES6推荐使用Object.setPrototypeOf(obj, prototype)第一个参数是要设置原型的对象,第二个参数是该对象的新原型。如果第二个参数不是对象或是null,则会报TypeError类型错误。
通过上面的方法更改原型,性能比较差,不推荐使用,能用Object.create()方法尽量不要使用这个
检测是否为某个对象的原型:
someObj.isPrototypeOf(anotherObj)
对象中super关键字指向该对象的原型
原型链
不同的原型组成的链叫原型链
添加属性
删除属性
delete运算符只能删除对象的自有属性,不能删除从原型继承而来的属性
检测属性
可以通过in,hasOwnProperty,propertyIsEnumberable等方法检测属性是否存在
propertyIsEnumberable是hasOwnProperty的增强版,是自身属性并且是可枚举时才返回true
枚举属性
可以使用for/in,Object.keys,Object.getOwnPropertyNames来枚举对象的属性
for/in可以枚举对象的所有属性(包括继承而来的属性),但必须是可枚举的
Object.keys只返回自身可枚举的属性
Object.getOwnPropertyNames返回自身属性,可枚举和不可枚举都算
查询属性
会遍历原型链,有一定的性能问题,要注意代码中原型链的长度,并在必要时将其分解,以避免潜在的性能问题。
共享带来的问题
如果原型是函数或者原始类型并不会有这个问题,否则其中一个实例改变原型另一个实例也会发生改变。原型是把双刃剑,就看如何使用。