JS 操作符优先级及new

基于segmentfault上的一道题

题目

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);}
new foo.getName ();      // 第一种       
new foo().getName ();         // 第二种
new new foo().getName ();       // 第三种
    
  • 首先先了解下优先级(由高到低)


    JS 操作符优先级及new_第1张图片
    MDN

由此可以知道new 的优先级带参数的比不带的高

解析

  • 第一种
    new foo.getName (); '.'的优先级比new高
    所以先执行foo.getName,在来执行new
    也就是new (foo.getName) () // 返回一个foo.getName的实力 获得就是2
  • 第二种
    new foo().getName (); 主要犹豫的地方是先foo()函数运算还是先new
    foo()先new (foo().getName)()
    new 先 (new foo()).getName()
    如果new 不带参数的优先级确实比函数调用的优先级低,但现在new是带参数的所有优先级
    所以执行的 (new foo()).getName() // foo()上的getName方法,但是没有这个方法所以去原型上找,结果为3
  • 第三种
    new new foo().getName (); 从上面分析得,new带参数会优先执行,这是在从左至右的运算基础下实现的
    也就是第一步new (new foo().getName)()
    第二步 new ((new foo()).getName)()
    最后进行运算 先计算new foo(), 在获取getName,在对获取内容进行new ()计算
    new ((new foo()).getName)() 也就是 new (foo.prototype.getName)()
    返回的就是3, 具体可以看下面new 原理解析

new原理

在第三种解析中我们要计算 new (foo.prototype.getName)()的值,首先要明白new到底做了什么,其实就做了3件事

var obj  = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

第一步:创建一个空对象
第二步:绑定该对象的原型
第三部:调用构造函数 // 执行了构造函数的内容
所以在 new (foo.prototype.getName)()也就会返回foo.prototype.getName的一个实例,并且执行一次构造函数,也就是执行console.log(3),打印3这个结果

你可能感兴趣的:(JS 操作符优先级及new)