我是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
指针还是什么?。
答案 0 :(得分:4)
问题是,您的函数f
在没有new
的情况下被调用,因此this
引用已window
object的status
property with its own meaning。
如果您打印其类型,您可以看到:
function f() {
this.status = true;
console.log(typeof this.status);
}
f()
&#13;
请注意结果是string
而不是预期的boolean
。
但如果你用不同的名字命名:
function f() {
this.myprop = true;
console.log(typeof this.myprop);
}
f()
&#13;
它产生正确的类型。
因此,要使其工作,您只需要更改其名称。但是,您必须将if
反转的else
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();
&#13;
但不鼓励使用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();
&#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:强>
答案 3 :(得分:-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();
&#13;