var 函数名 = function(){} 控制台提示 is not a function

boom();
function boom(){
    alert("good");
}

以上正常alert

boom();
var boom = function(){
    alert("good");
}

这上面的代码无法alert出内容,求大牛告知。

以下为html结构

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>abc</title>    
    </head>
    <body>
        <p>TEST</p>
<script src="js/test.js"></script>
    </body>
</html>
阅读 5.9k
6 个回答

先说结论:

两种函数定义的方式不一样,导致函数提前的方式不同

1.第一种方式,我们称为函数声明,在这种情况下,整个函数都被提升了,包括函数体。即

boom();
function boom(){
    alert("good");
}

等价于

function boom(){
    alert("good");
}
boom()

2.第二种方式,我们称为函数表达式,在这种情况下定义的函数,仅做函数名称的提升,函数体会留在原来的位置,即

boom();
var boom = function(){
    alert("good");
}

等价于

var boom = undefined;
boom();
boom = funciton() {
    alert("good");
}

调用boom()时,boom为undefined,因此会报错,

Uncaught TypeError: boom is not a function

函数表达式和function命令在变量提升上有区别

boom();
var boom = function(){
    alert("good");
}

// 这个实际上是
var boom;
boom() // 这里当然会报错,声明而未赋值
function boom(){}
boom()
function boom(){}

// 这个实际上是
function boom(){}
boom()
// 这个就是提升

这个和html结构一点关系都没有。有关系的是js的生明提升。

第一个有效是因为你声明boom()的位置并不是真正的位置,他实际上是被提到头部就声明好了,所以调用写在你生命的前面也没关系。

第二个也是一样的,但不同在于提升的方式,你那段代码就可以拆分成这样:

var boom = underfined;

boom();

boom = function(){
    alert("good");
}

所以你调用boom的时候,boom是underfined,不会alert任何东西的。

函数声明提升

因为函数的提升是整体提升,包含了声明和赋值。
但是变量提升,只是声明提升,在其赋值之前也不能正常使用。

根本原因是js的声明提升。

js的函数声明提升有两种,一种是变量声明提升,一种是函数声明提升。

在预解析时(代码执行之前的预处理),解析器会把所有的var关键字之后的变量名和function关键字之后的函数声明提升到最顶端。当代码执行时,这些变量名和函数名都已经被添加到了当前作用域,可以直接使用了。

对于变量声明,只提升声明不提升赋值,也就是说只有当执行到赋值的那一步时,变量才有值,否则默认是undefined。

而对于函数声明,是整体提升,也就是说无论函数在哪里定义,在预解析时都会提升到最顶端,所以在当前作用域的任何位置都可以调用。

对于第一种情况是函数声明,所以可以直接调用。

对于第二种情况是变量声明,在执行赋值的到那一步前,boom都是一个值为undefined的变量。所以如果调用会出现boom is not a function的错误。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题