前言
本文只是总结访问原型的方法,并不对原型链做深入理解。
8+种姿势访问原型
prototype
- prototype是一个对象
- 原型会形成原型链,原型链上查找属性比较耗时, 访问不存在的属性会访问整个原型
注意:toString的怪异现象
var proto = Array.prototype
console.log(typeof proto);
console.log(Object.prototype.toString.call(proto));
proto
- 构造函数的原型,null以外的对象均有__proto__属性
- Function,class的实例有prototype以及__proto__属性
- 普通函数,祖上第三代上必为null
const print = console.log
function Person(){}
var person = new Person()
console.log(person.__proto__);
print(person.__proto__ === person.constructor.prototype)
instanceof
- 检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
- 手写 instanceof
function instanceOf(instance, cclass) {
let proto = instance.__proto__
let prototype = cclass.prototype
while (proto) {
if (proto === prototype) return true
proto = proto.__proto__
}
return false;
}
- Object instanceof Function , Function instanceof Object 答案都是:true
const getType = val => Object.prototype.toString.call(val);
function getPrototypeChains(instance) {
const chains = [];
let proto = instance.__proto__;
chains.push(getType(proto));
while (proto) {
proto = proto.__proto__
chains.push(getType(proto));
}
return chains;
}
const print = console.log;
print(getPrototypeChains(Function));
print(getPrototypeChains(Object));
getPrototypeOf
- 返回对象的原型
- Object.getPrototypeof , Reflect.getPrototypeOf
- 内部先toObject转换,注意null和undefined
const print = console.log;
// null 和 undefined异常
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
// Uncaught TypeError: Cannot convert undefined or null to object
print(Object.getPrototypeOf(10n))
print(Object.getPrototypeOf(Symbol.for("a")))
setPrototypeOf
- 指定对象的原型
- Object.setPrototypeof , Reflect.setPrototypeOf
- 原型的尽头是null
var obj = {a:1};
console.log(obj.toString());
Object.setPrototypeOf(obj, null)
// obj.toString is not a function
console.log(obj.toString());
isPrototypeOf
- 一个对象是否存在于另一个对象的原型链上
- 与instanceof的不同:A对象 instanceof B对象(A是否是B的实例),原型A isPrototypeOf B对象(原型A是否出现在B对象的原型链上)
const print = console.log;
print(Object.isPrototypeOf({}))
print(Object.prototype.isPrototypeOf({}))
print(Reflect.isPrototypeOf({}))
print(Function.isPrototypeOf({}))