这是一道阿里云一面的代码输出题原题,笔者面试的时候直接就是抓耳挠腮,面试官甚至安慰我说你可以多看看,我看你已经痛苦面具了(可能也是因为笔者的面部表情比较丰富吧)
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()
Foo.getName()
: 2,没什么好说的,调用的是 Foo 的静态方法,输出 2getName()
: 4
var
有变量提升以外,function
也有变量提升,而且 function
是将整个声明+初始化提升到顶部,而非像 var
一样将声明提升到顶部,但初始化留在原地function getName()
,然后又被 var
留在原地的初始化覆盖了,故输出为 4Foo().getName()
:1
Foo()
,这个函数体内访问到的 getName
变量实际上就是外部的 getName
,将其覆盖为了输出 1,即 window.getName = function () {console.log(1)}
this
,由于没有使用 new
来调用这个函数,这个 this
实际上就是 window
this.getName()
,也就是 window.getName()
,即输出 1getName()
:1
getName
方法,所以输出还是 1new Foo.getName()
:2
new (Foo.getName)()
,正常调用静态方法,虽然这个方法里没有用到 this,也不影响输出new Foo().getName()
: 3
new new Foo().getName()
: 3
new ((new Foo()).getName)()
,又因为new Foo().getName = function(){console.log(3)}
,就又等同于new function(){console.log(3)}()
,即正常输出3下面对我电脑上的两个运行时的报错进行分析
Foo().getName is not a function
在 V8 中,全局对象是 window
,在 Node 中,全局对象是 global
,关键在于,V8 会把全局的 var/function 绑定到 window
对象上,而 Node 不会将其绑定到 global
上,这就造成了这里的global.getName
没有定义的问题
这是一个比较新的 js 运行时,官网说很快所以我本地运行的时候一般都会用这个,它在var getName = function ()
这里产生了不一样的报错:
SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'getName'.
说明 Bun 的设计者并不允许 var
变量去覆盖一个 function
一段小小的代码输出题,竟然能在三个运行时有三种不同的行为,真是让我打开眼界,当时面试官也没说是什么运行时下的运行结果,是不是也有些不严谨了
#阿里云##前端##秋招#