JavaScript中基于作用域的变量阴影
我很难理解JavaScript中基于作用域的变量阴影。考虑这个小代码片段:JavaScript中基于作用域的变量阴影,javascript,function,scope,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.prop
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);
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);
var k={
建议1:‘测试’,
建议2:‘另一项测试’
}
对于(var k=0;k<10;k++){
控制台日志(k);
}
//打印号码
控制台日志(k型);
//印刷品10
控制台日志(k);
//未定义
控制台日志(k.prop1);
这很好,因为由于immediate函数作用域的缘故,循环计数器变量k会隐藏我们前面提到的json变量k。因此可以说json变量k变得不可访问
问题:现在考虑另一个稍微修改的代码片段:
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);
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);
var k={
建议1:‘测试’,
建议2:‘另一项测试’
}
var m={
建议1:k
}
对于(var k=0;k<11;k++){
控制台日志(k);
}
//打印号码
控制台日志(k型);
//印刷品10
控制台日志(k);
//未定义
控制台日志(k.prop1);
//参考变更?不,此引用指向原始json k
//firebug将对象转储到控制台
控制台日志(m.prop1);
问题:k
的变量<代码>变量不在其他语言的意义上“声明变量”1。这里没有阴影。相反,它是一个提升到函数顶部的注释
以前由k
知道的对象不再是强可达的,因此可以回收。(具体时间取决于实现,但符合条件。)
2#是否有一种方法可以访问原始json var k,而无需在for循环之前编写任何代码
只有一个名为k
的变量<代码>变量不在其他语言的意义上“声明变量”1。这里没有阴影。相反,它是一个提升到函数顶部的注释
循环中的赋值覆盖相同的k
变量
3#这一次,我们在另一个json对象中持有对原始k的引用。当然,内存不会被取消分配。但是,对m.prop1求值是否会解析为一个更新的整数k(值为10)?为什么这个分辨率不导致循环计数器的值为10
变量不是对象。表达式(包括变量名)迫切需要用JavaScript进行计算。当计算m={prop1:k}
时,由变量k
命名的对象现在命名为m.prop1
。因此,为变量k
指定一个新值对先前计算的k
没有影响
JavaScript中对变量的唯一引用出现在赋值的左侧,或者像typeof
或del
这样的操作符。否则,变量永远不会在表达式产品中引用。不要将引用与语义或“对象变异”语义混淆:更改对象的属性会使该对象变异。(如图所示,某些类型,如number
是不可变的,不允许自定义属性“粘滞”。)
以上假设代码出现在函数中。当在任何函数之外时,
var
的规则略有不同——在这种情况下,它不会声明局部变量,而k
只会(仍然)引用全局window.k
属性
1正确的术语是“声明”;但是,我发现将其视为注释更为清晰,因为它是关于x
的函数范围属性,并且不是语句意义上的“评估”。例如,这两个功能是等效的:
function () { var x = 1; return x }
function () { x = 1; return x; var x }
另见:
prop1:k
时,您正在将k的引用指针传递给对象m。。。然后,当您用var k=0
重写时,您的意思是当前变量名k应该与一个全新的对象关联。。。对它的原始引用只字未提……如果我的答案让人困惑,我想我的措辞没有那么好……只有一个变量叫做k
。变量名为对象。变量不是对象。