变量x是真的吗?

Art*_*pek 4 javascript variables

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

if (variable){
  variablewasevertrue = true;
}
Run Code Online (Sandbox Code Playgroud)

然后,当我想知道,如果原来variable是曾经真实的,我检查,如果新variablewasevertruetrueundefined.没有比这更优雅的了if (variable was ever true){吗?这似乎不是Javascript-y.

Mik*_*uel 8

没有if (variable was ever true)语言设施.变量存储值,而不是历史.

在分配和检查值时截取值是唯一的方法.如果变量实际上是属性(例如,全局变量是全局对象的属性),则可以使用setter轻松拦截更改.

因此,要有一个历史保持全局变量,你可以做

var hasEverBeenTruthy = false;
(function () {
  var value;
  Object.defineProperty(window, "myGlobal", {
    "get": function () { return value; },
    "set": function (newval) {
      if (newval) { hasEverBeenTruthy = true; }
      value = newval;
    }
  });
})();
Run Code Online (Sandbox Code Playgroud)

这适用于现代浏览器,__defineSetter__许多旧版浏览器都有变种.


Mik*_*cic 7

变量存储值,而不是内存位置的历史记录.如果你想做这样的事情,我建议你使用某种对象:

var x = {
    value: false,
    history: [],
    set: function(val){
        history.push(this.value);
        this.value = val;
    },
    wasEver: function(val){
        return this.history.indexOf(val) >= 0;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后你可以使用这样的对象:

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
Run Code Online (Sandbox Code Playgroud)

这为每个对象提供了自己的历史记录(例如,它可以检查多个值,而不仅仅是一个 - 与其他答案中提到的getter/setter内容一样),并且保证可以在任何范围内工作,因为所有功能都包含在定义的对象.


pim*_*vdb 5

没有,但你可以使用一个gettersetter这样的,它代表一个变量的设定,让您可以检查它是否是设置在同一时间:

var value,
    wasevertrue = false;

window.__defineSetter__('test', function(v) {
    value = v;
    wasevertrue = wasevertrue || (v === true);
});

window.__defineGetter__('test', function() {
    return value;
});
Run Code Online (Sandbox Code Playgroud)

现在,

test = false; // wasevertrue === false
test = true;  // wasevertrue === true
test = false; // wasevertrue === true
Run Code Online (Sandbox Code Playgroud)

更好的是将其置于关闭状态,因为您现在可以将其设置value = true为setter的变通方法.

  • 您应该注意,defineSetter方法不是标准的,并且不会像其他解决方案那样跨平台:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineSetter (3认同)