简体   繁体   English

从对象内部访问时变量变为0

[英]Variable becomes 0 when accessing from within Object

I have created an Object like so: 我已经创建了一个像这样的对象:

var Object = function() {
    var value = 0;

    function do() {
        console.log(value);
    }

    return {
        do : do,
        value : value
    }
};
exports.Object = Object;

I am calling the do function from outside of this Object: 我从这个对象的外部调用do函数:

function call(object) {
    console.log(object.value);
    object.update();
}

I have set the value to equal 2.5 outside of the player class. 我已将值设置为等于Player类之外的2.5。 The bizarre thing is that when I execute the code, the console logs this: 奇怪的是,当我执行代码时,控制台会记录以下内容:

2.5
0
2.5
0

So it seems that the value is 0 from within the class, but 2.5 when I access it from outside it. 因此,似乎该值从类内部为0,但从类外部访问时为2.5。 What is the issue here? 这是什么问题?

My background is mainly Java, and I am rather new to Javascript, so perhaps I have missed something trivial. 我的背景主要是Java,而我对Javascript比较陌生,所以也许我错过了一些琐碎的事情。

You have created a closure: You're returning an object which has a property value , but the var value inside the closure does not change when you change the value property of the returned object. 您已经创建了一个闭包:您将返回一个具有属性value的对象,但是当您更改返回对象的value属性时,闭包内的var value 不会更改

Explained another way, when you say new Object , then you get two value s one is returned as a property of the object, and the other is the var object hidden inside the closure. 用另一种方式解释,当您说new Object ,您将获得两个value s,一个作为对象的属性返回,另一个是隐藏在闭包内部的var object

Try the following: 请尝试以下操作:

var Object = function() {
    this.value = 0;

    function do() {
        console.log(this.value);
    }

    return {
        do : do
    }
};

exports.Object = new Object;

Alternatively: 或者:

var Object = function() {
    var value = 0;

    function do() {
        console.log(value);
    }

    return {
        do : do,
        getValue : function(){ return value; },
        setValue : function(val){ value = val; }
    }
};

exports.Object = Object;

As Josh mentioned, this is a value vs reference issue, which is usually addressed by either returning an object (so it's by reference) or including functions like getValue and setValue . 如Josh所述,这是一个valuereference问题,通常可以通过返回一个对象(因此通过引用)或包括诸如getValuesetValue类的函数来解决。

For the second option, you could actually re-write your function and use getters , like so: 对于第二个选项,您实际上可以重新编写函数并使用getters ,如下所示:

var Object = function() {
    var value = 0;

    function _do() {
        console.log(value);
    }
    function update(val) {
        value = val * .5;
    }
    return {
        do: _do,
        update: update,

        // Our fancy getter!
        get value() {
            return value;
        }
    }
};
exports.Object = Object;

At this point, Object.value would behave similar to getValue . 此时, Object.value行为类似于getValue

Since it's Friday, let's go crazy and add our setter as well: 由于是星期五,让我们疯狂起来,同时添加我们的setter

var Object = function() {
    var value = 0;

    function _do() {
        console.log(value);
    }
    return {
        do: _do,

        // Our fancy getters/setters!
        get value() {
            return value;
        },
        set value(val) {
            value = val * .5;
        }
    }
};
exports.Object = Object;

Then you're doing things like: 然后您正在执行以下操作:

Object.value; // Returns 0
Object.value = 5;
Object.value; // Returns 2.5
Object.do(); // Logs 2.5

Defining Getters and Setters 定义getter和setter

Getter/Setter compatibility Getter / Setter兼容性

In fact , your code is equivalent to 实际上,您的代码相当于

var Object = function() {
  var value = 0;

  function do() {
    console.log(value);
  }

  var res= {
    do : do,
    value : value
  }
  return res;
 };
exports.Object = Object; 

the function do() will not log the res.value . 函数do()不会记录res.value Instead it logs a local variable of function Object , that means you can't change the value do returns. 相反,它记录功能的局部变量Object ,这意味着你不能改变的价值do回报。

if you want to log res.value , can try following: 如果要记录res.value ,可以尝试以下操作:

function do(){
    console.log(this.value);
}

However I have to mention something else. 但是我不得不提些其他的事情。 if value is an object instead of literal. 如果value是一个对象而不是文字。 you can easily access it. 您可以轻松访问它。 A closure is unable to protect an object from been changed as object is passed by ref. 当对象由ref传递时,闭包无法保护对象不被更改。

Just try this: 尝试一下:

var Object = function() {
    var value = [0];

    function doSth() {
        console.log(value[0]);
    }

    var res= {
        do : doSth,
        value : value
    }
    return res;
};
exports.Object = Object; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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