原本标題是:element.onclick = fun與<element οnclick="fun()">的差別,但是提示含有非法字元。
問題背景:
在看this指向的時候看到了這個,有的時候通過給DOM元素綁定監聽事件,來觸發某些事件處理函數(如點選目前元素時修改該元素樣式等),如果綁定的監聽函數裡面用到了this,上面兩種方式可能會有不同的效果。
試驗代碼:
<!DOCTYPE html>
<html >
<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