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();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
20 行的会在变量 / 函数提升,被 16 行重新赋值,所以 window.getName() 是 console.log(4);
Foo.getName();
对应第 8 行,输出 2
getName();
对应 window.getName();
,输出 4
Foo().getName();
- 首先第 2 行执行,Foo() 的词法环境是 window, getName 是 window 的 getName。所以这里又重新赋值 window.getName 为 console.log(1);
- Foo() 执行后返回 this,这个 this 是指向 window,对应
window.getName();
,输出 1
getName();
对应 window.getName();
,在第 2 行执行时已经修改,输出 1
成员访问比 new 无参数列表的优先级高,但 new 有参数列表是与成员访问一样的,
即 new 是对应到出现 () 为止,把那部分作构造函数
new Foo.getName();
是 new 第 8 行的构造函数,输出 2
new Foo().getName();
是 new 第 1 行的构造函数,
- 返回 this 是 Foo 的实例
- 其实例没有 getName() 方法,所以会向其原型上找
- 找到第 12 行,所以输出 3
new new Foo().getName();
new Foo()
是 new 第 1 行的构造函数, 返回 this 是 Foo 的实例记作 foonew foo.getName()
, 成员访问比 new 无参数列表的优先级高,foo 没有 getName 又从其原型找foo.getName()
就是第 12 行的原型,然后 new Foo.prototype.getName(),输出 3
2
4
1
1
2
3
3