Javascript 变量x是真的吗?

Javascript 变量x是真的吗?,javascript,variables,Javascript,Variables,在Javascript中,是否有一种好方法可以检查变量在整个会话中是否为真(或任何值)?我现在能想到的最好的方法是执行这样的定期检查,在另一个变量中记录真实性: if (variable){ variablewasevertrue = true; } 然后,当我想知道原始变量是否为真时,我会检查新的变量是否为真是否为真或未定义。没有比if(variable was ever true)更优雅的了。{有吗?这看起来不像Javascript-y。不,语言中没有if(variable was e

在Javascript中,是否有一种好方法可以检查变量在整个会话中是否为真(或任何值)?我现在能想到的最好的方法是执行这样的定期检查,在另一个变量中记录真实性:

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"