阻止JavaScript和内部函数的作用域

时间:2016-12-14 17:54:50

标签: javascript

我试图绕过范围界定。根据我的理解,ES5没有阻挡范围的能力,因此,内部f()应该在身体测试的范围内。

这些是运行函数

的结果
  • 测试(真); // [" local"," local"]
  • test(false)// f未定义

但是,我无法理解为什么test(false)会出错?我期待 - [本地]。

  function f() { return "global"; }

    function test(x) {
        var result = [];
        if (x) {
            function f() { return "local"; } // block-local

            result.push(f());
        }
        result.push(f());
        return result;
    }

2 个答案:

答案 0 :(得分:3)

这是您的代码在编译时实际看起来的样子:

function f() { return "global"; }

    function test(x) {
        var result = [];
        var f; 
        if (x) {
            f = function () { return "local"; } // block-local

            result.push(f());
        }
        result.push(f());
        return result;
    }

f变量(保存函数指针的变量)在函数的顶部声明,但它是在条件中定义的。

JavaScript还有一个名为strict mode的功能。这是在语言的最初开发之后进行的,以强制执行一些最佳实践和一些规则,以防止开发人员根据具有类似语法的其他语言对他们认为语言如何工作做出错误的假设。在这种情况下,严格模式实际上会更改新f函数的范围。

以下代码:

function f() { return "global"; }

    function test(x) {
    "use strict" // STRICT MODE TAG INSERTED HERE
        var result = [];
        if (x) {
            function f() { return "local"; } // block-local

            result.push(f());
        }
        result.push(f());
        return result;
    }

test(true);
test(false);

产生以下结果:

["local","global"] //test(true);

["global"] //test(false);

它会覆盖默认的作用域规则,并确保f的新声明仅适用于定义它的条件。

答案 1 :(得分:0)

这是因为当你的条件为真时,'f'是一个函数声明,所以它检查内部f函数。

当x为false时,由于'f'不可见,它会抛出一个错误而无法看到全局'f'函数,因为f已在本地覆盖

要覆盖它,您可以明确调用window.f()或将if条件中的f()设为IIFE

检查这些摘录

function f() {
  return "global";
}

function test(x) {

  var result = [];
  if (x) {

    // block-local
    result.push((function f() {
      return "local";
    })());
  }
  result.push(f());
  return result;
}
var res = test(true);
console.log(res);
var res1 = test(false);
console.log(res1);

希望有所帮助