Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么在';如果';条件';外部不可见的表达式部分?_Javascript - Fatal编程技术网

Javascript 为什么在';如果';条件';外部不可见的表达式部分?

Javascript 为什么在';如果';条件';外部不可见的表达式部分?,javascript,Javascript,为什么日志会导致错误,f尚未在上述表达式中定义 您可能认为这相当于: if (function f() {}) { console.log(f) // Throw an error: f is not defined } 函数声明被视为函数表达式(如函数(){}),而不是函数语句 证明: if (function f() {}) { console.log(f) // Throw an error: f is not defined } 如果函数实际上是一条语句,则无法立即

为什么日志会导致错误,
f
尚未在上述表达式中定义


您可能认为这相当于:

if (function f() {}) {
    console.log(f) // Throw an error: f is not defined
}
函数声明被视为函数表达式(如函数(){}),而不是函数语句

证明:

if (function f() {}) {
    console.log(f) // Throw an error: f is not defined
}
如果函数实际上是一条语句,则无法立即执行它(如果不将其括在括号中或在其前面加上
将其转换为表达式)


你的假设是错误的。这两个片段并不相同。第一种是不存储值(实际的函数对象)的。这样的对象总是真实的-因此执行
if
get


这些函数的函数名(或者更确切地说应该是)仅在函数本身内部可见(某些早期IE版本除外)。因此,由于
f
根本不存在,当您试图将其传递到
控制台时,会抛出
ReferenceError
。log

函数声明语句在其周围范围内定义函数,甚至将定义移到顶部。但是,这是一个命名函数表达式。函数由其内部的名称定义,而不是外部的名称(旧IE中除外,它是一个bug)。除此之外,它只是一个设置了名称的函数。只有当语句以关键字
function
开头时,它才算作function语句

这项工作:

function f(x) {return x}(false) //Would yield a syntax error
当你说

function f(){};
if (f) console.log(f);
它是一个函数声明语句。此函数将在封闭环境中定义。因此,如果它是在另一个函数中定义的,那么该函数将在该环境中定义,您可以通过名称访问该函数

但是,当您在表达式中使用函数声明时,它将不会被视为函数声明,而是函数表达式,其计算方式如下(引用自)

生产

函数表达式:

function f () {}
评估结果如下:

  • funcEnv作为调用的结果传递正在运行的执行上下文作为参数
  • 让envRec成为funcEnv的环境记录
  • 调用envRec的(N)具体方法,传递标识符的字符串值作为参数
  • 让闭包作为创建一个新函数对象的结果,如13.2所述,该函数对象的参数由FormalParameterListopt指定,主体由指定。传入funcEnv作为作用域。如果FunctionExpression包含在中或其FunctionBody是Strict code,则将
    true
    作为Strict标志传入
  • 调用envRec的(N,V)具体方法,传递标识符和闭包的字符串值作为参数
  • 返回关闭
  • 因此,当您在表达式中创建函数时

  • 将创建一个新的环境上下文(请参见第一项)

  • 函数名将绑定到新创建的环境(请参见第三项)

  • 函数体将用于创建实际的函数对象(参见第四项)

  • 创建的实际函数对象绑定到新创建的上下文中的函数名称(参见第五项)

  • 然后返回函数对象


  • 由程序在当前环境上下文中将函数对象指定给变量以保留函数。否则,当表达式计算完成时,新创建的环境上下文将无效。因此,函数
    f
    在外部将不可见。

    我不确定为什么要在
    if
    语句中声明一个函数,如果您在它上面声明
    var f=function(){}
    ,它就可以正常工作。此外,如果执行
    if(f=function(){})
    它工作得很好。块范围和函数范围之间似乎存在混淆,但我认为这与此无关。我建议编辑。@Doge,你的编辑把问题弄糊涂了。您正在将变量f声明为函数。这与声明函数不同。正如许多人所说,
    如果(f=function(){})
    有效。。。因为它将函数存储在一个全局变量中。
    function f(){}
    相当于
    var f=function(){}
    假定了某些约束。您认为原始代码等同于什么?条件现在为false,因此不会打印任何内容。这并不能解释为什么
    if
    语句中没有
    f
    。这是一个激进的编辑。是其他答案之一改变了你的想法吗?:-)不,我只是想弄清这个问题的真相,仅此而已。所以我检查了规格。@mpm:Excellent插图,当涉及到b/w语句和表达式的差异时。然而,在我的例子中,最后一行没有产生语法错误(Google Chrome)。你的解释和链接在我看来很好地解释了这个问题。我甚至试过,因为这个问题本身非常有趣。-“factorial”名称仅在函数体中可见。很可能
    f
    是一个引用错误,而且
    console.log
    甚至没有被调用;当然,
    console.log
    可以记录
    未定义的
    为什么它的行为像一个命名函数?我认为命名函数应该像本例中的@Smeegs那样被赋值。放置(如if条件)使其成为表达式而不是声明。命名函数表达式中的名称不是来自变量名,而是来自函数名。这在函数本身之外是不可见的。明白了,这就是为什么函数从未声明过。它计算函数声明,但实际上并不声明函数(函数本身之外)
    function f(){};
    if (f) console.log(f);
    
    function f () {}
    
     function Identifier ( FormalParameterListopt ) { FunctionBody }