美文网首页
经典Foo和Foo.getName

经典Foo和Foo.getName

作者: _章鱼小丸子 | 来源:发表于2019-05-15 16:59 被阅读0次
    function Foo(){
        getName = function(){
            console.log(1);
        };
        return this;
    } 
    
    Foo.getName = function(){
        console.log(2);
    }
    
    Foo.prototype.getName = function(){
        console.log(3);
    }
    
    var getName = function(){
        console.log(4);
    }
    
    function getName(){
        console.log(5);
    }
    
    Foo.getName();//2
    
    getName();//4
    
    Foo().getName();//1
    
    getName();//1
    
    new Foo.getName()//2
    
    new Foo().getName();//3
    
    new new Foo().getName();//3
    
    

    输出解释如下:

    1. Foo.getName()
      Foo的静态方法优先级高于方法内部定义,调用Foo.getName(),输出2

    2. getName()
      function getName()变量提升,声明后被var getName= function(){...}覆盖,输出4

    3. Foo().getName()
      调用Foo()函数,返回的this,则当前的全局window变为Foo内部的this,再调用getName()时就是调用Foo内的getName(),输出1

    4. getName()
      由于第三步已经将Foo的this覆盖了window,调用getName()时,仍然时调用Foo的getName(),输出1

    5. new Foo.getName()
      等价于new (Foo.getName()),先执行Foo.getName(),输出2,再创建Foo.getName()方法的实例。

    6. new Foo().getName()
      相当于(new Foo()).getName(),先创建Foo的实例,调用实例的getName()方法,由于自身没有该方法,去原型链上找,它的原型指向构造函数的prototype,即调用Foo.prototype.getName(),输出3

    7. new new Foo().getName()
      相当于new (new Foo().getName()),即先执行new Foo().getName(),由第六步可知,输出3,再创建Foo.prototype.getName()这个函数的实例返回。

    知识点

    1. 为什么new Foo().getName()先运算new Foo(),而new Foo.getName()是先运算Foo.getName?

    对照下面链接里的优先级,看这两个的区别:

    • new Foo() 属于new(带参数列表)
    • new Foo属于new(无参数列表)

    无参数列表的优先级为18,而成员访问的优先级为19,高于无参数列表。因此new Foo.getName()先执行Foo.getName()

    带参数列表的优先级为19,而成员访问的优先级也为19,按照运算符规则(同一优先级,按照从左向右的执行顺序),new Foo().getName()先执行new Foo(),再对new之后的实例进行成员访问.getName()操作。
    这是js运算符的优先级链接,可查看每个运算符的优先级。

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

    相关文章

      网友评论

          本文标题:经典Foo和Foo.getName

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