gpt4 book ai didi

javascript - 闭包行为不一致的 javascript 对象中的 "this"

转载 作者:行者123 更新时间:2023-11-28 13:33:00 24 4
gpt4 key购买 nike

所以,这个问题可能在这个网站的某个地方得到了回答,但我找不到它,如果有的话。

我无法弄清楚为什么函数内的一个 this 引用似乎在我创建对象时得到了解析,而当我调用其中包含该引用的函数时,又似乎得到了解析。这是一些代码:

function MyObj (name) {
this.locked = false;
this.name = name;
this.elem = null;
this.func1 = function () {
if (this.locked) return;
/* code that changes this.name here */
this.elem.innerHTML = this.name;
};
this.func2 = function () {
this.locked = !this.locked;
if (this.locked) this.elem.className = "locked";
else this.elem.className = "unlocked";
};
}

var myObjGlobal = new MyObj("foo");

function callFunc1 () {
myObjGlobal.func1();
}

然后我有一个在文档加载时调用的函数:

function onLoad() {
var myElem = document.getElementById("myElem");
myObjGlobal.elem = myElem;
myElem.onclick = myObjGlobal.func2;
document.getElementById("myButton").onclick = callFunc1;
}

我已确保所有 html 元素都有正确的 ID。当我点击 myButton 时,我没有收到任何错误。但是,当我单击 myElem 时,我收到 Uncaught TypeError: Cannot set property 'className' of undefined

为什么在调用函数时设置第一个 this,而在创建对象时设置第二个 this? (或者看起来是这样?)

这是一个 working jsfiddle显示问题(使用给定的示例代码)。

提前致谢!

最佳答案

myElem.onclick = myObjGlobal.func2;

这并不符合您在 JavaScript 中的想法。它不会为您提供 func2 以及以任何方式“附加”到它的对象;它只是给你func2。当稍后调用它时,它会作为 myElem 的方法被调用,所以这就是 this 的意思。

这是 JS 中的一个巨大而可怕的疣。 :)

您可以将其包装在另一个函数中:

myElem.onclick = function() {
myObjGlobal.func2();
};

或者使用 .bind,它实际上可以完成相同的事情,并且现在几乎得到普遍支持:

myElem.onclick = myObjGlobal.func2.bind(myObjGlobal);

另请注意,分配给 onclick 有点粗鲁,因为您会破坏任何现有的点击处理程序。您可能需要addEventListener相反。

关于javascript - 闭包行为不一致的 javascript 对象中的 "this",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23464497/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com