JavaScript中的true / false vs int(意外行为)

时间:2017-09-29 23:59:16

标签: javascript html function dom this

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

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

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而不是true / false,代码可以出于某种原因。

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指针还是什么?。

4 个答案:

答案 0 :(得分:4)

问题是,您的函数f在没有new的情况下被调用,因此this引用已window objectstatus property with its own meaning

如果您打印其类型,您可以看到:

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

 f()
&#13;
&#13;
&#13;

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

但如果你用不同的名字命名:

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

 f()
&#13;
&#13;
&#13;

它产生正确的类型。

因此,要使其工作,您只需要更改其名称。但是,您必须将if反转的else boolean逻辑可以转换为!(不是),这大大简化了代码:

&#13;
&#13;
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();
&#13;
&#13;
&#13;

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

您可以更多地改进解决方案:

&#13;
&#13;
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();
&#13;
&#13;
&#13;

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

答案 1 :(得分:0)

由于您是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

的示例

答案 2 :(得分:0)

其他人发表了一些不错的回复,但这是我的两分钱。

您可以在函数中初始化一个局部变量,该变量将初始化一个值,然后在单击该按钮时替换该值。在这里似乎没有必要使用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引用了文档窗口,这似乎是一个问题。

<强> Codepen:

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

答案 3 :(得分:-1)

&#13;
&#13;
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();
&#13;
&#13;
&#13;