同系列文章请查看:Github:pre-interview
原题
1 | function Foo() { |
分析
Foo.getName() - 2
本质:执行Foo函数上的静态方法
1 | // 函数Foo的静态方法 -> 函数对象上的方法/属性 |
getName() - 4
执行:
1 | // 给全局变量赋值为一个匿名函数 |
Foo().getName() - 1
1 | // 构造函数 |
执行过程:
Foo() -> this -> window -> window.getName() 重新赋值成 1
getName() * 2 - 1
被重新赋值了: window.getName() = 1 => getName() = 1
new Foo.getName() - 2
注意区别 new Foo()
1 | // 函数Foo的静态方法 -> 函数对象上的方法/属性 |
这里的 new
没有实质作用,将函数改为如下:
1 | // 函数Foo的静态方法 -> 函数对象上的方法/属性 |
this打印结果:
Foo.getName {} 对象
指向实例化的新对象
此时回顾到第一种情况 [Foo.getName() - 2](#Foo.getName() - 2) ,该静态方法也被调用了,那么此时的 this 就会指向谁调用它的对象上,即 Foo
调用了getName 方法,this 指向 Foo 函数对象上,打印结果如下:
1 | ƒ Foo() { |
new new Foo().getName() - 3
拆分一下:
1 | var foo = new Foo() // 实例化对象 foo,继承了原型属性上的方法 |
即执行下面的函数:
1 | // 扩展函数原型上的方法 |
第一个 new
没有实际意义;
如果只写成 new new Foo()
,报错:
Uncaught TypeError: (intermediate value) is not a constructor
总结
-
Foo.getName() 调用
Foo
函数上的静态方法 -
Foo().getName() 调用
Foo
返回值下(window)的 getName 方法 -
new Foo.getName() 实例化了
Foo
函数上的静态方法 -
new Foo().getName() 实例化了
Foo
构造函数再调用 getName 方法
蚌埠住了
Tips: Please indicate the source and original author when reprinting or quoting this article.