[英]JavaScript Closure and Scoping issues
Could anyone explain to me the following code: 任何人都可以向我解释以下代码:
var person = (function () {
var locX = 0;
return {
"walk": function () {
locX++;
},
"getLocX": function () {
return locX;
},
"locX": locX
}
})();
person.locX // output 0
person.getLocX() // output 0
person.walk()
person.getLocX() // output 1
person.locX // output 0 <-------- why it is still 0
person.locX// output 0 <-------- why it is still 0 person.locX //输出0 <--------为什么仍为0
Because in the object initializer, this property initializer: 因为在对象初始值设定项中,此属性初始值设定项:
"locX" : locX
takes the value of locX
and assigns it to a property on the object. 接受locX
的值并将其分配给对象的属性。 It doesn't create a link between your locX
variable and the property. 它不会在locX
变量和属性之间创建链接。
It's exactly like this: 就像这样:
var a, b;
a = 1;
b = a;
a = 2;
console.log(b); // 1, of course
Assigning a
's value to b
didn't create any kind of link between a
and b
. 为b
分配a
的值不会在a
和b
之间建立任何形式的链接。 It's exactly the same with an object property. 对象属性完全相同。
If you want to get the value of the variable locX
, your getLocX
function is exactly how you would do that. 如果要获取变量 locX
的值,则getLocX
函数正是您将要执行的操作。
If your goal is to be able to read locX
from the object without explicitly calling a function, but have that value come from your variable, in ES5 onward you could use a getter function for that: 如果您的目标是能够在不显式调用函数的情况下从对象读取locX
,但是该值来自您的变量,那么从ES5开始,您可以使用getter函数:
var person = (function() { var locX = 0; return { walk: function() { locX++; }, get locX () { return locX; } }; })(); snippet.log(person.locX); // 0 person.walk(); snippet.log(person.locX); // 1
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
It's important to realize that using a getter function means that person.locX
is a hidden function call. 重要的是要意识到使用getter函数意味着person.locX
是隐藏的函数调用。
person.locX// output 0 <-------- why it is still 0 person.locX //输出0 <--------为什么仍为0
Problem is here, 问题在这里
"locX" : locX
Unlike getLocX
, only the value 0
was copied at the time of return statement and not the reference of locX
. 与getLocX
不同,在return语句时仅复制了值0
,而不是locX
的引用。
Because changing the value of locX
variable will not update the value of the property, they are not linked together. 因为更改locX
变量的值不会更新属性的值,所以它们不会链接在一起。
A possible solution is to use Object.defineProperty() as below, so that we can return the value of the local variable whenever the value of the locX
property is requested. 一个可能的解决方案是使用Object.defineProperty()如下,这样,无论何时请求locX
属性的值,我们都可以返回局部变量的值。
var person = (function() { var locX = 0; var obj = { "walk": function() { locX++; }, "getLocX": function() { return locX; } } Object.defineProperty(obj, 'locX', { enumerable: true, get: function() { return locX } }); return obj; })(); snippet.log('locX: ' + person.locX); snippet.log('getLocX: ' + person.getLocX()); person.walk(); snippet.log('walk') snippet.log('locX: ' + person.locX); snippet.log('getLocX: ' + person.getLocX());
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Or as TJ said using getter 还是TJ所说的使用吸气剂
var person = (function() { var locX = 0; return { "walk": function() { locX++; }, "getLocX": function() { return locX; }, get locX() { return locX; } }; })(); snippet.log('locX: ' + person.locX); snippet.log('getLocX: ' + person.getLocX()); person.walk(); snippet.log('walk') snippet.log('locX: ' + person.locX); snippet.log('getLocX: ' + person.getLocX());
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.