最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why doesn't my variable's value change when a variable its value relies on also changes? - Stack Ov

programmeradmin1浏览0评论

After hitting the increment button in my code below, y is equal to 7, but z stays equal to 7 instead of changing to 8.

Why don't JavaScript variables update within other variables? Is there a solution to this problem?

<body>
    <script>
        var y=6;
        var z=1+y;
    </script>
    <button onclick="y++">Increment</button>
    <button onclick="alert(y)">What is y?</button>
    <button onclick="alert(z)">What is z?</button>
</body>

After hitting the increment button in my code below, y is equal to 7, but z stays equal to 7 instead of changing to 8.

Why don't JavaScript variables update within other variables? Is there a solution to this problem?

<body>
    <script>
        var y=6;
        var z=1+y;
    </script>
    <button onclick="y++">Increment</button>
    <button onclick="alert(y)">What is y?</button>
    <button onclick="alert(z)">What is z?</button>
</body>
Share Improve this question edited Mar 19, 2024 at 13:42 TylerH 21.1k79 gold badges79 silver badges114 bronze badges asked Jun 26, 2013 at 3:23 klinoreklinore 2,7494 gold badges20 silver badges21 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 4

The value held on variable z is calculated the moment you assign it to the variable:

var z=1+y;

If you want it to change, you have to update it manually:

<button onclick="z=++y+1">Increment</button>

Most puter languages behave like that, I believe.


In JavaScript and other languages you can use "getters" and "setters" to achieve what you want, but the code will bee more plex. Judge if you really think it's necessary:

<body>
    <script>
    var vals = {
        _y : 0,
        z : 0,
        set y(val) {
            this._y = val;
        },
        get y() {
            this.z = this._y + 1
            return this._y;
        } 
    }
    vals.y = 6;
    vals.z = 1 + vals.y;
    </script>
    <button onclick="vals.y++">Increment</button>
    <button onclick="alert(vals.y)">What is y?</button>
    <button onclick="alert(vals.z)">What is z?</button>
</body>

https://jsbin./udediy/1/edit


Another, simpler solution is to just use a function. That would work well for the example you gave:

<body>
    <script>
    var y=6;
    var z = function() {
        return 1+y;
    }
    </script>
    <button onclick="y++">Increment</button>
    <button onclick="alert(y)">What is y?</button>
    <button onclick="alert(z())">What is z?</button>
</body>

https://jsbin./ojorax/1/edit

y is evaluated when you set z. At that time y is 6 so z is 7. When you increase y then z is not re evaluated (as you've found out).

y=1;
z=++y;//increment y and assign the value to z
 // z will be 2;
z=y++;//set z to the value of y and then increment y
   // z is now 2 and y is 3

If you want one variable to be dependent on the value of another variable you can't just assgin new values to them. You have to use getters and setters functions:

var myObj={
  y:0,
  x:0,
  setY:function (value){
    this.y=value;
    this.x=value+1;
  },
  setX:function (value){
    this.x=value;
    this.y=value-1;
  }
}
myObj.setY(4);
console.log(myObj.x);//=5
myObj.y=2;//breaks setting x, you have to use setters
console.log(myObj.x);//=5

As you can see the line myObj.y=2 breaks setting z so you can't assign values to either myObj.y or myObj.z without breaking it.

To prevent this from happening you have to make x and y private. In JavaScript you can simulate private variables using closures.

A warning for the folling code: if you plan to create multiple instances of your object use constructor functions and have private variables using code conventions (like _privateVar) instead of real privateness since JS doesn't support it unless you're planning on not using prototype.

var myObj=(function(){
  var x=0;// x and y only exist in the funciton body
  var y=0;// you cannot access them in myObj.x or .y
  return{
    setX:function(value){
      //maybe check if value is a number here
      x=value;
      y=value-1;
    },
    setY:function(value){
      //maybe check if value is a number here
      y=value;
      x=value+1;
    },
    getX:function(){
      return x;
    },
    getY:function(){
      return y;
    }
  }
})();
myObj.setX(6);
console.log(myObj.getY());//logs 5
myObj.y=22;
console.log(myObj.getY());//still logs 5

Using bfavaretto's syntax with get and set you can assign new values but internally JavaScript will use the getters and setters functions. This does not work in older browsers like IE8 and under.

var myObj={
  _y:0,
  _x:0,
  set y(value){
    this._y=value;
    this._x=value+1;
  },
  get y(){
    return this._y;
  },
  set x(value){
    this._x=value;
    this._y=value-1;
  },
  get x(){
    return this._x
  }
}
myObj.x=4;
console.log(myObj.y);//=3

once you assign the value of z = 1 + y z references a different location and there is no further relation between z and y

One way to do it is to wrap the variable in an object, which is passed by reference rather than by value:

var obj = { y : 6 };
var obj_2 = obj;
alert(obj.y); //6
alert(obj_2.y); // 6
obj.y++;
alert(obj.y); // 7
alert(obj_2.y); // 7`

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论