详解instance和new的用法

instanceof

原理

其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。

因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。

手写instanceof

instanceof 就是判断构造函数的 prototype 属性是否出现在实例的原型链上。

function instanceOf(left, right) {
    let proto = left.__proto__
    while (true) {
        if (proto === null) return false
        if (proto === right.prototype) {
            return true
        }
        proto = proto.__proto__
    }
}

上面的 left.proto 这种写法可以换成 Object.getPrototypeOf(left)

function instance_of(L, R) { // L 表示左边表达式 R表示右边表达式
    const O = R.prototype; // 取R的显式原型
    L = Object.getPrototypeOf(L); // 取L的隐式原型 L = L.__proto__
    while(true) {
    // Object.prototype.__proto__ === null
        if(L===null) {
            return false;
        }
        if(L===O) { // 当L严格等于O时,返回true
            return true;
        }
        L = Object.getPrototypeOf(L); // // 没找到继续向上一层原型链查找 L = L.__proto__
    }
}

function Foo(name) {
  this.name = name;
}
var f = new Foo('nick')

f instanceof Foo // true
f instanceof Object // true

new

new 运算符用来创建用户自定义的对象类型的实例或者具有构造函数的内置对象的实例。

实现要点:

  • new 会产生一个新对象;
  • 新对象需要能够访问到构造函数的属性,所以需要重新指定它的原型;
  • 构造函数可能会显示返回;

手写new

function objectFactory() {
    var obj = new Object()
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    var ret = Constructor.apply(obj, arguments);
    
    // ret || obj 这里这么写考虑了构造函数显示返回 null 的情况
    return typeof ret === 'object' ? ret || obj : obj;
};
function _new(constructor, ...args) {
    // 构造函数类型合法判断
    if(typeof constructor !== 'function') {
      throw new Error('constructor must be a function');
    }
    // 新建空对象实例
    let obj = new Object();
    // 将构造函数的原型绑定到新创的对象实例上
    obj.__proto__ = Object.create(constructor.prototype);
    // 调用构造函数并判断返回值
    let res = constructor.apply(obj,  args);
    let isObject = typeof res === 'object' && res !== null;
    let isFunction = typeof res === 'function';
    // 如果有返回值且返回值是对象类型,那么就将它作为返回值,否则就返回之前新建的对象
    return isObject || isFunction ? res : obj;
};

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:
1. 本站所有文章教程及资源素材均来源于网络与用户分享或为本站原创,仅限用于学习和研究。
2. 如果内容损害你的权益请联系客服QQ:1642748312给予处理。
码云笔记 » 详解instance和new的用法

发表回复

IT互联网行业相关广告投放 更专业 更精准

立即查看 联系我们