var a = function b(){};
a(); //正常
b(); //报错
这是为什么?????
在 JS 里面函数有两种定义的方法
函数声明
函数表达式
其中函数声明只有一种形式:
function 标识符(形参) { 函数代码 }
而函数表达式有两种写法:
function (形参) { 函数代码 }
function 标识符(形参) { 函数代码 }
可见,函数声明的语法和函数表达式的第二种语法是一样的。函数声明只会声明一个函数,因为有变量声明提升的机制,所以函数声明不会有返回值。而函数表达式不是一个声明,是一个标准的 js 表达式,会有一个返回值,返回值就是定义的那个函数。所以说对于函数声明和函数表达式的第二中写法的区分就是要看需不需要一个返回值。var a = function b(){}
显然需要一个返回值,所以function b(){}
是一个函数表达式。如果把其作为一个函数声明,那么根据变量声明提升就会导致这一句代码有错误。
函数表达式的第二种写法的执行过程是:
创建一个新的词法记录器(在函数执行的时候会根据这个记录器创建作用域)
在记录器中创建一个名为标识符
的变量。
根据函数代码
创建一个函数
把那个标识符
初始化为这个函数
返回这个函数
也就是说,在函数表达式中给出的那个函数名仅仅在该函数中有效。只能在定义的那个函数中使用。
参考 http://www.ecma-international.org/ecma-262/5.1/#sec-13
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
function b () {}
这种形式是一个函数声明,而var a = function () {}
这种形式是函数表达式,所以var a = function b () {}
也是一个函数表达式,只不过表达式中的函数带有名字,但因为这个声明形式是函数表达式而非函数声明,所以b
这个名称是不会被在当前作用域下声明成为一个可调用的函数,这是因为函数表达式的执行过程是建立一个函数对象然后返回给变量,从头到尾都没有作用域下的声明行为,不过在函数中是可以调用函数它自己的名称的.详情可看 @锋云战锦 的链接,说的很好。
另外请注意函数声明提升: