
都可以弹出alert,但是上面那个在控制台输出了undefined,是怎么回事?
-----update-----
多谢大家的耐心解答,起初我的疑惑就是foo这个对象定义的先后顺序问题,因为使用非hoisted的函数定义方式在chrome的控制台中仍然可以正常运行而没有报TypeError。后来我新建文件之后再测试是完全没问题的。所以这里导致困惑的主要就是chrome对undefined输出的解释了。再次感谢@BetaRabbit
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
虽然一般情况下Javascript的编译和运行时的界限很模糊,但为了回答你的问题,我在这里还是想区分一下这两个概念。
编译器在看到下面例子里的函数时,它知道你在定义一个函数,这个函数名叫foo,foo将在程序运行的始终绑定到这个函数(因为他是这个函数的名字)。所以foo是这个函数的名字,他绑定到这个函数
而上面这个例子,编译器定义了一个匿名函数,它没有名字,尔后的赋值将这个匿名函数对象赋值给了变量foo,所以foo是一个变量,里面储存的是这个函数
另, 他们有一个挺大的区别:
最后提供一篇文章: http://davidbcalhoun.com/2011/different-ways-of-defining-functions-in-javascript-this-is-madness/, 作者总结的很详细,关于JS里各种函数定义的方法及其细微区别
UPDATE:
手机上码字写着写着就顺着自己思路来了,其实只回答了题主一半的问题:
1。 第一次foo()的调用应该是会失败的,有同学已经指出了,我们猜测题主之前可能已经定义过这个foo,所以第一次调用foo时才居然没有失败。非hoisted的函数定义方式只能先定义再使用,之前所答其实主要就是解释了这个
2。关于undefined的behavior,有同学从JS语言规范的角度解释了。但是简单理解的话,对于赋值语句和函数定义语句来说,他们是一种操作,没有值这是理所应该的吧。简单看看这个例子:
另外题主第二个例子里没有undefined输出,我开始也很奇怪,所以在chrome里试了试,于是我想说题主你把那个alert对话框点掉后再看看呢 :-)

楼上的答案都是错的,这个和hoist没有关系,和函数表达式和函数声明也没有关系。
真正的原因是,语言规范要求,返回
undefined节选自http://www.ecma-international.org/ecma-262/5.1/#sec-12.2
最后的(normal, empty, empty)是什么意思呢,规范里面叫The Completion Specification Type。
综上所述,返回值的value是个
empty,具体到javascript里面,就是undefined了。PS: 类似会返回(normal, empty, empty)还有很多,比如,
{}: 空block(不是对象);: 空语句所有声明变量或声明函数都会被提升到当前函数的顶部。MDN链接地址
变量foo提升到顶部
等价为==>
会执行报错
TypeError: foo is not a function. (In 'foo()', 'foo' is undefined)你说的执行输出了undefined,要看下之前的代码是什么样的!
是不是之前已经定义过foo函数了
而对于
函数foo声明提升到顶部
等价为
执行正常~~~
变量定义提升与函数声明提升
用
function关键字声明的函数,会有一个函数声明提升的过程,所以你可以在声明函数之前进行调用。如果使用函数表达式来定义函数,只能在定义之后来调用,原因在于会存在一个变量声明提升。