element.onclick = fun与element onclick="fun()"的区别

原本标题是:element.onclick = fun与<element onclick="fun()">的区别,但是提示含有非法字符。

问题背景:

在看this指向的时候看到了这个,有的时候通过给DOM元素绑定监听事件,来触发某些事件处理函数(如点击当前元素时修改该元素样式等),如果绑定的监听函数里面用到了this,上面两种方式可能会有不同的效果。

试验代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>区别onclick不同绑定方式</title>
</head>
<body>
<div id="div1" style="width: 80px;height: 80px" >DIV1,点击触发更改颜色</div>
<div id="div2" style="width: 80px;height: 80px" onclick="changeBackground2()">DIV2,点击触发更改颜色</div>
<script>
  //this指向当前元素,本质是调用对象里面的方法
  div1.onclick = changeBackground1;
  function changeBackground1(){
    console.log(this);
    this.style.color = '#cc0000';
  }

  //this指向window对象,本质是调用了嵌套函数,先调用onclick(),再调用changeBackground()
  //嵌套函数中的this要么指向window(非严格模式)要么undefined(严格模式)
  function changeBackground2() {
    console.log(this);
    this.style.color = '#cc0000';  //TypeError:color undefined
  }
</script>
</body>
</html>

试验结果:

可以很明显的看到,第一种方式达到了想要的效果,第二种方式直接报错了。通过控制台打印的内容和报的错能够分析出基本原因,this指向不同,第一个指向了div元素(div1),颜色修改成功,第二个指向了window对象,找不到color属性报错。为什么this的指向会不一样?

原因分析:

1.copying

element.onclick = doSomething;

这个实际上是把doSomthing这个函数复制一份给了element的onclick属性,因此触发点击事件时,this指向的是运行时调用它的对象element。原解释:The function is copied in its entirety to the onclick property (which now becomes a method). So if the event handler is executed this refers to the HTML element and its color is changed.

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

2.referring

<element onclick="doSomething()">

这种方式只是让onclick属性指向了函数doSomething,并没有把doSomething函数的内部实现也包含进来,因此当触发点击事件时,只是找到onclick属性,然后告诉你去找doSomething吧,我这没具体实现,找到doSomething后,这时候里面的this已经指向window了,其实是在window下调用的doSomething函数。原解释:

you do not copy the function! Instead, you refer to it, and the difference is crucial. The onclick property does not contain the actual function, but merely a function call:

doSomething();

So it says “Go to doSomething() and execute it.” When we arrive at doSomething()the this keyword once again refers to the global window object and the function returns error messages.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------

3.两个的区别就是:第一种方式是完全复制;第二种只是指向了函数。

3.1

element.onclick = doSomething;
alert(element.onclick)
//结果如下

function doSomething()
{
	this.style.color = '#cc0000';
}

doSomething是element对象的一个属性(方法),类似下面:

var element = {
            value: "123",
            onclick: function doSomething() {
                console.log(this.value);
            }
        }
element.onclick();//123

3.2 

<element onclick="doSomething()">
alert(element.onclick)
//结果如下

function onclick()
{
	doSomething()
}

doSomething是一个嵌套函数,类似下面:

var element = {
       value: "123",
       onclick: function onclick(){
           doSomething();
       }
    }
function doSomething() {
    console.log(this.value);
}
element.onclick();//undefined

嵌套函数中的this要么指向window(非严格模式),要么undefined(严格模式)

参考链接:https://www.quirksmode.org/js/this.html

https://blog.csdn.net/u013584334/article/details/81192899

猜你喜欢

转载自blog.csdn.net/wml00000/article/details/88173783
今日推荐