美文网首页
一篇就够-JS的new实现

一篇就够-JS的new实现

作者: johe_jianshu | 来源:发表于2020-03-24 19:18 被阅读0次

    new的作用

    function Fruit(name){
        this.name = name;
    }
    Fruit.prototype.show = function(){
        console.log(this.name);
    }
    
    var banana = new Fruit('banana');
    //输出Fruit.protoype
    console.log(Object.getPrototypeOf(banana));
    //输出Fruit.prototype
    console.log(banana.__proto__);
    //输出'banana'
    console.log(banana.show());
    //输出'banana'
    console.log(banana.name);
    //输出true
    console.log(banana.hasOwnProperty("name"));
    //输出false
    console.log(banana.hasOwnProperty("show"));
    

    可以看到,经过new之后返回了一个对象,该对象的构造函数原型为Fruit.prototype,也就是proto指向Fruit.prototype
    并且banana可以调用show和name属性,但name是其拥有的属性,show是原型上的属性。
    也就是new做了以下几件事

    • 返回一个对象,该对象的proto指向构造函数的原型
    • 该对象会实现构造函数中的实例属性,也就是调用构造函数的apply方法

    初步实现new操作符

    function objectFactory(paramConstrutor){
        if(typeof paramConstrutor !== 'function' ){
            throw new Error("");
        }
        var args = Array.prototype.slice.call(arguments,1);
        //设置obj的proto为constructor的proto,也就是继承共享属性
        //两种方式,
        //一种是直接设置__proto__,官方不建议,后面可能变成只读属性
        var obj = new Object();
        obj.__proto__ = paramConstrutor.prototype;
        //一种是通过Object.create()或者该方式的polyfill
        //模拟Object.create()
        function Empty(){};
        Empty.prototype = paramConstructor.prototype;
        var obj = new Empty();
        //继承实例属性
        paramConstructor.apply(obj,args);
        return obj;
    }
    

    如果构造函数由返回值,那应该是返回新建的对象还是返回值呢?

    • 直接返回返回值,当返回值是Object、Function、Array、Date、RegExg、Error
    • 返回新建对象,当返回值是Null、Undefined、Number、Boolean、String、Symbol
    function Fruit(name){
        this.name = name;
        return {
            a:1
        }
    }
    
    var banana = new Fruit('banana');
    //{a:1}
    console.log(banana);
    
    function Fruit(name){
        this.name = name;
        return 1;
    }
    
    var banana = new Fruit('banana');
    //Fruit {name:'banana‘}
    console.log(banana);
    

    完整代码

    根据上面的返回值,进一步完善代码。
    需要了解的:

    • typeof检测除了Function之外的都为object
    • typeof检测Null为object
    function objectFactory(paramConstructor){
        if(typeof paramConstructor !== 'function'){
            throw new Error("");
        }
        var args = Array.prototype.slice.call(arguments,1);
        //继承共享属性,修改proto属性
        function Empty(){};
        Empty.prototype = paramConstructor.prototype;
        var obj = new Empty();
        //继承实例属性
        var result = paramConstructor.apply(obj,args);
        var isObejct = typeof result === 'object' && result !== null;
        var isFunction = typeof result === 'function';
        if(isObejct ||isFunction ){
            return result
        }
        return obj;
    }
    
    

    相关文章

      网友评论

          本文标题:一篇就够-JS的new实现

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