2021.6.23 (预解析-运算符-函数声明)

104 阅读1分钟

问题描述

说出并解释下列代码的输出结果:

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()
// 解析:调用window.Foo.getName(),打印 2                
Foo().getName()
// 解析:Foo() 就是普通函数调用,返回的this 是window,后面调用的是window.getName()
// 而window 下的getName 属性在Foo() 中被调用,getName 被重新赋值,因此打印 1
getName()
// 解析:在执行Foo().getName() 的基础上,所以getName = function() {console.log(1)}, 打印 1
// 如果getName() 放在Foo().getName() 上面执行,则打印 4 [函数声明会提升]
new Foo.getName()
// 补充知识:JS 运算符优先级 
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
// 解析:根据运算优先级先执行Foo.getName() 后执行new, 因此执行Foo构造器私有属性的getName(), 打印2
new Foo().getName()
// 解析:根据执行顺序, 可以改造表达式为 var bar = new Foo()    bar.getName()
// 先执行new Foo() 获得一个实例对象,然后执行实例对象原型上的getName方法,打印 3
new new Foo().getName()
// 解析:根据执行顺序,可以改造表达式为 var bar = new Foo().getName    new bar()
// 先执行new Foo() 获得一个实例对象,然后将实例对象原型上的getName方法作为构造函数,生成实例后执行,打印 3