普通函數中的this:
1. this總是代表它的直接調用者, 例如 obj.func ,那么func中的this就是obj
2.在默認情況(非嚴格模式下,未使用 'use strict'),沒找到直接調用者,則this指的是 window
3.在嚴格模式下,沒有直接調用者的函數中的this是 undefined
4.使用call,apply,bind(ES5新增)綁定的,this指的是 綁定的對象
箭頭函數中的this
默認指向在定義它時,它所處的對象,而不是執行時的對象, 定義它的時候,可能環境是window(即繼承父級的this);
下面通過一些例子來研究一下 this的一些使用場景
示例1
<script>
var obj = {
say: function () {
setTimeout(function () {
console.log(this)
});
}
}
obj.say();
</script>
結果是:window
匿名函數,定時器中的函數,由於沒有默認的宿主對象,所以默認this指向window
問題: 如果想要在setTimeout中使用這個對象的引用呢?
用一個 變量提前把正確的 this引用保存 起來, 我們通常使用that = this, 或者 _this = this來保存我們需要的this指針!
<script>
var obj = {
func: function() {},
say: function () {
var that = this; //此時的this就是obj對象
setTimeout(function () {
console.log(this)
that.func()
});
}
}
obj.say();
</script>
示例2
window.val = 1;
var obj = {
val: 2,
dbl: function () {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
}
};
// 說出下面的輸出結果
obj.dbl();
var func = obj.dbl;
func();
結果是:2 4 8 8
<1> 12行代碼調用
val變量在沒有指定對象前綴,默認從函數中找,找不到則從window中找全局變量
即 val *=2 就是 window.val *= 2
this.val默認指的是 obj.val ;因為 dbl()第一次被obj直接調用
<2>14行代碼調用
func() 沒有任何前綴,類似於全局函數,即 window.func調用,所以
第二次調用的時候, this指的是window, val指的是window.val
第二次的結果受第一次的影響
示例3.在嚴格模式下的this
<script>
function test() {
'use strict';
console.log(this);
}
test();
</script>
結果是:undefined
示例4.箭頭函數中的this
<script>
var obj = {
say: function () {
setTimeout(() => {
console.log(this)
});
}
}
obj.say(); // obj
</script>
此時的this是定義它的對象,即繼承父級的this,父級中的this指的是obj,而非window
示例5
<script>
var obj = {
say: function () {
var f1 = () => {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
})
}
f1();
}
}
obj.say()
</script>
結果:都是obj
f1繼承父級this指代的obj,不管f1有多層箭頭函數嵌套,都是obj.
示例6
<script>
var obj = {
say: function () {
var f1 = function () {
console.log(this); // window, f1調用時,沒有宿主對象,默認是window
setTimeout(() => {
console.log(this); // window
})
};
f1();
}
}
obj.say()
</script>
結果:window,window
第一個this:f1調用時沒有宿主對象,默認是window
第二個this:繼承父級的this,父級的this指代的是window.
