一道有趣的面试题

Posted 前端茅台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道有趣的面试题相关的知识,希望对你有一定的参考价值。

最近考虑跳槽,所以就去参加面试,其中面到一家金融科技公司,考题让我异常深刻,因为全程被虐。但是,可能因为我对原生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

以上是关于一道有趣的面试题的主要内容,如果未能解决你的问题,请参考以下文章

一道有趣的面试题

一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)

一道有趣的阿里面试题

测试开发实战|一道有趣的大厂测试面试题,你能用 Python or Shell 解答吗?

一道面试题

一道有趣的签到题