Javascript onClick函数“;这";返回窗口对象
我的JavaScript应用程序遇到了一个令人头疼的问题 如果我写这样一个元素:Javascript onClick函数“;这";返回窗口对象,javascript,function,onclick,window,this,Javascript,Function,Onclick,Window,This,我的JavaScript应用程序遇到了一个令人头疼的问题 如果我写这样一个元素: <li onClick="alert(this.tagName)"></li> 我得到“未定义” 我不知道“这”在附加功能方面应该如何工作。但是,我很困惑,因为“this”并没有拾取元素,而是默认为“window”。我不明白为什么会发生这种情况 有人对此有解释吗?这是因为您没有在JavaScript函数调用中传递对此的引用。JavaScript函数中的这一点与onClick示例中的对象不同
<li onClick="alert(this.tagName)"></li>
我得到“未定义”
我不知道“这”在附加功能方面应该如何工作。但是,我很困惑,因为“this”并没有拾取元素,而是默认为“window”。我不明白为什么会发生这种情况
有人对此有解释吗?这是因为您没有在JavaScript函数调用中传递对此的引用。JavaScript函数中的这一点与onClick示例中的对象不同。请尝试以下方法:
<li onClick="foo(this)"></li>
function foo(item){ alert(item.tagName); }
函数foo(item){alert(item.tagName);}
如果您不熟悉JavaScript,请不要使用this
或new
关键字,因为您可能会出错,或者您的代码会不必要地低效且更复杂。不过,您正试图实现以下目标:
<li onclick="foo(this)">some text</li>
一些文本
在该示例中,该列表项的click事件触发一个名为foo的函数。this
关键字作为变量传入。此
关键字仅指调用相关函数的实体,如果找不到该实体,则将指浏览器的窗口
对象。在本例中,调用函数的实体是DOM中的列表项节点
我仍然建议不要使用这个
关键字,以避免这种混乱
编辑:另外,不要使用标记名属性,因为这不是标准属性。在内联侦听器中使用nodeName
属性。:
> <li onClick="alert(this.tagName)"></li>
当你把一个函数放在主体中时,你基本上得到了:
function anon() {
foo();
}
这里,anon中的this
将是元素,但是由于调用foo
时没有设置this
,因此它将是未定义的。在非严格模式下,此
将默认为全局对象(浏览器中的窗口
)。在严格模式下,此内部foo
将未定义
一种解决方案是将元素引用传递给函数:
<li onclick="foo(this)" ... >
function foo(callingElement) {
...
}
甚至:
<li onclick="foo.call(this)" ... >
function foo() {
var callingElement = this;
}
函数foo(){
var callingElement=this;
}
另一个选项是使用or,这样您就不必将此作为参数传递。这是一种内置机制,用于在函数中设置该的值。尽管我要指出,将事件处理程序直接添加到html有点过时。您可能希望签出事件委派的JS框架(、等)
小提琴:
HTML
<div onClick='alert(this.tagName);'>test</div>
<div onClick='foo.call(this);'>test2</div>
正如其他答案已经提到的那样,this
的值将取决于包含它的函数的调用方式。但由于您的示例是关于事件处理程序的,我想强调cjc343在评论中所说的内容:
如果删除内联事件处理程序,您可能会发现这更明智
事实上,这很简单。考虑到这个HTML:
<ul id="list">
<li id="item1">item 1</li>
<li id="item2">item 2</li>
<li id="item3">item 3</li>
</ul>
这将适用于所有符合W3C事件模型的浏览器,包括IE9。对于较旧的IE,您必须使用attachEvent
而不是addEventListener
,并在事件名称前面加上“on”
。更多详细信息。请先尝试搜索。有许多重复的此
被“动态绑定”到函数的接收者或全局对象(例如窗口
)。提示:将foo()
包装到匿名函数中,而不是直接调用foo()
。Hint2:这是什么意思,与使用它的位置相关。如果删除内联事件处理程序,您可能会发现它更合理。此
与作用域无关。此
完全由调用函数的方式设置(忽略)。调用上下文(即建立作用域的全局或函数上下文)是无关的。如果调用未设置此
,则无论函数在何处调用,它都将默认为非严格模式下的全局对象,此
可以在从任何上下文调用时设置为任何对象(即,它与作用域无关)。@RobG Ah,我明白了。。。感谢您的澄清和更正!我已经编辑了我的答案。要添加可移植性,您也可以这样使用:被调用函数将继承调用元素作为“this”。元素。标记名
由DOM级别2提供,就像节点.节点名
一样。您关于避免使用这个
和新的
的建议很麻烦-如果您学会了使用它们,它们就不会让人困惑。@Dennis我不同意。我从未见过使用这个比不使用该关键字的类似逻辑更清晰或简单。因此,我看到了许多来自其他语言的人试图用this
创建类结构,以使JavaScript屈从于他们以前的经验,这是不合理的这个
也是JavaScript的代名词,代名词不符合编程的利益。我非常乐意接受反对票,因为我将继续坚持我的观点。
<li onclick="foo.call(this)" ... >
function foo() {
var callingElement = this;
}
<div onClick='alert(this.tagName);'>test</div>
<div onClick='foo.call(this);'>test2</div>
function foo(){ alert(this.tagName); }
<ul id="list">
<li id="item1">item 1</li>
<li id="item2">item 2</li>
<li id="item3">item 3</li>
</ul>
var list = document.getElementById('list');
list.addEventListener('click', function(evt){
console.log("this is the element the event is bound to: " + this.id);
console.log("the event target is the clicked element: " + evt.target.id);
});