8+种姿势访问原型

48 阅读1分钟

前言

本文只是总结访问原型的方法,并不对原型链做深入理解。

8+种姿势访问原型

prototype

  • prototype是一个对象
  • 原型会形成原型链,原型链上查找属性比较耗时, 访问不存在的属性会访问整个原型

注意:toString的怪异现象

var proto = Array.prototype
console.log(typeof proto);
console.log(Object.prototype.toString.call(proto));

image.png

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));

image.png

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({}))

Object.create

总结

image.png