【问题标题】:true/false vs int in JavaScript (unexpected behavior)JavaScript 中的 true/false vs int(意外行为)
【发布时间】:2018-03-11 21:59:14
【问题描述】:

我是 javascript 的新手,今天我正在研究一个基本上切换值并将其显示为警报的函数,但我偶然发现了 JavaScript 与真/假和 0/1 相关的奇怪行为。

以下代码,当用户点击切换锚链接时,它似乎没有切换值,并且警报总是给出“真”(我认为应该发生):

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML;
function f() {
    this.status = true;
    var btn = document.getElementById("toggle")
    btn.addEventListener("click", () => {
        if (this.status == true) {
             alert(this.status)
            this.status = false;
        } else {
            alert(this.status)
            this.status = true;
        }

     }, false)
}

f()

但如果我使用 0 和 1 而不是真/假,代码会出于某种原因工作。

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' +document.body.innerHTML;

function f() {
    this.status = 1;
    var btn = document.getElementById("toggle")
    btn.addEventListener("click",()=>{
    if(this.status==1){
         alert(this.status)
         this.status = 0;
    }else{
        alert(this.status)
        this.status = 1;
      }

     },false)
 }

 f()

我不知道这里发生了什么,这是因为我在函数中使用了this 指针还是什么?

【问题讨论】:

  • 为什么不使用 === 而不是 == ?
  • JavaScript 有一个比你可能熟悉的其他语言更复杂的相等概念,但幸运的是它是一个很好理解的概念;查看this article了解简介

标签: javascript html function dom this


【解决方案1】:

问题是您的函数f 是在没有new 的情况下调用的,所以this 指的是window object,它已经有status property with its own meaning

如果你打印它的类型,你可以看到这个:

function f() {
    this.status = true;
    console.log(typeof this.status);
 }

 f()

注意结果是string,而不是预期的boolean

但如果你换个名字:

function f() {
    this.myprop = true;
    console.log(typeof this.myprop);
 }

 f()

它产生正确的类型。

因此,要使其正常工作,您只需更改其名称即可。但是ifelse逻辑你必须反转boolean可以变成!(not),这大大简化了代码:

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' + document.body.innerHTML;

function f() {
  this.myStatus = true;
  var btn = document.getElementById("toggle");
  
  btn.addEventListener("click", () => {
    this.myStatus = !this.myStatus; //here the value is inverted only with the ! (not)
    console.log(this.myStatus);
  }, false);
}

f();

但不鼓励使用window 对象,原因与您遇到的原因很相似,并且myStatus 属性仍存储在那里。

您可以进一步改进解决方案:

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' + document.body.innerHTML;

function f() {
  let myStatus = true;
  var btn = document.getElementById("toggle");
  
  btn.addEventListener("click", () => {
    myStatus = !myStatus; //here the value is inverted only with the ! (not)
    console.log(myStatus);
  }, false);
}

f();

另外,不要忘记用分号结束语句,我注意到你几乎没有。

【讨论】:

  • 值得注意的是,您仍在将 myStatus 添加到窗口对象,这不一定是一个好主意,除非您是故意这样做的,并且可以清楚地说明您想要它的原因。
  • 请注意 letvar 之间的区别。在上一个 sn-p 中,为什么你使用 let 代表 myStatus 和 var 代表 btn ?
  • @rov.er let 保证您的范围,而 var 不保证。此外,它在闭包和其他小细节方面效果更好。检查文档here
【解决方案2】:

由于您是 JavaScript 新手,您可能还没有听说过,但您应该 know when to use === instead of ==(提示:总是)。

简而言之,因为JavaScript is weakly/un-typed 很难知道您实际上是在比较两个相同的事物(数字)还是两个不同的事物(数字和对象):

new Number(10) == 10 // true
new Number(10) === 10 // false

因为:

typeof Number(10) // returns number
typeof 10 // returns number
typeof new Number(10) // returns object

^ 以上示例来自https://coderwall.com/p/bqurhg/why-always-use-in-javascript

【讨论】:

  • @DragonKnight 你能详细说明一下吗?
【解决方案3】:

其他人发表了一些很好的回应,但这是我的两分钱。

您可以在函数中初始化一个局部变量,该变量将初始化一个值,然后在单击按钮时交替使用该值。您在这里似乎不需要使用this 表示法。

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML;
function f() {
    var status = true;
    var btn = document.getElementById("toggle")
    btn.addEventListener("click", () => {
        if (status === true) {
            alert(status)
            status = false;
        } else {
            alert(status)
            status = true;
        }

     }, false);
}

f();

使用它时,请始终了解您所指的内容。正如 Isac 指出的那样,您的 this 指的是文档窗口,这似乎是一个问题。

代码笔:

https://codepen.io/foozie3moons/pen/gGRBxZ?editors=0010

【讨论】:

    【解决方案4】:

    document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML;
    function f() {
        let status = true;
        let btn = document.getElementById("toggle");
        btn.addEventListener("click", () => {
            if (status === true) {
                alert(status);
                status = false;
            } else {
                alert(status);
                status = true;
            }
    
        }, false)
    }
    
    f();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-24
      • 2020-03-08
      • 2020-12-15
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      相关资源
      最近更新 更多