这是 JavaScript 中变量影子的例子吗?

Is this an example of variable shadowing in JavaScript?

提问人:fakeguybrushthreepwood 提问时间:8/10/2012 最后编辑:Flimmfakeguybrushthreepwood 更新时间:5/17/2022 访问量:41612

问:

我在 Eloquent Javascript(第 3 章)中学习了术语变量阴影,但我正在尝试理解这个概念的一个精确的基本示例。

这是影子的例子吗?

var currencySymbol = "$";

function showMoney(amount) {
  var currencySymbol = "€";
  console.log(currencySymbol + amount);
}

showMoney("100");

JavaScript 阴影

评论

1赞 Felix Kling 8/10/2012
是的。另请参阅 stackoverflow.com/questions/5373278/...

答:

35赞 Madara's Ghost 8/10/2012 #1

这也是所谓的可变范围

变量仅存在于其包含的函数/方法/类中,这些函数/方法/类将覆盖属于更广泛范围的任何变量。

这就是为什么在您的示例中,将显示一个欧元符号,而不是美元。(因为包含美元的范围比包含欧元符号的范围更广(全球)。currencySymbolcurrencySymbol

至于你的具体问题:是的,这是变量阴影的一个很好的例子。

16赞 Eric Robinson 8/10/2012 #2

在计算机编程中,当在特定作用域(决策块、方法或内部类)中声明的变量与在外部作用域中声明的变量同名时,就会发生变量阴影。据说这个外部变量是阴影的......

所以我相信你的榜样是好的。

您有一个全局命名的变量,该变量与 Inner Method 同名。内部变量将仅在该函数中使用。没有该变量声明的其他函数将使用全局函数。

12赞 Platinum Azure 8/10/2012 #3

是的,你的例子是影子的一个例子。

由于闭包在 JavaScript 中的工作方式,阴影也会在其他场景中持续存在。下面是一个示例:

var x = -1;
function xCounter() {
    var x = 0;
    return function() {
        ++x;
        return x;
    };
}

console.log(x);   // -1
counter = xCounter();
console.log(counter());   // 1
console.log(counter());   // 2
console.log(x);   // still -1, global was never touched

请注意,在这种情况下,即使 xCounter 返回,它返回的函数仍然具有对它自己的引用,并且对该内部函数的调用对全局函数没有影响,即使原始函数早已超出范围。x

1赞 Musty 7/9/2019 #4
var role = "Engineer";
console.log(role);

function displayRole(){
    role = "developer";
    console.log(role);
}

displayRole();
console.log(role);

请注意最后一行代码 (console.log) 的打印方式,但它不在函数范围内。这是一个很好的例子,说明全局作用域中的角色变量已被函数作用域中的角色覆盖。developershadowing

为了避免影子,应使用 var 关键字声明函数作用域中的变量,以便它仅可供函数访问。

评论

2赞 Jakub Strebeyko 4/10/2020
代码很好,但解释具有误导性 - 所做的不是变量阴影,而是命名空间冲突,导致覆盖外部范围的变量。影子完全是通过对给定范围的变量重新声明(通过添加一个)而不是重新分配来实现的 - 这是一个有意识的设计决策,而不是要避免的“本身”发生的事情。请参见:github.com/getify/You-Dont-Know-JS/blob/1st-ed/...displayRole()rolevar
0赞 Jakub Strebeyko 4/10/2020
转念一想,关于上述内容,代码也是错误的;P不好意思
4赞 Yilmaz 8/7/2019 #5

我们不能多次定义一个变量。但是我们可以在不同的范围内定义。

let name="tara"
if(true){
  let name="ali"
  if(true){
    console.log(name)
  }
}

变量阴影是指局部作用域中的变量使用其值而不是父作用域中的变量。因此,局部变量值在父项上有所遮蔽。

在上面的代码中,定义了两个名称变量,但它们未在同一作用域中定义。因此,console.log(name)将检查本地范围,如果它找到使用它的名称变量,如果没有,它将检查父范围,一旦找到它,它就会使用该范围,因此它不会进入根目录。

0赞 Tejaswini G 5/17/2022 #6

是的,这是影子的一个很好的例子。当全局作用域变量具有相同的名称时,称为块作用域变量的阴影。这发生在您的代码中,并且块作用域正在遮蔽全局作用域。