Javascript onClick 函数“this”返回窗口对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12485759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 10:30:26  来源:igfitidea点击:

onClick Function "this" Returns Window Object

javascriptfunctiononclickwindowthis

提问by Pori

I've come across a head scratching issue with my JavaScript application.

我的 JavaScript 应用程序遇到了一个令人头疼的问题。

If I write an element like this:

如果我写一个这样的元素:

<li onClick="alert(this.tagName)"></li>

I get "LI."

我得到“李”。

However if I do this:

但是,如果我这样做:

<li onClick="foo()"></li>

Where "foo()" is:

其中“foo()”是:

function foo(){ alert(this.tagName); }

I get "undefined."

我得到“未定义”。

I am away how "this" is supposed to work in regards to attached functions. But, I am baffled because "this" is not picking up the element, but apparently defaulting to "window." I can't figure out why this is happening.

我不知道“这个”在附加功能方面应该如何工作。但是,我很困惑,因为“this”没有选择元素,但显然默认为“window”。我不明白为什么会这样。

Does anyone have an explanation?

有人有解释吗?

回答by p_strand

That's because you aren't passing a reference to thisin the JavaScript function call. thisin the JavaScript function doesn't refer to the same object as in the onClickexample. Try this instead:

那是因为您没有在 JavaScript 函数调用中传递对this的引用。JavaScript 函数中的this引用的对象与onClick示例中的对象不同。试试这个:

 <li onClick="foo(this)"></li>

 function foo(item){ alert(item.tagName); }

回答by RobG

In an inline listener:

在内联侦听器中:

> <li onClick="alert(this.tagName)"></li>

The onclick attribute value is effectively wrapped in a function and called with the element set to this, e.g.

onclick 属性值有效地包装在一个函数中,并使用设置为 this 的元素调用,例如

function anon() {
  /* attribute value */
}

anon.call(element);

When you put a function in the body, you are essentially getting:

当你在 body 中放置一个函数时,你基本上得到:

function anon() {
  foo();
}

Here, thiswithin anonwill be the element, but since foois called without setting this, it will be undefined. In non-strict mode, thiswill default to the global object (windowin a browser). In strict mode, thisinside foowill be undefined.

这里,thisinsideanon将是元素,但由于foo在没有设置的情况下被调用this,它将是未定义的。在非严格模式下,this将默认为全局对象(window在浏览器中)。在严格模式下,thisinsidefoo将是未定义的。

One solution is to pass an element reference to the function:

一种解决方案是将元素引用传递给函数:

<li onclick="foo(this)" ... >

then in the function:

然后在函数中:

function foo(callingElement) {
  ...
}

or even:

甚至:

<li onclick="foo.call(this)" ... >

function foo() {
  var callingElement = this;
}

回答by bfavaretto

As other answers already mention, the value of thiswill depend on how the function that contains it is called. But since your example is about event handlers, I'd like to highlight what cjc343 said on the comments:

正如其他答案已经提到的那样,的值this将取决于包含它的函数的调用方式。但是由于您的示例是关于事件处理程序的,我想强调 cjc343 在评论中所说的内容:

You may find it to be more sensible if you remove the inline event handlers.

如果您删除内联事件处理程序,您可能会发现它更明智。

That's pretty simple, actually. Considering this HTML:

这其实很简单。考虑到这个 HTML:

<ul id="list">
    <li id="item1">item 1</li>
    <li id="item2">item 2</li>
    <li id="item3">item 3</li>
</ul>

The following JavaScript will account for both removing inline handlers, and using delegation:

以下 JavaScript 将考虑删除内联处理程序和使用委托:

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

http://jsfiddle.net/J3Gje/

http://jsfiddle.net/J3Gje/

That will work on all browsers compliant to the W3C event model, including IE9. For older IE, you have to use attachEventinstead of addEventListener, and prepend the event names with "on". More details here.

这将适用于所有符合 W3C 事件模型的浏览器,包括 IE9。对于较旧的 IE,您必须使用attachEvent代替addEventListener,并在事件名称前加上"on". 更多细节在这里

回答by Brandon Boone

Another option, so you don't have to pass thisas a param, is to use callor apply. It's a built in mechanism to set the value of thiswithin a function. Though I would point out, adding your event handlers directly to your html is a bit antiquated. You may want to check out a JS framework for event delegation (jQuery, Prototype, Dojo, YUI, etc.).

另一种选择是使用callapply,因此您不必将作为参数传递。它是一种在函数中设置this值的内置机制。尽管我会指出,将事件处理程序直接添加到 html 有点过时了。您可能想查看用于事件委托的 JS 框架(jQueryPrototypeDojoYUI等)。

fiddle: http://jsfiddle.net/bboone/Q2CkV/2/

小提琴:http: //jsfiddle.net/bboone/Q2CkV/2/

HTML

HTML

<div onClick='alert(this.tagName);'>test</div>
<div onClick='foo.call(this);'>test2</div>?

JS

JS

function foo(){ alert(this.tagName); }

回答by austincheney

If you are new to JavaScript do not use the thisor newkeyword, because either you will get it wrong or your code will be unnecessarily inefficient and more complex. What you are trying to accomplish, though is the following:

如果您是 JavaScript 新手,请不要使用thisornew关键字,否则您会弄错,或者您的代码会不必要地低效且更加复杂。您正在尝试完成的任务如下:

<li onclick="foo(this)">some text</li>

In that example the click event of that list item fires a function named foo. The thiskeyword is passed in as a variable. The thiskeyword merely refers to the entity that called the function in question and if it cannot find that entity it will refer to the windowobject of the browser. In this case the entity that called the function is the list item node from the DOM.

在该示例中,该列表项的点击事件会触发一个名为 foo 的函数。所述this关键字被传递在作为变量。该this关键字仅仅指的是质疑有关的功能实体,如果它不能找到该实体将参照window浏览器的对象。在这种情况下,调用该函数的实体是来自 DOM 的列表项节点。

I still suggest never using thiskeyword in order to avoid this kind of confusion moving forward.

我仍然建议永远不要使用this关键字以避免这种混淆。

EDIT: Also, do not use a tagName property as this is not standard. Instead use the nodeNameproperty.

编辑:另外,不要使用 tagName 属性,因为这不是标准的。而是使用该nodeName属性。