您好我想知道是否可以使变量的行为如下:
var someFlag = true;
var someWidth = (()=>(someFlag) ? 16 : 12)();
console.log(someWidth) // 16
someFlag = false;
console.log(someWidth) // would be nice if it was 12
// right now it still prints 16
这样的事情可能吗?另外我知道someWidth可能是一个函数,我的想法是我有很多代码需要重构,所以我不想做someWidth();
答案 0 :(得分:4)
描述对象属性的好方法是here
var someFlag = true;
Object.defineProperty(window, 'someWidth', {
get:()=>someFlag ? 16 : 12
})
console.log(someWidth) // 16
someFlag = false;
console.log(someWidth) // 12

我不认为有这样的全局变量是个好主意。你可以尝试创建自己的对象吗?
答案 1 :(得分:1)
简短回答:是的,但不推荐。
如果名称不属于局部变量,则查找该名称作为全局对象的属性名称 - 在浏览器上为window
。可以在defineProperty
对象上使用window
来定义具有getter函数的属性。
Object.defineProperty(window, 'test', {
get: function () { return 3; },
});
var x = test; // x = 3
然而,绝对不建议这样做,因为只有一个全局上下文。如果多个单独的JS模块定义相同的全局变量,定义将发生冲突,您将遇到崩溃或一些奇怪的行为。
您不能推荐的另一件事是使用with
块,如下所示:
var o = {};
Object.defineProperty(o, 'test', {
get: function () { return 3; },
});
with (o) {
var x = test; // x = 3
}
with
关键字将一个对象作为参数。首先查找块内的名称作为该对象的属性,然后作为局部变量,然后作为全局对象的属性。也不建议这样做,因为它要求首先查找所有名称作为对象的属性,这会降低代码的速度。
with (o) {
var test = 4;
var x = test; // x = 3
}
此外,Javascript具有词法作用域,而不是动态作用域,因此您无法将顶级入口点包装在with
块中,整个程序必须写入{{{ 1}}阻止。
with
答案 2 :(得分:1)
我不确定这是否是一个解决方案取决于您正在查看的重构类型,但是如何使用修改过的getter / setter创建自己的对象?
var VariableWidth = {
flag: true,
get value() {
return this.flag ? 16 : 12;
},
set setFlag(p_bool) {
this.flag = p_bool;
}
}
console.log(VariableWidth.value) // 16
VariableWidth.setFlag = false;
console.log(VariableWidth.value) // would be nice if it was 12
// right now it still prints 16