search

Home  >  Q&A  >  body text

javascript - if语句内的function声明会不会被提前?

关于JS函数运行时预解释的问题,函数运行时会在内部也预解释,提升function函数声明及var变量声明。
但是如下代码:为什么运行时候提示条件判断内的 g is not a function 呢?
按照预解释,不是会把条件语句内的 function g(){ return true; } 声明提前的吗?

(function(){
    if(g()){    //提示此行 g is not defined
        console.log('hello world');
        function g(){ return true; }
    }
})();

但是下面的代码没有报错,而且打印了 hello world,证明 function g(){ } 是提前了的,但是 g 并没有被赋值为函数(很可能值是undefined),所以上面的例子中才会提示 g is not defined。

(function(){
    if(!g){
        console.log('hello world');
        function g(){return true;};
    }
})();

得出结论:if语句体中的 function 函数声明会被提前,但是函数名并未被赋值。
大牛们帮忙看看这个问题,是不是有这样的问题呢?

天蓬老师天蓬老师2812 days ago1986

reply all(4)I'll reply

  • 怪我咯

    怪我咯2017-04-11 10:35:12

    前面的答案里很多人都说 IIFE 里的函数声明不会提前,这是不对的。比如说这样:

    (function() {
      if (g()) {
        console.log('OK');
      }
      function g() { return true; }
    })()

    所以无所谓 IIFE,只要是函数作用域声明都会提前,IIFE 也是函数,无非就是定义之后立刻执行而已。

    真正的问题在于原题中的 function g() {...} 生命在 if 语句内部。在 strict mode 出现之前,if 语句(以及其他条件语句所创造的代码块内)内部的函数声明是否会提前是没有一致性的,不同的浏览器会做出不同的解释,所以最佳实践的代码规范都会要求不要在这里面声明和定义函数。

    直到 strict mode 出现之后,明确规定了在此种情形下的函数声明会抛出错误,所以现在写代码都会约定遵循严格模式以避免这些问题。

    另外 ES6 模块缺省就是严格模式的,也就是跟上语言的发展潮流是上策,不要再和以前那些不完善的坑做无谓的周旋了。

    reply
    0
  • PHP中文网

    PHP中文网2017-04-11 10:35:12

    首先你这么写可能会有问题,因为 g = function(){ return false; } 后面没有分号,或者说 (function() {})() 前面没有分号。

    然后,即使不是在自运行函数中,类似的 if 语句仍然不能运行,比如

    // globl scope
    if (!g()) {
        console.log("hello");
        function g() { return false; }
    }

    因为需要 if 判真才会定义 g,那在 if 判断的时候 g 肯定是不存在的。

    再来说自运行函数内容,同样的道理,如果你把 g 定义在 if 之外,就没有问题了。

    reply
    0
  • 迷茫

    迷茫2017-04-11 10:35:12

    这不是自调函数的问题

    if(g() && []==![]){
            f = function(){ return false; }
            function g(){ return true; }
        }

    一样会报错,你要是if条件没通过,解释器都不会读里面的声明函数。

    reply
    0
  • 阿神

    阿神2017-04-11 10:35:12

    iife 里的函数表达式不会提前声明!

    reply
    0
  • Cancelreply