美文网首页
手写instanceof和new操作符

手写instanceof和new操作符

作者: 小宇cool | 来源:发表于2020-09-11 15:58 被阅读0次

    instanceof

    instanceof是JavaScript的保留字, 通常用于判断某个对象是否为另一个对象(构造方法)的实例, instanceof会查找原型链, 直到null如果还不是后面这个对象的实例就返回false, 否者就返回true.

    下面是一个简单的例子

    let obj = {name:'张三'};
    obj instanceof Object // true
    

    因为在js中,变量都是通过构造函数创建的,这种字面量的方式其实是一种语法糖变量obj其实是通过Object这个构造函数通过创建出来的, 所以obj是构造函数Object的实例, 返回会返回true;

    由于实例对象的原型默认等于构造函数的原型, 所以我们可以通过查找目标对象的原型链,是否等于构造函数的原型来判断这个目标对象是否为这个构造函数的实例对象

    需要注意的是, instanceof只能判断数据类型为function和object的变量

    0 instanceof Number //false
    fasle instanceof Boolean // false
    'str' instanceof String // false
    
    function isIntanceof(obj,cons){
        // 错误判断 构造函数类型必须为 函数
        if(typeof cons !== 'function') throw new Error('The paramenter type must be an function');
        // 判断obj不为null, 或者obj的类型不为object, 且类型不为function 返回true时返回 fasle
        if(!obj || (typeof obj !== "object" && typeof obj !== 'function')) return false;
        // 获取构造函数的原型对象
        let proto = cons.prototype;
        // 如果原型的对象不为null, 就一直查找, 否者就停止,如果找到了就返回true 
        while(obj.__proto__){
            if(obj.__proto__ === proto ) return true;
            obj = obj.__proto__
        }
        return false;
    }
    

    所以instanceof 可以准确的判断复杂数据类型,但是不能正确的判断基本数据类型.由于typeof判断array时返回的object,此时我们需要使用instanceof精准判断才能达到我们需要的结果.

    [] instanceof  Array // true
    typeof [] // false
    

    New

    new的定义

    new运算符创建一个用户的对象类型的实例, 或者具有构造函数的内置对象的实例.

    new做了什么

    1. 创建新的一个空对象,
    2. 将new操作符调用的构造函数的prototype原型对象指向新创建的空对象
    3. 将这个对象作为该函数执行的上下文(this)
    4. 如果该函数没有返回值或者返回值不是引用类型,则返回上面的对象

    上面的难点就在于改变函数的执行上下文this,我们都知道this指向调用的对象, 我们可以给对象添加一个fn属性指向函数体,如果该对象调用fn函数,执行函数体内部this就指向了该对象

    let obj = {name:'张三'};
    function fn(){
        console.log(this.name)// 张三
    }
    obj.fn = fn;
    obj.fn()
    

    了解了上面的几点之后我们就可以手写一个new

    function _new(fn){
        // 创建一个空对象
        let newObj = Object.create()
        // 如果构造函数的原型不为空, 就将构造函数的原型指向新创建的对象的原型
        if(fn.prototype !== null) newObj.__proto__ = fn.prototype;
        // 获取所有的参数集合
        let args = Array.prototype.slice.call(arguments,1);
        // 将构造函数的this指向新创建的对象, 并将剩余的参数传递给构造函数
        let res = fn.call(newObj, ...args)
        // 判断构造函数返回的值是否不为空,且类型为对象或者函数时 如果条件成立 ,返回 res
        if(res !== null && (typeof res === 'object' ||typeof res === 'function')){
            return res;
        }
        // 返回新创建的对象
        return newObj
    }
    

    相关文章

      网友评论

          本文标题:手写instanceof和new操作符

          本文链接:https://www.haomeiwen.com/subject/dbhbektx.html