在微信群中看到有人发出了一道 Javascr 面试题,比较菜的我还是很感兴趣的,立马就撸了起来。
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()
初步看一下:这道题目涉及的知识点还是挺多的,含有 这几点知识点的考察
第一步:由于 Js 是单线程的,所以代码是一行一行的往下执行的,但是由于变量提升的问题,我们可以得出
function Foo() {
getName = function() {console.log(1)}
return this
}
+ var getName
+ function getName() {console.log(5)}
Foo.getName = function() {console.log(2)}
Foo.prototype.getName = function() {console.log(3)}
- var getName = function() {console.log(4)}
- function getName() {console.log(5)}
+ getName = function() {console.log(4)}
...省略
变量声明,函数声明会提到最前面来,此时 getName 为 function getName()
{console.log(5)}
第二步:看看程序执行到 Foo.getName() 时的变化
function Foo() {
getName = function() {console.log(1)}
return this
}
+ var getName
+ function getName() {console.log(5)}
Foo.getName = function() {console.log(2)}
Foo.prototype.getName = function() {console.log(3)}
- var getName = function() {console.log(4)}
- function getName() {console.log(5)}
+ getName = function() {console.log(4)}
...省略
此时 getName 为 function getName() {console.log(4)}
第三步:程序执行到 Foo.getName() 结束时,输出结果为 2
第四步:程序执行到 getName() 结束时,输出结果为 4
第五步:程序执行到 Foo().getName() 结束时,输出结果为 1
function Foo() {
getName = function() {console.log(1)}
return this
}
...省略
Foo().getName()
...省略
调用了 Foo 函数,因为 Foo 作用域中的 getName 没有用 var 声明,所以 getName 是一个全局变量,即此时的 getName 为 function() {console.log(1)}
又因为 Foo 函数显示的返回 this, Foo() 运行时是一个隐式调用相当于 window.Foo()
,所以 this 为 window。 window.getName() => 1
第六步:程序执行到 getName() 结束时,输出结果为 1
第七步:程序执行到 new Foo.getName() 结束时,输出结果为 2
function Foo() {
getName = function() {console.log(1)}
return this
}
...省略
new Foo.getName()
...省略
由 Js 运算符优先级可知:. 运算符高于 new ,所以 new Foo.getName()
相当于 new (Foo.getName)()
第八步:程序执行到 new Foo().getName() 结束时,输出结果为 3
new Foo().getName()
相当于 (new Foo()).getName()
第九步:程序执行到 new new Foo().getName() 结束时,输出结果为 3
new new Foo().getName()
相当于 new ((new Foo()).getName)()
Js 原算符优先级汇总表
【学习笔记,有错误之处,敬请指教,谢谢阅读!😊】
【如对您有帮助,请点个赞,谢谢!😊】