【问题标题】:Trying to understand better "variable shadowing" [duplicate]试图更好地理解“可变阴影”[重复]
【发布时间】:2021-05-29 03:21:11
【问题描述】:

我知道这是一个全局变量(例如函数内部的原始变量)(局部变量)的问题。全局变量不会被局部变量覆盖。 喜欢:

let a = 10;
function increase1(a){ 
a++; }
increase1(a);
console.log('a = ',a);

所以这行不通。它给了我们 a = 10 下面的代码有效,它给了我们a = 11

let a = 10;
function increase2(){
a++;}
increase2(a);
console.log('a = ',a);

因为它是一样的:

let a = 10;
a++;
console.log('a = ',a);

但为什么这与 increase1 的行为方式相同?

let a = 10;
function increase3(x){ 
x++; }
increase3(a);
console.log('a = ',a);

为什么当我尝试这个时,我得到“undefined”?

console.log('a = ',increase3(a));

谢谢。

【问题讨论】:

  • 您的第三个示例是否缺少let a = 10;
  • increase3 只增加局部变量x,就像increase1 只增加局部变量a。当然,在这个例子中没有外部变量 x 被遮蔽,但这并不重要 - 遮蔽的全部意义在于功能不依赖于其他地方(外部)定义的变量。跨度>
  • "为什么当我登录increase3(a) 时,我得到"未定义"?" - 因为这是函数调用在函数没有return 语句时返回的内容
  • 所有的例子都应该是一样的 let a = 10;... 我编辑了所有的例子。希望我的疑虑现在更清楚了

标签: javascript variables undefined shadowing


【解决方案1】:

首先,您需要了解这里有 2 个作用域,一个是全局的,另一个是功能性的。 将作用域想象成一个对象,其中定义的每个变量都作为属性附加到该对象。这里函数作用域嵌套在全局范围内。

现在变量查找从运行范围(上下文)开始。如果那里不存在变量,它将继续查看外部范围(而不是内部),直到找到变量或到达全局范围

现在案例1:

let a = 10;             //[[globalScope]] = {a: 10}
function increase1(a){  //[[increase1Scope]] = {a : 10} as parameters are local variable to function
a++; }                  //[[increase1Scope]] = {a: 11}
increase1(a);           //here u have passed 10 as a **value**  to increase1 param a(you havent passed global variable **"a"**  but its value)
console.log('a = ',a);  //takes value from its running scope i.e [[globalScope]] which is 10

案例 2:

let a = 10;            //[[globalScope]] = {a: 10}
function increase2(){  //no parameters so [[increase2Scope]] = {}
a++;}                  //[[increase2Scope]] don't have a, so look into next outerscope i.e. [[globalScope]] and alter its value to [[globalScope]] = {a: 11}
increase2(a);         //as increase2() has no defined parameter so this argument of 10 wont do anything
console.log('a = ',a); //same from [[globalScope]] = {a: 11}

案例 3:

let a = 10;             //[[globalScope]] = {a: 10}
function increase3(x){  //[[increase1Scope]] = {x: 10}
x++; }                  //[[increase1Scope]] = {x: 11}
increase3(a);           //value 10 get passed to increase3 -> x
console.log('a = ',a);  //this time [[globalScope]] = {a: 10}, so 10

现在,由于 increase3() 函数没有返回任何内容,所以你得到了 undefined

console.log('a = ',increase3(a));  //undefined

要获得所需的结果,请在函数定义中包含 return 语句:

function increase3(x){  
  x++; 
  return x;
} 

希望它会有所帮助。我试图把一些东西放在眼里。 我强烈建议您阅读以下在线 JS 书籍。肯定会有帮助的。

https://javascript.info/closure

【讨论】:

  • 非常感谢。但我仍然不明白为什么会发生未定义的事情。我试图将 return 放在函数的末尾,但没有帮助。我会阅读您分享的文档
  • 我希望您将值传递给函数。示例:让 a=10;函数增加(x) { x++;返回 x; } console.log('a=',increase(a));
  • 知道了!就像你说的那样,我的回报是正确的。这是未定义的部分原因(我在修复它后进行了测试)。我未定义的另一个原因是因为我有 2 个同名的函数。所以控制台变得混乱。奇怪的是我没有收到任何错误...
【解决方案2】:

案例 1: 这将运行并给出值 10,因为您知道在函数内部更改的值(对象/数组除外) - 因为这些是按值调用而不是引用.

let a = 10;
function increase1(a){ 
a++; }
increase1(a);
console.log('a = ',a);

案例 2: 这将产生错误,因为您没有在任何地方定义 a。您会得到价值增加的虚张声势/海市蜃楼,因为您使用相同的控制台窗口,a 的值来自 chrome-tab 的缓存。它应该给出错误。

function increase2(){
a++;}
increase2(a);
console.log('a = ',a);

案例 3: 这也会出错。只是在使用值进行测试时不要使用相同的 chrome-tab-console。尝试一个新的。你还没有定义a,那么你如何期望值甚至增加?

function increase3(x){ 
x++; }
increase3(a);
console.log('a = ',a);

【讨论】:

  • 它们都具有相同的a定义。在我的程序中,他们都在一起。我只是忘了复制 let a = 10;对于所有示例
猜你喜欢
  • 2020-03-04
  • 1970-01-01
  • 2014-02-24
  • 2016-01-20
  • 1970-01-01
  • 2018-07-05
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多