普通函數中this
1. this總是代表它的直接調用者(js的this是執行上下文), 例如 obj.func ,那麼func中的this就是obj
2.在默認情況(非嚴格模式下,未使用 'use strict'),沒找到直接調用者,則this指的是 window (約定俗成)
3.在嚴格模式下,沒有直接調用者的函數中的this是 undefined
4.使用call,apply,bind(ES5新增)綁定的,this指的是 綁定的對象
注意:普通函數中,內層函數不能從外層函數中繼承this的值,在內層函數中,this會是window或者undefined,臨時變量self用來將外部的this值導入到內部函數中(另外的方式是在內部函數執行.bind(this))
es6箭頭函數
箭頭函數沒有自己的this, 它的this是繼承而來; 默認指向在定義它時所處的對象(宿主對象),而不是執行時的對象, 定義它的時候,可能環境是window; 箭頭函數可以方便地讓我們在 setTimeout ,setInterval中方便的使用this。
===========================================================================
當在函數中使用一個變量的時候,首先在本函數內部查找該變量,如果找不到則找其父級函數,
最後直到window,全局變量默認掛載在window對象下
下面幾個例子
1、普通函數中內層函數
function fun(){
var self = this;
setTimeout(function(){
console.log(this);// window
console.log(self);// {id: 001}
console.log('id: ', self.id);// id:001
},500);
}
fun.call({id:001});
2、普通函數中內層函數.bind(this)
function fun(){
var self = this;
setTimeout(function(){
console.log(this); //{id: 1}
console.log(self); //{id: 1}
console.log('id: ', self.id); //id: 1
}.bind(this),500);
}
fun.call({id:001});
3、
function fun(){
/*setTimeout(() =>{
console.log("args:",arguments); //args:[2,2,3,4]
},500);*/
setTimeout(function(){
console.log("args:",arguments); //
},500);
}
fun(2,2,3,4);
4、
var obj = {
say: function () {
setTimeout(() => {
console.log(this)
});
}
}
obj.say(); // obj
5、
var obj = {
say: function () {
var f1 = () => {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
})
}
f1();
}
}
obj.say()
6、
var obj = {
say: function () {
var f1 = function () {
console.log(this); // window, f1調用時,沒有宿主對象,默認是window
setTimeout(() => {
console.log(this); // window
})
};
f1();
}
}
obj.say()
7、
var obj = {
say: function () {
'use strict';
var f1 = function () {
console.log(this); // undefined
setTimeout(() => {
console.log(this); // undefined
})
};
f1();
}
}
obj.say()
8、總結例子
var a = 'window';
var id = '1';
var obj2 = {
id: '2',
a: 'obj2'
}
var obj = {
a: 'obj',
id: '3',
say1: () => {
console.log(this.a);
console.log(this.id);
},
say2: function() {
var f1 = () => {
console.log(this.a);
console.log(this.id);
}
f1();
},
say3: () => {
var f1 = () => {
console.log(this.a);
console.log(this.id);
}
f1();
}
}
console.log('================================');
obj.say1.call(obj2)
console.log('================================');
obj.say2.call(obj2)
console.log('================================');
obj.say3.call(obj2)
console.log('================================');
obj.say1()
console.log('================================');
obj.say2()
console.log('================================');
obj.say3()
console.log('================================');