最近思考跳槽,所以就去加入面试,其中面到一家金融科技公司,考题让我异样粗浅,因为全程被虐。然而,可能因为我对原生 js 的理解多多少少还是晓得些的,至多能晓得面试题考查的是哪些知识点,也多亏面试官是一个特地自信同时又虚心的人,他急躁解答我的疑难并且疏导我去思考,因而幸运通过了面试。
当初我将这个题目分享进去供大家思考,十分的乏味!!
function Foo() {print = function () {console.log(1)
}
return this
}
Foo.print = function() {console.log(2)
}
Foo.prototype.print = function() {console.log(3)
}
var print = function() {console.log(4)
}
function print() {console.log(5)
}
Foo.print()
print()
Foo().print()
print()
new Foo.print()
new Foo().print()
请写出以上代码输入后果,并将剖析后果表达出来?
首先咱们剖析一下调用过程
1、Foo.print()
这里是调用了 Foo 这个对象的 print 函数,考查的知识点是 js 外面一切都是对象,构造函数定义后,为 Foo 对象增加了一个 print 函数,所以输入为 2
2、print()
这里考查了变量晋升和函数晋升
var print = function() {console.log(4)
}
function print() {console.log(5)
}
这两段代码首先会将变量申明和函数的申明晋升到作用域的顶部,就是将 var print = undefined 晋升到顶部,然而赋值表达式还是在书写的地位,第二个函数只是申明了并没有赋值,所以后果输入为 4
3、Foo().print()
这里能够看作两步,先执行构造函数(构造函数当作一般函数执行),执行后返回一个 this,这里的 this 指向的是 window 对象。咱们来看看 Foo 函数外面的代码
function Foo() {print = function () {console.log(1)
}
return this
}
一开始我就留神到外面的 print 没有应用 var 来定义,起初面试官和我说只是一个考点,次要考作用域链。当执行这个函数的时候,在函数外部如果没有找到 print 变量,会去查找父级作用域,因而执行 Foo()函数后,print 函数就从新赋值了,因而这里输入 1
这里其实还有一个考点就是对于 this 指向的问题,大家能够去理解一下。
4、print()执行到这里,print 函数曾经更新了,所以也是输入 1
5、new Foo.print()
这一步其实也是间接调用了 Foo 的属性函数 print,所以输入 2
6、最初一个考点是原型链的常识
先 new 一个构造函数生成实例,而后去调用实例对象上的 print 函数,发现实例对象上没有该函数,就会去实例原型下来查找该函数,因而这里输入 3