简体   繁体   English

JavaScript关闭和作用域问题

[英]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不会在ab之间建立任何形式的链接。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM