JavaScript中的this一直以來都是一個比較不容易理解的知識點,this的指向問題很容易對新手造成干擾這里就總結(jié)一下JavaScript中的this的指向問題
this的指向大致分為以下四種:
- 作為對象的方法調(diào)用
- 作為普通函數(shù)調(diào)用
- 構(gòu)造器調(diào)用
- Function.prototype.call或Function.prototype.apply調(diào)用
下面分別進行介紹:
1.作為對象的方法調(diào)用
當(dāng)函數(shù)作為對象的方法被調(diào)用時,this指向該對象;
var obj = {
a: 1,
getA: function () {
alert(this === obj); //輸出true
alert(this.a); // 輸出1
}
}
obj.getA()
2.作為普通函數(shù)調(diào)用
當(dāng)函數(shù)不作為對象的屬性被調(diào)用時,也就是我們通常說得普通函數(shù)方式,此時的this總是指向全局對象.在瀏覽器的JavaScript里,這個全局對象就是window對象.
window.name = 'globalName'
var getName = function () {
return this.name
}
console.log(getName()); // 輸出globalName
或者
window.name = 'globalName'
var getName = function () {
return this.name
}
console.log(getName()); // 輸出globalName
var myObject = {
name: 'michael',
getName: function () {
return this.name
}
}
console.log(myObject.getName()) // 輸出michael
var getName = myObject.getName
console.log(getName()) // 輸出globalName
有時候我們會遇到一些困擾,比如在div節(jié)點的事件內(nèi)部,有一個局部的callback方法,callback作為普通函數(shù)調(diào)用時,callback內(nèi)部的this指向了window,但我們往往希望讓它總是指向該節(jié)點,見如下代碼:
<div id="div1">我是一個div</div>
<script>
window.id = 'window'
document.getElementById('div1').onclick = function () {
alert(this.id) //輸出div1
var callback = function () {
alert(this.id); //輸出window
}
callback();
}
</script>
此時有一種簡單的解決方案,可以用一個變量臨時保存div節(jié)點的引用:
window.id = 'window'
document.getElementById('div1').onclick = function () {
var that = this; // 保存div的引用
var callback = function () {
alert(that.id); //輸出div1
}
callback();
}
在ECMA5的static模式下,這種情況的this已經(jīng)被規(guī)定為不會指向全局對象,而是undefined:
function func() {
"use strict";
alert(this);//輸出undefined
}
func();
在最新的es6中,引入了箭頭函數(shù)的概念,箭頭函數(shù)很大一部分對this的影響很深,這里不對es6的箭頭函數(shù)詳細分析,直接拿出結(jié)論,箭頭函數(shù)沒有自己的 this,其內(nèi)部的 this 綁定到它的外圍作用域。對象內(nèi)部的箭頭函數(shù)若有this,則指向?qū)ο蟮耐鈬饔糜颉?/p>
window.color = "red";
//let 聲明的全局變量不具有全局屬性,即不能用window.訪問
let color = "green";
let obj = {
color: "blue",
getColor: () => {
return this.color;//this指向window
}
};
let sayColor = () => {
return this.color;//this指向window
};
obj.getColor();//red
sayColor();//red
如果是對vue熟悉的,那么對這個問題就更容易理解了,在vue中,我們會很方便的使用箭頭函數(shù),比如ajax之后,改變vue的data的值:
html:
<div id="app" @click="getName">
我是div
</div>
<script>
let a = 10
var vm = new Vue({
el: '#app',
data: {
a: 11
},
methods: {
getName: function () {
console.log(this.a) // 輸出11
$.get('https://cnodejs.org/api/v1/topics', function (data) {
console.log(this.a) // 輸出undefined
var that=this;
console.log(that.a);//輸出11
})
$.get('https://cnodejs.org/api/v1/topics', (data) => {
console.log(this.a) //輸出11
})
}
}
})
</script>
以上兩種用jQuery的ajax在vue中分別使用了普通函數(shù)和箭頭函數(shù),輸出的結(jié)果都不一樣,箭頭函數(shù)指向了vue對象,所以輸出data里面的a,輸出11,普通函數(shù)則輸出undefined.
查看原文:https://blog.noob6.com/2018/06/03/the_meaning-of-this-in-javascript/