2017-09-29 24 views
2

我是一种新的JavaScript,今天我正在研究一个基本上切换值并将其显示为alert的函数,但我偶然发现了一个与JavaScript有关的奇怪行为到真/假和0/1。true/false vs int in JavaScript(意外的行为)

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

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指针我使用的功能什么的?

+1

你为什么不使用===代替==? – zhuravlyov

+0

与其他语言相比,JavaScript有一个更复杂的平等概念,但幸运的是,它是一个很好理解的概念;看看[这篇文章](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness)的介绍 – Hamms

回答

4

的问题是,你的函数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可以变成一个!(没有),从而简化代码很多:

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();

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

+0

值得注意的是,您仍然将myStatus添加到窗口对象中,除非您故意这样做,否则它不一定是个好主意,并且可以阐明为什么您希望它在那里。 – Ben

+0

侧面说明'let'和'var'之间有什么区别。在最后一个片段中,你为什么使用'let'作为myStatus而'var'作为btn? –

+0

@ rov.er'let'保证你的范围,而'var'不会。此外,它在封闭和其他小细节方面效果更好。检查文档[这里](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) – Isac

-1

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();

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

+0

不一定“永远” – DragonKnight

+0

@DragonKnight你能否详细说明一下? –

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