Javascript变量范围和值
我的问题是为什么函数Javascript变量范围和值,javascript,function,namespaces,scope,Javascript,Function,Namespaces,Scope,我的问题是为什么函数alert(namepace.blog)返回5而不是我所期望的6?这里要理解的重要一点是,JavaScript中的所有名称都是对其他对象的引用 使用对象文字创建对象时,左侧名称用于引用已由右侧名称引用的对象 在这种情况下,当你 var namepace = (function () { var loca = 5; var getLocal = function () { loca += 1; return loca;
alert(namepace.blog)代码>返回5
而不是我所期望的6
?这里要理解的重要一点是,JavaScript中的所有名称都是对其他对象的引用
使用对象文字创建对象时,左侧名称用于引用已由右侧名称引用的对象
在这种情况下,当你
var namepace = (function () {
var loca = 5;
var getLocal = function () {
loca += 1;
return loca;
};
return {
glob: getLocal,
blog: loca,
frog: function () {
return loca;
}
};
})();
alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
blog: loca,
namepace.frog()
您所说的blog
是指loca
所指的值,即5。稍后,当您增加loca
时,它变为6
,这意味着它引用了一些其他值,但blog
仍然引用值5
这就是为什么您会得到5
但当你这么做的时候
var namepace = (function () {
var loca = 5;
var getLocal = function () {
loca += 1;
return loca;
};
return {
glob: getLocal,
blog: loca,
frog: function () {
return loca;
}
};
})();
alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
blog: loca,
namepace.frog()
您正在获取由loca
引用的当前值。由于它是在getLocal
中分配的6
,因此您将获得6
递增创建新的数字对象
更清楚地说,当你这么做的时候
var namepace = (function () {
var loca = 5;
var getLocal = function () {
loca += 1;
return loca;
};
return {
glob: getLocal,
blog: loca,
frog: function () {
return loca;
}
};
})();
alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
blog: loca,
namepace.frog()
或
内部发生的是,类似这样的事情
loca++;
参考ECMAScript 5.1规范,用于和
由于数字是不可变对象(您可以更改5
的值吗?您不能更改,这就是为什么它被称为不可变对象的原因),因此会创建一个新的数字对象,并在其中添加一个对象,并使名称loca
引用新对象
可变对象
如果你考虑可变对象
oldValue = loca
newValue = oldValue + 1
loca = newValue
现在,blog
和loca
都引用相同的数组对象。在glob
中发生的事情称为变异。您只是将一个元素添加到数组对象中,该数组对象具有两个名称blog
和loca
。这就是为什么namepace.blog
也会打印[1]
这是一个逻辑问题。当函数需要一些时间时。在指定的时间变量中。。看看下面的代码。试试这个
var namepace = (function () {
var loca = [];
return {
glob: function () {
loca.push(1);
return loca;
},
blog: loca,
frog: function () {
return loca;
}
};
})();
console.log(namepace.glob());
// [ 1 ]
console.log(namepace.blog);
// [ 1 ]
console.log(namepace.frog());
// [ 1 ]
当分配给namespace.blog
时,您使用的是传递给setter的值。这意味着没有关于loca
的参考
当您通过namespace.frog
访问该值时,您使用的是原始变量,该变量利用JavaScript的闭包作用域解析为loca
,本地作用域链上的下一个可用定义
您可以在这里阅读有关作用域的内容:当JavaScript程序运行时,考虑执行上下文会有所帮助。JavaScript计算引用(而不是直接计算值)
全局上下文由全局变量和对象组成。在这种情况下(JavaScript解释器读取名称空间指令时):
这意味着命名空间正在引用函数。在第一个警报时,将为命名空间创建以下执行上下文:
namespace = {f} // namespace references a function
因此,函数glob被调用。glob引用名为getLocal的函数。glob的执行上下文如下所示:
loca = 5 // loca references the value 5
getLocal = {f} // getLocal references a function
return { // return object with glob, blog and frog as properties
glob = { getLocal() } // references the function getLocal()
blog = 5 // blog references same value as loca: 5
frog = {f} // references anonymous function
}
下一个调用是blog,这个调用返回值5。它不涉及loca。它仅引用loca在创建执行上下文时具有的值。创建执行上下文时,loca引用的值为5,因此博客引用的值为5。
无论你多久调用一次glob,blog都会引用5的值
在最后一条alert语句中,将调用frog。frog引用了一个现在正在执行的匿名函数。frog的执行上下文如下
loca = 6 // loca now references the value 6
return loca // return value referenced by loca
基本上就是这样。每当你想到价值时,试着去想“参考价值”。这有助于习惯它。并尝试在程序运行时可视化执行上下文(如作为人工调试器)