Javascript 变量x是真的吗?
在Javascript中,是否有一种好方法可以检查变量在整个会话中是否为真(或任何值)?我现在能想到的最好的方法是执行这样的定期检查,在另一个变量中记录真实性:Javascript 变量x是真的吗?,javascript,variables,Javascript,Variables,在Javascript中,是否有一种好方法可以检查变量在整个会话中是否为真(或任何值)?我现在能想到的最好的方法是执行这样的定期检查,在另一个变量中记录真实性: if (variable){ variablewasevertrue = true; } 然后,当我想知道原始变量是否为真时,我会检查新的变量是否为真是否为真或未定义。没有比if(variable was ever true)更优雅的了。{有吗?这看起来不像Javascript-y。不,语言中没有if(variable was e
if (variable){
variablewasevertrue = true;
}
然后,当我想知道原始变量
是否为真时,我会检查新的变量是否为真
是否为真
或未定义
。没有比if(variable was ever true)更优雅的了。{有吗?这看起来不像Javascript-y。不,语言中没有if(variable was ever true)功能。变量存储值,而不是历史
在赋值和检查时截取值是唯一的方法。如果变量确实是一个属性(例如,全局变量是全局对象的属性),则可以轻松地使用
所以要保存全局变量的历史记录,您可以
var hasEverBeenTruthy = false;
(function () {
var value;
Object.defineProperty(window, "myGlobal", {
"get": function () { return value; },
"set": function (newval) {
if (newval) { hasEverBeenTruthy = true; }
value = newval;
}
});
})();
这将在现代浏览器上运行,并且在许多旧浏览器上都有
\uuu defineSetter\uuuu
变体。否-变量上没有状态跟踪。它只是它的当前值。除此之外,它是您自己的自定义实现,使用类似属性的方法进行状态跟踪。否,除非您可以使用gETER
和setter
如下所示,它代表变量的设置,以便您可以检查是否一次性设置:
var value,
wasevertrue = false;
window.__defineSetter__('test', function(v) {
value = v;
wasevertrue = wasevertrue || (v === true);
});
window.__defineGetter__('test', function() {
return value;
});
现在,
更好的方法是将其放在闭包中,因为您现在可以将
value=true
设置为setter的变通方法。在设置“variable”的任何位置都可以使用另一个名为“wasevertrue=false”的变量紧接着检查变量是否为true。如果为true,则设置为wasevertrue=true。变量存储值,而不是内存位置的历史记录。如果要执行类似操作,我建议您使用某种类型的对象:
var x = {
value: false,
history: [],
set: function(val){
history.push(this.value);
this.value = val;
},
wasEver: function(val){
return this.history.indexOf(val) >= 0;
}
};
然后您可以像这样使用对象:
x.set(false);
x.value; //returns false
x.set(true);
x.value; //returns true
x.wasEver(true); // returns true
x.wasEver(false); //returns true
x.wasEver("hello"); //returns false
这为每个对象提供了它自己的历史记录(如中所示,它可以检查多个值,而不仅仅是一个值——就像其他答案中提到的getter/setter一样),并保证在任何范围内工作,因为所有功能都包含在定义的对象中。您不能使用单个标量变量跟踪历史,但可以使用数组。这并不理想,但它是一种替代方法:
function setVar(arr, value) {
arr.unshift(value);
return arr;
}
function getVar(arr) {
return arr[0];
}
function checkHist(arr, histValue) {
var ii;
for (ii = 0; ii < arr.length; ii++) {
if (arr[ii] === histValue) {
return true;
}
}
return false;
}
var myVar = [];
myVar = setVar(myVar, true);
myVar = setVar(myVar, false);
alert(checkHist(myVar, true)); // alerts "true"
函数setVar(arr,value){
arr.unshift(值);
返回arr;
}
函数getVar(arr){
返回arr[0];
}
函数检查历史(arr、历史值){
var ii;
对于(ii=0;ii
您试图解决的总体问题是什么?也许有更好的解决方法。您为什么需要这样做?很有可能,任何导致变量更改的因素都会为您提供一些实现目标的能力。它是对象内部的全局变量。在对象通过特定pro后,它将被取消cess只有一次,但它的值也决定了其他事情是否会重复发生。我想我只使用两个变量。似乎有点像暴力编码,但可能不是。迈克,你真的用斯蒂芬·科尔伯特发明的一个词编辑了我的帖子吗?@Artur,是的。if(变量)
无法确定变量
是否为真
,因为当变量
为1
、[]
和许多其他值时,该测试通过。若要检查该值,需要if(变量==真)
。您应该注意,defineSetter方法不是标准的,也不会像其他一些解决方案那样跨平台:我看到了所有设置的列表。有趣的想法是,这实际上是一个非常强大的变量设置瓶颈。请记住,这只适用于窗口名称空间中的变量。如果您想让它在对于一个函数,您需要将定义更改为位于该函数名称空间内(这对于匿名函数来说很难)@Mike Trpcic,我想我已经用“如果变量真的是一个属性(例如,全局变量是全局对象的属性)”明确了这一点@MikeSamuel可能想提及ES6代理。同意,非常好地使用arrayAm I是错误的,还是必须切换代码第一部分的第5行和第6行?@Artur:这取决于您想要什么。在当前代码中,值只有在更改后才会进入历史数组(即“当前值”)对象的当前值不在历史数组中)。如果要在历史数组中使用当前值,只需交换这两行即可。
function setVar(arr, value) {
arr.unshift(value);
return arr;
}
function getVar(arr) {
return arr[0];
}
function checkHist(arr, histValue) {
var ii;
for (ii = 0; ii < arr.length; ii++) {
if (arr[ii] === histValue) {
return true;
}
}
return false;
}
var myVar = [];
myVar = setVar(myVar, true);
myVar = setVar(myVar, false);
alert(checkHist(myVar, true)); // alerts "true"