原型
JS 中的每个对象实例都有一个爹,这个爹就是它的原型(也是一个对象),对象实例继承了原型上的属性和方法。
- 每个对象实例都有属性
__proto__
,属性值即该对象实例的原型(因通常没对外显示,被称为隐式原型
) - 每个对象实例是通过对应的类 class / 构造函数 用 new 运算符创建的,该类 class / 构造函数都有属性
prototype
,属性值也是对象实例的原型(因通常都可直接看到,被称为显式原型
) - 类 class / 构造函数中定义的属性和方法,都存储在原型中,当在对象实例中找不到目标属性/方法时,就会去其原型中找,父辈原型中没有,则继续向祖父辈原型中找,直到找到最顶端的原型
Object.prototype
,有则访问/调用,没有则返回 undefined。
如下范例: class Student 创建了 实例 xialuo
- 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时,先在自身属性和方法寻找,如果找不到则自动去_proto_ 中查找
原型链
JS 对象的顶级原型是 Object.prototype ,即 JS 中所有对象都继承自 Object.prototype
- Object.prototype 没有原型,所以 Object.prototype 的
_proto_
属性值为 null
【下图需能手绘!】
- 通过 hasOwnProperty 可以判断某属性是否为实例自己的属性
实战 – 绘制原型链图
范例 1
const obj1 = {
a: 10,
};
Object.prototype.__proto__ === null // true
obj1.__proto__.__proto__ === null // true
obj1.__proto__ === Object.prototype // true
实例的隐式原型指向类的显式原型
范例 2
const obj1 = {
a: 10,
};
const obj2 = Object.create(obj1);
Object.create() 的参数为对象实例时,返回一个以该对象实例为隐式原型的对象。
obj2.__proto__ === obj1 // true
范例 3
const obj3 = Object.create(null);
Object.create() 的参数为 null 时,返回一个无原型也无属性的空对象。
【考题】new Object() 和 Object.create() 的区别
- new Object() 等同于 {} ,其隐式原型是 Object.prototype
- Object.create()
- 参数为 null 时,返回一个无原型也无属性的空对象
- 参数为对象实例时,返回一个以该对象实例为隐式原型的对象。
const obj1 = {
a: 10,
};
const obj2 = new Object({
a: 10,
});
const obj3 = new Object(obj1);
console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true