gpt4 book ai didi

关于关键字this的javascript问题

转载 作者:搜寻专家 更新时间:2023-11-01 05:14:58 24 4
gpt4 key购买 nike

示例代码:

<!DOCTYPE html>
<html>
<head>
<title>test</title>

<script language="javascript" type="text/javascript">

function init() {
var nodeList = document.getElementsByTagName("a");
var nodeArr = [];
for( var i = 0; i < nodeList.length; i++) // Copy NodeList to Array
nodeArr.push(nodeList[i]);
for( var i = 0; i < nodeArr.length; i++) // Loop over array
if( nodeArr[i].className == "clickLink" )
nodeArr[i].onclick = clickLink2; // Attach event function
}

window.onload = init; //Attach event function

function clickLink2() {
console.log("this: " + this); //Prints window URL in href
console.dir( this ); //show attributes of anchor
console.log( this.name ); // Prints name attribute
}


function clickLink( elem ) {
console.log( "this: " + this ); //Prints [object Window]
console.dir( this ); // Shows attributes, etc. al of [object Window]
console.log( "name: " + elem.name );
}
</script>

</head>

<body>

<!-- inline -->
<a href="#" name="blah1" onclick="clickLink(this); return false;">Test 1</a>
<a href="#" name="blah2" onclick="clickLink(this); return false;">Test 2</a>
<a href="#" name="blah3" onclick="clickLink(this); return false;">Test 3</a>
<a href="#" name="blah4" onclick="clickLink(this); return false;">Test 4</a>


<hr/>
<!-- not inline -->
<a href="#" name="blah5" class="clickLink">Test 5</a>
<a href="#?t" name="blah6" class="clickLink">Test 6</a>
<a href="#" name="blah7" class="clickLink">Test 7</a>
<a href="#" name="blah8" class="clickLink">Test 8</a>

</body>

</html>

我在 firefox 中进行了测试,使用 firebug 查看控制台输出。

现在我想知道的是:

  1. 为什么在 clickLinkthis 引用窗口对象?
  2. 为什么 clickLink2 中的 this 会作为链接 href 的值打印到控制台?
  3. 有没有更好的方法将this 传递给这样一个不显眼的附件?您如何确定this 指的是什么?

好的,所以我从这里的答案中提取了一些片段,发现this 在某些浏览器中有点古怪。此外,将函数分配给 onclick 与附加不同(但不幸的是,并非所有 IE 版本都支持查看 addEventListenerattachEvent)。出于某种原因,较旧的 IE 还使事件触发函数体内的 this 仍然引用窗口对象而不是调用者。所以我使用了 event.srcElement。下面是一些新的示例代码:

<!DOCTYPE html>
<html>
<head>
<title>test</title>

<script language="javascript" type="text/javascript">

function init() {
var nodeList = document.getElementsByTagName("a");
var nodeArr = [];
for( var i = 0; i < nodeList.length; i++) // Copy NodeList to Array
nodeArr.push(nodeList[i]);
for( var i = 0; i < nodeArr.length; i++) // Loop over array
if( nodeArr[i].className == "clickLink" ) {

var a = nodeArr[i];

if (a.addEventListener) { //IE9, other browsers
a.addEventListener('click', clickLink2); // Attach event function
} else if (a.attachEvent) { //IE6,7,8, etc.
a.attachEvent('onclick', clickLink2 ); // Legacy IE Attach event function
}

a.onclick = function() { return false }; // override default onclick behavior for these anchors so URL is not followed
}
}

window.onload = init; //Attach event function

function clickLink2() {

if( typeof(event) != 'undefined' ) {
elem = event.srcElement; //IE < 8 keeps this as window object
} else {
elem = this;
}

alert( elem.name );
}


function clickLink( elem ) {
alert( elem.name );
}
</script>

</head>

<body>

<!-- inline -->
<a href="#" name="blah1" onclick="clickLink(this); return false;">Test 1</a>
<a href="#" name="blah2" onclick="clickLink(this); return false;">Test 2</a>
<a href="#" name="blah3" onclick="clickLink(this); return false;">Test 3</a>
<a href="#" name="blah4" onclick="clickLink(this); return false;">Test 4</a>


<hr/>
<!-- not inline -->
<a href="#" name="blah5" class="clickLink">Test 5</a>
<a href="#?t" name="blah6" class="clickLink">Test 6</a>
<a href="#" name="blah7" class="clickLink">Test 7</a>
<a href="#" name="blah8" class="clickLink">Test 8</a>

</body>

</html>

最佳答案

1) 为什么在 clickLink 中 this 指的是 window 对象?简单地说:clickLink 不是事件处理程序,通过将属性 onclick 添加到元素,您可以使用 native onclick 方法作为调用函数的处理程序。这个函数是在主作用域中声明的,因此 this 指向窗口对象。要清楚:行为类似于:

<p onclick='function(){window.clickLink(this);}'>

使实际的事件处理程序成为匿名函数,而不是 clickLink。这就是为什么 this 将指向窗口:匿名函数也在全局范围内声明,因此 clickLink 的调用者是窗口。

2) 为什么 clickLink2 中的 this 作为链接 href 的值打印到控制台?

想想这句话“Javascript allows you to manipulate the DOM, the DOM-tree, all events and behaviors”。在您的 init 函数中,元素的 onclick 行为被操纵。 onclick 的默认方法被否决,并被 clickLink2 方法替换 nodeArr[i].onclick = clickLink2;

这样看:您所有的元素都有一个原型(prototype) onclick 方法,它接受一个参数。在第一种情况下,此参数是一个字符串,其计算结果为对 clickLink 函数的调用。然而,在第二种情况下,具有特定类的实例有它们自己的 onclick 方法,否决了原型(prototype)的 onclick。

我确实希望这能为您解决一些问题。一旦您掌握了事件、处理程序、方法、原型(prototype)等背后的基本理念并克服了 JS 的怪癖,这就很容易了。

3) 是否有更好的方法将其传递给像这样的不显眼的附件?你怎么能确定这是指什么?

好吧,我在上面回答了这个问题,不是吗?但是无论如何:如果您自己定义一个元素或对象的方法,一般来说,this 将指向所有者对象/元素。如果您依赖 html 和默认行为,JS 将主要关注它自己的业务,这将指向窗口。

我不知道这是否是一个选项,但也许你可以尝试这样的事情:

<a onclick='clickLink'>

理论上,这应该和您的初始化函数做同样的事情

编辑:上面的工作替代方案:

<p onclick='clickLink.call(this)'>

Call 将 p 元素定义为 clickLink 的调用者,使 this 指向调用该函数的元素。

关于关于关键字this的javascript问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9721116/

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