一、this的指向主要有下面幾種:
1、this出現在全局函數中,永遠指向window
var Car = function() { console.log(this); // window console.log(this.Car==window.Car,Car==window.Car); // true true } Car();
Car作為全局函數,直接調用時,函數的this指向window。
也就是Car==window.Car===this.Car
2、this出現在嚴格模式中 永遠不會指向window
函數中使用es5的嚴格模式‘use strict’,this為undefined
var Car = function() { 'use strict' console.log(this); // undefined } Car();
3、當某個函數為對象的一個屬性時,在這個函數內部this指向這個對象
如下圖:在car這個對象的run方法中打印this為car本身。
var car = { name:'豐田', run() { console.log(this); // {name: "豐田", run: ƒ} } }
4、this出現在構造函數中,指向構造函數新創建的對象
var Car = function(name) { this.name = name; console.log(this); // Car {name: "亞洲龍"} // Car {name: "漢蘭達"} } var myCar_1 = new Car('亞洲龍'); var myCar_2 = new Car('漢蘭達');
上述代碼中構造了兩個實例對象myCar_1和myCar_2,構造函數里面的this分別指向創建的實例化對象myCar_1和myCar_2。
5、當一個元素被綁定事件處理函數時,this指向被點擊的這個元素
var btn = document.querySelector('button'); btn.onclick = function() { console.log(this); // <button>this</button> }
6、this出現在箭頭函數中時,this和父級作用域的this指向相同
接下來看一段比較復雜的代碼:
const obj = { Car() { setTimeout(function() { setTimeout(function() { console.log(this); // window }) setTimeout(()=>{ console.log(this); // window }) }) setTimeout(() => { setTimeout(function() { console.log(this); // window }) setTimeout(()=>{ console.log(this); // obj }) }) } } obj.Car();
看到上述代碼是不是有點懵逼。別急 ! ! !,讓我娓娓道來。
首先遇到function(){}這種格式,如果是直接調用,瀏覽器會把Core傳進去,所以①和③this指向為window。
而箭頭函數的this是指向父級作用域,➁的父級作用域是setTimeout(function(){})里面,
前面已經說過function(){}這種格式如果直接調用Core傳進去,this指向為window,
所以➁的this指向=父級作用域的this指向=window,至於④就比較簡單了,這里不做贅述。
二、修改this的指向
上文說了this在函數中的指向問題,那么如何修改this的指向呢?
1、使用call、apply、bind修改this指向
具體使用方法請大家點擊我另一篇博客 https://www.cnblogs.com/tsl0324/p/14556853.html
3、使用new關鍵字改變this指向
也就是上述第一大點的第三小點所舉的例子。