如何在外部变量更改时更新对象属性

时间:2019-09-18 12:01:12

标签: javascript

我再次偶然发现了我不理解的Javascript行为。我需要在对象外部的变量更改后立即更新对象的属性。对象属性中引用了外部变量,因此我认为我要做的就是从外部更改变量并自动更改属性值。

下面是代码的简化版本:

var serverPath = "123/";

var GetCurrentProductionApiConfig = {
  URL: {
    GetStart: serverPath + 'GetCurrentProduction?returnValue=start&',
    GetEnd: serverPath + 'GetCurrentProduction?returnValue=end&',
    Get: serverPath + 'GetCurrentProduction?returnValue=start&'
  }
};

serverPath = "456/";

console.log(GetCurrentProductionApiConfig.URL.GetStart);

这将导致:

  

123 / GetCurrentProduction?returnValue =开始&

是因为变量已被复制(通过值传递)而不是在其上具有指针(通过引用传递)吗?哪种方法才是更新属性的正确方法?

1 个答案:

答案 0 :(得分:2)

Everything in JavaScript is pass by value,但是,碰巧对象的值就是它的引用。但是,这里重要的是,对于基元,引用的变量更改时将不会更改:

var a = "world";
var obj = {
  b: "hello" + a //evaluated once
}

a = "universe"; //does not modify obj.b which references a

console.log(obj.b); //helloworld

为了拥有动态求值的字符串,您需要调用一个函数或方法:

var a = "world";
var obj = {
  b: function() { 
    return "hello" + a //evaluated every time the function is executed
  }
}
console.log(obj.b()); //helloworld

a = "universe"; //will influence obj.b

console.log(obj.b()); //hellouniverse

但是,这看起来有点“肮脏”,因为它迫使调用者每次都知道要评估该属性。如果某些属性是纯字符串,而其他函数则还可能导致不一致,如果属性必须从一个属性更改为另一个属性,这会特别令人讨厌-您需要修改每个调用此代码的位置,例如obj.cobj.c()

相反,使用ES6 +,您可以define a getter来获得与之前相同的功能,但会隐藏函数调用,因此,每次读取属性时,您实际上都会评估代码以返回结果:

var a = "world";
var obj = {
  c: "plain property"
}

Object.defineProperty(obj, 'b', {
  get: function() {
    return "hello" + a //evaluated every time the property is read
  }
});

console.log(obj.b); //helloworld

a = "universe"; //will influence obj.b

console.log(obj.b); //hellouniverse
console.log(obj.c); //plain property