我再次偶然发现了我不理解的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 =开始&
是因为变量已被复制(通过值传递)而不是在其上具有指针(通过引用传递)吗?哪种方法才是更新属性的正确方法?
答案 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.c
到obj.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