为什么函数语句在使用设置为方法时不创建函数

Why function statement doesn't create a function when using setting it as a method?

本文关键字:函数 方法 创建 语句 为什么 设置      更新时间:2023-09-26

我遇到了以下行为:

> foo = {};
{}
> foo.bar = function bar() { return arguments; }
[Function: bar]
> bar()
ReferenceError: bar is not defined
    at repl:1:2
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.emit (events.js:98:17)
    at emitKey (readline.js:1095:12)

bar不应该是当前范围内的函数吗?

添加[var] bar =可以解决问题:

> bar = foo.bar = function bar() { return arguments; }
[Function: bar]
> bar(1)
{ '0': 1 }

但是为什么没有分配给bar它就不起作用呢?

您在(在赋值的 RHS 上(中使用函数关键字的上下文使其成为函数表达式,而不是函数声明。

function() 之间放置一个名称会使其成为命名函数,但由于它不是函数声明,因此不会在当前范围内创建变量。

请注意,命名函数表达式在旧 IE 中存在内存泄漏问题。

在该上下文中使用该类型的函数声明时,将创建命名函数表达式 (NFE(。当您有一个函数声明时,将其与简单地声明命名函数形成对比。

规范规定,NFE的名称只能在函数本身内部访问。以下是查看差异的方法:

var x = function() { console.log(foo); }      // (anonymous) function expression
x(); // ReferenceError: foo is undefined
var y = function foo() { console.log(foo); }  // NFE
y(); // function foo()...

您实际上是在创建命名函数表达式。因此,它不在当前范围内,而是作为方法分配给对象foo的属性。

我敢肯定,在没有给出名称的表达式(而不是声明(中使用 function 关键字时,您创建了一个您已经知道的匿名函数。

在表达式上下文中的 function 关键字和()之间添加名称时,将创建命名函数表达式

函数

名称的范围在函数本身内,因此在函数内部,您可以使用 bar() 递归调用自身,但在函数外部,它不存在并为您提供遇到的 ReferenceError