在JavaScript中基于范围的变量投影 [英] Scope based variable shadowing in JavaScript

查看:129
本文介绍了在JavaScript中基于范围的变量投影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  var k = {
prop1:'test',
prop2: (var k = 0; k <10; k ++){
console.log(k);'anotherTest'
}

;
}

//打印数字
console.log(typeof k);

//打印10
console.log(k);

//未定义
console.log(k.prop1);

这很好,因为由于立即函数范围,循环计数器变量k会隐藏json变量我们早些时候决定。因此,变量k变得无法访问。



问题:


  1. 就内存分配而言,现在无法访问原始json var k的
    ,是否有资格进行垃圾回收?将
    分配的内存释放吗?或者参考孤儿变量
    仍然活着?如果是的话,为什么和多长时间?


  2. 有没有办法在for循环之前写入
    任何代码的原始json var k?

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

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

var m = {
prop1 :k
}

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

//打印数字
console.log(typeof k);

//打印10
console.log(k);

//未定义
console.log(k.prop1);

//引用改变了吗?不,这个引用指向原始的json k
// firebug转储对象到控制台
console.log(m.prop1);

问题:


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


解决方案

< blockquote>

1#在内存分配方面,现在没有办法访问原始的json var k,是否符合垃圾回收的条件?分配的内存是否被释放?或者参考孤儿变量仍然存在?


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



以前由 k知道的对象不再是强烈可及,因此可以回收。 (确切地说是依赖于实现的,但它是符合条件的。)


2#有没有一种访问方式原始的json var k没有在for循环之前编写任何代码?


只有一个变量被调用ķ var 在其他语言的意义上不会声明变量 1 。这里没有阴影。相反,它是一个将注释提升到函数的顶部。



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


<3>#这次我们持有原始k在另一个json对象之前。当然,内存不会被解除分配。但是,不会评估m.prop1解析为更新的整数k,值为10吗?为什么不是这个分辨率导致循环计数器的值为10?


变量不是对象。表达式,包括变量名,在JavaScript中被热切地评估。当 m = {prop1:k} 时,由变量 k 命名为的对象评估现在由 m.prop1 命名。因此,为变量赋予一个新值 k k 之前进行了评估。



JavaScript中变量的唯一引用出现在赋值的左侧或像 typeof del 。否则,表达式生成中的变量永远不会引用。不要将引用与按对象共享混淆,或者对象变异 ,语义:改变对象的属性改变该对象。 (正如所看到的, number 之类的某些类型是不可变的,并且不允许自定义属性粘住。)






上面假设代码出现在函数中。在任何函数之外, var 的规则略有不同 - 在这种情况下,不是声明局部变量,而是 k 就会引用全局 window.k 属性。



1 正确的术语declares;然而,我发现把它看作是一个注释,因为它是一个关于 x 的函数范围的属性,并且在声明的意义上没有被评估,更多明确。例如,这两个函数是等价的:

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






另见:




I'm having difficulty understanding variable shadowing in JavaScript based on scopes. Consider this small code fragment:

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);

This is fine, because owing to the immediate function scope, the loop counter variable k shadows the json variable k we declated earlier. Hence the json variable k becomes inaccessible so to speak.

Question:


  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?

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

Now consider another slightly modified code fragment:

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);

Question:


  1. 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?

解决方案

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?

There is only one variable called k. var does not "declare a variable"1 in the sense of other languages. There is no shadowing here. Rather, it is an annotation lifted to the top of the function.

The object that was previously known by k is no longer strongly reachable and thus can be reclaimed. (Exactly when is implementation dependent, but it is eligible.)

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

There is only one variable called k. var does not "declare a variable"1 in the sense of other languages. There is no shadowing here. Rather, it is an annotation lifted to the top of the function.

The assignment in the loop overwrites the same k variable.

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?

Variables are not objects. Expressions, including variable names, are eagerly evaluated in JavaScript. The object named by the variable k when m = { prop1: k } was evaluated is now named by m.prop1. Assigning a new value to the variable k thus has no effect to what k previously evaluated to.

The only references to variables in JavaScript appear on the left-hand-side of an assignment or to operators like typeof or del. Variables are never references in an expression production otherwise. Do not confuse references with Call-By-Object-Sharing, or "object mutating", semantics: changing a property of an object mutates that object. (As seen, some types like number are immutable and do not allow custom properties to "stick".)


The above assumes the the code appears in a function. The rules for var are slightly different when outside of any function -- in that case it does not declare a local variable, rather k would just (still) refer to the global window.k property.

1 The correct terminology is "declares"; however, I find that thinking of it as an annotation, as it is a function-wide attribute about x and is not "evaluated" in the sense of a statement, is more clear. For example, both of these functions are equivalent:

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


See also:

这篇关于在JavaScript中基于范围的变量投影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆