likes
comments
collection
share

这道面试题不是特别变态

作者站长头像
站长
· 阅读数 81

题目

var foo = function () {
    console.log("foo1")
}
foo()

var foo = function () {
    console.log("foo2")
}
foo()


function foo() {
    console.log("foo1")
}
foo()

function foo() {
    console.log("foo2")
}
foo()

知识点

这道面试题涉及到两个知识点,一个是变量提升,一个是变量的声明与赋值,搞懂这两个问题,这题就迎刃而解了。

变量提升

当你使用var关键字(注意,这个特性不适用于letconst)声明一个变量时,JavaScript会将这个声明移动到其所在作用域的顶部。但是,请注意,只有声明被提升,赋值不会

JavaScript会将这个声明移动到其所在作用域的顶部。 这句话应该很好理解吧。就是我定义的变量,都会被放到代码最顶处,不管你书写位置在哪。

我们着重看变量的声明与赋值。

变量的声明与赋值

怎么去理解只有声明被提升,赋值不会这句话呢?

我们需要去先去理解什么是声明,什么是赋值

就比如下面代码:

var a = 1

我们可以把它看成是两行代码组成,分别是

var a = undefined//声明部分
a = 1 //赋值部分;

相信大家看完这个例子,应该就明白了。大概可以这么去理解,声明就是表明存在这么个东西,但是这个东西是什么,我不去管。赋值就是给存在的这个东西赋予明确的值;

懂了什么是声明,什么是赋值之后,就很容易理解“只有声明被提升,赋值不会”这句话了。

我们再通过一个例子去解释这句话

console.log(a);
var a = 1;

程序会报错吗?答案是不会的。它会输出undefined。为什么是undefined呢?因为a = 1这行代码声明被提升了,而赋值没有被提升。

“首先声明被提升到作用域顶部,但是赋值是不变的”,因此代码实际实际效果可以等同于如下代码。在执行到第二行时,a未被赋值,它此时还是默认值undefined,所以输出结果是undefined

var a = undefined
console.log(a);
a = 1;

欸?当我们声明了一个变量会发生声明提升,赋值不提示的情况,那么函数呢?我声明一个函数,它的声明和赋值是什么情况?声明会不会提升啊?赋值呢?

比如下面代码:

console.log(a);
var a = function() {
    console.log('fun');
};

它还是会打印undefined,因为它实际效果是这样的

var a = undefined
console.log(a);
a = function() {
    console.log('fun');
};

好,这道面试题的关键点快来了。下面情况会发生什么?

a()
var a = function() {
    console.log('fun');
};

结果是Uncaught TypeError: a is not a function。这大家是很容易理解的,因为我们上面都打印a了,它是undefined么,因此报错a不是一个函数。这不是显而易见嘛!

但是把代码改成下面这段就不会出问题了,它会正常打印fun,这是为什么呢?

a()
function a() {
   console.log('fun');
};

原因在于此时的a函数,它是通过function声明的,它是一个完整的函数声明,也就是说没有涉及到赋值操作

如何理解这句话呢?也就是说,如果直接通过function声明的函数,它直接在声明的时候就进行了赋值操作,而不是先声明它,并设置一个undefined,然后进行赋值操作。

最终的代码可以等同于

function a = function() {console.log('fun')}
a()

看到没,它将a直接提到了最顶部,并且给它声明,它就是一个函数,这个函数要干什么干什么。而不像之前那样,我先给它定义个初始值undefined,然后再去赋值。

这样的话,执行a的时候,就不会报错,能够正确输出值。

不行,我还的给大家画一幅图来解释下吧。(因为我当初理解这块的时候就理解了好久,所以才如此啰嗦给大家讲解,属实抱歉。)

这道面试题不是特别变态

解答

具备以上知识后,就可以发现,它题目代码可以等同于如下;

var foo = undefined;
var foo = undefined;
function foo = function foo() {
    console.log("foo1")
}
function foo = function foo() {
    console.log("foo2")
}
foo = function () {
    console.log("foo1")
}
foo()

foo = function () {
    console.log("foo2")
}
foo()
foo()
foo()

这下子结果就一目了然了吧。先foo1,然后三个foo2。

小伙伴们,以上是我的一个理解,欢迎大家批评指正。

转载自:https://juejin.cn/post/7369813870633812019
评论
请登录