JS | 知识点总结 - 原型链
省流,总结图:
原型链
原型链: 通过 __proto__ 进行连接
每个对象都有一个内部属性 [[ Prototype ]],在浏览器中可以通过 __proto__ 访问,现代浏览器中推荐用 Object.getPrototypeOf()
在 JS 中, 每个函数都有一个默认的 prototype 属性,这个属性会在该函数被 new 调用时成为新创建实例对象的 __proto__ (即 原型)。
修改 构造函数.prototype <==> 修改 将来通过 new 构造函数() 创建的对象的原型链。
关键公式:
指向构造函数的 prototype:p.__proto__ === Person.prototype
默认指回构造函数本身:Person.prototype.constructor === Person
标准方式:Object.getPrototypeOf(p) === Person.prototype;
p.constructor = p.__proto__.constructor
(注: p为实例,Person构造函数,Person.prototype为构造函数的原型。)
(注:图中应为 Object.getPrototypeOf() )
原型链继承:
Object.create( 新对象的原型对象, [新对象定义属性] ):用现有对象 来作为 新对象的原型(即 __proto__ )
const 新对象 = Object.create(现有对象)
等价于
新对象.__proto__ === 现有对象
——》 例子:即 类似于 新对象=实例,对象=原型对象——》实例.__proto__ = 原型对象
例子—— 原型链的总结:
Chinese.prototype.__proto__ = Human.prototype;
等价于 Chinese.prototype = Object.create(Human.prototype)
等价于 Chinese.prototype = new Human(); 【存在变量同享的污染可能。】
为什么是修改 Chinese 的原型对象 prototype 呢?
① 修改 构造函数.prototype
<==> 修改 将来通过 new 构造函数() 创建的对象的原型链。
② 让返回的 新函数的原型对象 继承 来自 原函数的原型对象(通过原型链)。
Object.create(proto)
用来创建一个继承自 proto
的新对象
语法:Object.create(prototype, [propertiesObject])
prototype
:新对象的原型对象(可以为null
)
propertiesObject
(可选):为新对象定义的自身属性(类似于Object.defineProperties
)
其他知识点—— 继承:
知识点 | 说明 |
---|---|
构造函数继承 | Parent.call(this, args...) |
原型链继承 | Child.prototype = Object.create(Parent.prototype) |
原型方法添加 | Constructor.prototype.methodName = function() {} |
修正 constructor | 否则 子类实例的 constructor 会指向父类. 即 Constructor.prototype.constructor = Constructor |
prototype vs proto | prototype 是构造函数的原型对象,__proto__ 是实例指向原型的属性 |
原型方法定义 不能带括号,也不要用箭头函数。——》 ✅ xxx.prototype.方法 = function() {...}
(箭头函数,this是外部上下文;方法的不能带括号。X Number.prototype._isPrime( ) {})
其他知识点
对象属性的遍历(es6中对象新增的总结)
Object.keys(obj):返回一个数组,包含对象自身可枚举的属性名(不含原型链上的属性)
Object.getOwnPropertyNames() :返回一个数组,包含指定对象自身 所有的属性(含可枚举和不可枚举的属性)
Object.getPrototypeOf(obj) :获取对象的原型(即 父对象)。——》获取原型链的属性const protoProps = Object.getOwnPropertyNames(Object.getPrototypeOf(obj));