javascript - JavaScript 中基于范围的变量阴影

标签 javascript function scope

我很难理解 JavaScript 中基于范围的变量阴影。考虑这个小代码片段:

var k = {
    prop1: 'test',
    prop2: 'anotherTest'
}

for(var k = 0; k < 10; k++) {
    console.log(k);
}

//prints number
console.log(typeof k);

//prints 10
console.log(k);

//undefined
console.log(k.prop1);

这很好,因为由于直接函数作用域,循环计数器变量 k 隐藏了我们之前声明的 json 变量 k。因此,可以说 json 变量 k 变得不可访问。

问题:


  1. 在内存分配方面,现在没有办法访问 原始的 json var k,是否符合垃圾回收条件?将要 分配的内存被释放?或“引用孤立”变量 还活着吗?如果是,为什么以及持续多长时间?

  2. 有没有一种不用写就可以访问原始 json var k 的方法 for 循环之前的任何代码?

现在考虑另一个稍微修改过的代码片段:

var k = {
    prop1: 'test',
    prop2: 'anotherTest'
}

var m = {
    prop1: k
}

for(var k = 0; k < 11; k++) {
    console.log(k);
}

//prints number
console.log(typeof k);

//prints 10
console.log(k);

//undefined
console.log(k.prop1);

//reference altered? No, this reference points to the original json k
//firebug dumps object to console
console.log(m.prop1);

问题:


  1. 这一次,我们持有对原始 k 的引用,在 另一个 json 对象。当然,内存不会 取消分配。但是,不会评估 m.prop1 解决更新 整数 k,值为 10?为什么这个决议没有导致 值为 10 的循环计数器?

最佳答案

1# In terms of memory allocation, now that there is no way to access the original json var k, is it eligible for garbage collection? Will the allocated memory be freed? Or the 'reference-orphaned' variable still live on? If yes, why and for how long?

只有一个变量叫做k . var 不会在其他语言的意义上“声明变量”1这里没有阴影。相反,它是 提升 到函数顶部的注释。

k 之前已知的对象不再强可达,因此可以回收。 (具体何时取决于实现,但它是合格的。)

2# Is there a way of accessing the original json var k WITHOUT writing any code before the for loop?

只有一个变量叫做k . var 不会在其他语言的意义上“声明变量”1这里没有阴影。相反,它是 提升 到函数顶部的注释。

循环中的赋值覆盖相同 k变量。

3# This time, we hold a reference to the original k before hand, in another json object. And surely, the memory will not be de-allocated. But, wouldn't evaluating m.prop1 resolve to an updated integer k, with a value of 10? Why isn't this resolution leading to the loop counter with value 10?

变量不是对象。表达式(包括变量名称)在 JavaScript 中急切地求值。由变量 k 命名的对象 什么时候m = { prop1: k }评估现在被命名为m.prop1 .为变量分配一个新值 k因此对k没有影响之前评估为。

在 JavaScript 中,对变量的唯一引用出现在赋值的左侧或像 typeof 这样的运算符。或 del .否则,变量从不在表达式产生式中是引用。不要将引用与 Call-By-Object-Sharing 混淆,或“对象变异”,语义:改变一个对象的属性会改变那个对象。 (正如所见,一些类型,如 number不可变的,并且不允许自定义属性“固定”。)


以上假定代码出现在一个函数中。 var 的规则在任何函数之外时都略有不同——在这种情况下,它声明一个局部变量,而是k只会(仍然)指的是全局 window.k属性(property)。

1 正确的术语“声明”;但是,我发现将其视为注释,因为它是关于 x 的函数级属性并且在声明的意义上不是“评估”,更清楚。例如,这两个函数是等价的:

function () { var x = 1; return x }
function () { x = 1; return x; var x }

另见:

关于javascript - JavaScript 中基于范围的变量阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11113292/

相关文章:

javascript - JQuery UI 可排序,输入框不可编辑

javascript - NuxtJS在中间件中设置Cookie

function - Emacs 按键输入备忘单

class - 为什么嵌套类会让包含类访问子类的 protected 数据?

variables - PHP - if 语句和 while 循环内的变量范围

Ruby 实例变量还是局部变量?

javascript - 分割文档并插入为多个的转换

javascript - 如何在 ES6 中导出静态函数?

PHP "Undefined Function"即使它实际上在同一个文件中

c++ - 如何从 main.cpp 文件中的单独 cpp 文件调用函数?