我得到了意外的结果。这是代码:
b = function c() {
console.log(c);
c = 3;
console.log(c);
}
b();
我认为第二个控制台。log应该打印" 3",但我得到了功能本身。为什么?
同时,从下面的代码中,我得到了正确的" 3"。
function ff() {
ff = 3;
console.log(ff);
}
ff();
您无法在其自己的声明中覆盖函数的命名变量。NFE(命名函数表达式)名称不能被覆盖(因为它是常数)
当您以严格的JS模式编写时,这很明显。尝试下面的示例:
'use strict';
var b = function c(){
console.log(c);
c = 3; // c still is a function
console.log(c);
}
b();
您正在使用函数表达式:
功能表达:
函数标识符 opt (正式参数列表 opt ){functionbody}
因此,b = function c() { ... };
是完全有效的,严格的模式或其他方式。c
发生的事情是另一个问题。根据规格:
生产
功能表达:功能标识符( 正式参数列表 opt ){functionbody}
评估如下:[...]
3.调用 createImmutableBinding Envrec的具体方法 将标识符的字符串值作为参数。
4.闭合是创建新功能对象的结果 如13.2 [...]
中指定 5.调用Envrec的初始iMimmutablebincting混凝土方法 将标识符的字符串值和闭合作为参数。
[...]注意
可以从功能表达中的标识符从 在功能表达的功能机构内部允许函数到达 递归称呼自己。但是,与函数交流不同, 无法从和执行功能表达中的标识符 不影响包含功能表达的范围。
so:
-
c
在功能中可见,但在其外部不可见 -
c
不能从函数内部覆盖(一个"不可变"绑定)
同时,从下面的代码中,我得到了正确的" 3"。
function ff() {
这是函数声明;在此处适用不同(更明显的)规则。
第一个示例中显示的函数声明模式称为NFE(命名函数expression ),而Othher othher被称为函数函数声明strong>。最大的区别是,在NFE的情况下,函数的名称,在我们的情况下,i.e. c
只会使函数的范围限制。因此,如果您尝试以其外部的名称来调用它,则会收到错误,c is not defined
,这意味着c
在全球范围内不存在。
b = function c(){
console.log(c);
c=3;
console.log(c);
}
c(); //c is not defined
现在,仔细观察 c 的功能主体内的c=3
行。该代码块通常会做的,是由名称C创建 global变量,在功能体外部也可以在函数外部访问。但是,在这里,由于c
已经生活在函数自己的身体范围内,因此它不会让您在那里声明,因为它将意味着覆盖其自己的名称,而在 nfe ,(,但在函数声明的情况下允许,即,所讨论的第二个示例)。这就是为什么分配代码c=3
在这里没有做任何事情的原因。
要更接近地实现它,您可以使用var c=3
更新c=3
,在这种情况下,它将让您在功能主体内部以c
的名称来声明局部变量,然后您可以在功能内使用。
b = function c(){
console.log(c);
var c=3;
console.log(c);
}
b();