我试图绕过范围界定。根据我的理解,ES5没有阻挡范围的能力,因此,内部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;
}
答案 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);
希望有所帮助