function(){} 和 () => {} 中this指向的問題

普通函數中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('================================');



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章