&引用;这";在闭包行为不一致的javascript对象中

&引用;这";在闭包行为不一致的javascript对象中,javascript,html,this,scope,Javascript,Html,This,Scope,所以,这个问题可能在这个网站的某个地方得到了回答,但我找不到,如果是的话 我很难弄清楚为什么我的这个函数中的一个引用在我创建对象时似乎得到了解决,还有一个是在我调用包含引用的函数时得到了解决。下面是一些代码: function MyObj (name) { this.locked = false; this.name = name; this.elem = null; this.func1 = function () { if (this.lock

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

我很难弄清楚为什么我的
这个
函数中的一个引用在我创建对象时似乎得到了解决,还有一个是在我调用包含引用的函数时得到了解决。下面是一些代码:

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。当我点击我的按钮时,我没有收到任何错误。但是,当我单击MyLem时,我得到了未捕获的TypeError:无法设置未定义的属性“className”

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

下面是一个示例,显示了问题(使用给定的示例代码)

提前谢谢

myElem.onclick = myObjGlobal.func2;
这将完全丢失
myObjGlobal
myObjGlobal.func2
只是一个函数,它的
this
与任何东西都没有关联。在JavaScript中,函数的
this
是在调用时确定的,而不是在定义时确定的。这是JavaScript的一个奇妙而有用的特性,它比Python更直观。调用
myElem.onclick
时,将使用绑定到
myElem
this
调用它

是一个实用程序,用于执行您正在使用
callFunc1
执行的操作,顺便说一下:

myElem.onclick = myObjGlobal.func2.bind(myObjGlobal);
这将完全丢失
myObjGlobal
myObjGlobal.func2
只是一个函数,它的
this
与任何东西都没有关联。在JavaScript中,函数的
this
是在调用时确定的,而不是在定义时确定的。这是JavaScript的一个奇妙而有用的特性,它比Python更直观。调用
myElem.onclick
时,将使用绑定到
myElem
this
调用它

是一个实用程序,用于执行您正在使用
callFunc1
执行的操作,顺便说一下:

myElem.onclick = myObjGlobal.func2.bind(myObjGlobal);
这和你想的不一样。它不会以任何方式为您提供带有对象“附加”的
func2
;它只提供
func2
。当以后调用它时,它会作为
myElem
的一个方法调用,所以这就是
this

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

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

myElem.onclick = function() {
    myObjGlobal.func2();
};
或者使用
.bind
,它可以有效地完成同样的事情,并且现在几乎普遍支持:

myElem.onclick = myObjGlobal.func2.bind(myObjGlobal);
还要注意的是,分配给
onclick
有点粗鲁,因为这样会破坏任何现有的click处理程序。你可能会想要

这和你想的不一样。它不会以任何方式为您提供带有对象“附加”的
func2
;它只提供
func2
。当以后调用它时,它会作为
myElem
的一个方法调用,所以这就是
this

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

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

myElem.onclick = function() {
    myObjGlobal.func2();
};
或者使用
.bind
,它可以有效地完成同样的事情,并且现在几乎普遍支持:

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

还要注意的是,分配给
onclick
有点粗鲁,因为这样会破坏任何现有的click处理程序。您可能需要。

谢谢您,伊维!这解决了我的问题。在addEventListener上也有很好的调用。如果允许的话,我会在8分钟内接受你的回答。谢谢你,伊维!这解决了我的问题。在addEventListener上也有很好的调用。如果允许的话,我会在8分钟内接受你的回答。谢谢minitech!我认为这比Python的做事方式要混乱得多,但作为一个长期使用Python的用户,我有偏见。@GailTerman:我只是在中编辑了这一部分来反驳Eevee的做法。=)谢谢minitech!我认为这比Python的做事方式要混乱得多,但作为一个长期使用Python的用户,我有偏见。@GailTerman:我只是在中编辑了这一部分来反驳Eevee的做法。=)