美文网首页
实现构造器函数,同时支持new作用和普通函数调用

实现构造器函数,同时支持new作用和普通函数调用

作者: 不知所语 | 来源:发表于2018-11-12 18:21 被阅读13次

    题目

    实现一个构造器函数A,同时支持var a = new A()与var a = A()两种形式,且支持A类的继承

    首先支持new作用是比较容易实现的(应该是我们拿到这个题目立马能写出来的)

    function A(){
        this.name = 'John';
    }
    
    A.prototype.say = function(){
        console.log(`I am ${this.name}`);
    }
    

    思路

    既然new关键字可以帮我们完成一系列的对象实例化工作,那么当A作为普通函数被调用时也可以在函数内部实现new的整个过程,这样就可以解决问题啦。应该有同学想到直接调用下new是吧,哈哈哈~,我觉得这也太省事了,自己实现new的过程岂不更爽!接下来应该区分A是在哪种形式下被调用的,根据不同的调用方式做不同的处理。

    问题

    • 1、A作为普通函数调用时如何实现new的效果

    问题可以转换为new的过程做了什么?

    var a = {};
    a.__proto__ = A.prototype; //继承构造函数原型的属性和方法
    var result = A.apply(a, arguments); //拥有A的实例属性和方法
    return type result === 'object' ? result : a;
    
    • 2、如何区分A当前是作为构造器使用还是普通函数调用

    首先要清楚一点,var a = new A(),此时A中的this指向的是a实例;var a = A(),此时this指向的是window(浏览器中),因此我们可以根据this是否是A的实例来区分函数的调用方式,从而进行不同的处理。

    解决了上面两个问题,再试着把A函数改写下

    实现

    function A(){
        if(!(this instanceof A)){
            var a = {};
            a.__proto__ = A.prototype; //a是A的实例
            A.apply(a, arguments);
            return a;
        }else{
            this.name = 'John';
        }
        
    }
    
    A.prototype.say = function(){
        console.log(`I am ${this.name}`);
    }
    
    var a1 = new A();
    var a2 = A();
    a1.name; //'John'
    a2.name; //'John'
    a1.say === a2.say; //true
        
    

    Yeah~

    相关文章

      网友评论

          本文标题:实现构造器函数,同时支持new作用和普通函数调用

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