无法从功能内部覆盖功能



我得到了意外的结果。这是代码:

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();

最新更新