咱們在js中常常看到this這個關鍵字,那麼他是什麼呢?它能夠是全局對象、當前對象,也能夠是任意對象,函數的調用方式決定了 this 的值。javascript
1. 方法中的this。java
在對象方法中, this 指向調用它所在方法的對象。例如:數組
var information = { name: "alan", age : "18", all : function() { return this.name + " " + this.age; } };
在這裏,this 表示 information 對象。all 方法所屬的對象就是 information。app
2. 單獨直接調用this.函數
單獨使用 this,則它指向全局(Global)對象。例如:this
var name = this; && "use strict";(嚴格模式) var name = this;
3. 函數中調用this.spa
在函數中,函數的所屬者默認綁定到 this 上。例如:prototype
function information() { return this; } && "use strict";(嚴格模式) function information() { return this; }
4. 箭頭函數調用this.code
ES6 新增了箭頭函數,箭頭函數不只更加整潔,還對 this 的指向進行了改進。箭頭函數會從做用域鏈的上一層繼承 this。orm
var obj = { y: function() { console.log(this === obj) var getX = () => { console.log(this === obj) } getX() } } obj.y() // true // true
和普通函數不同,箭頭函數中的 this 指向了 obj,這是由於它從上一層的函數中繼承了 this,你能夠理解爲箭頭函數修正了 this 的指向。例如:
var x = 1 var obj = { x: 2, y: function() { var getX = () => { console.log(this.x) } return getX() } } obj.y() // 2 var a = obj.y a() // 1
obj.y() 在運行時,調用它的對象是 obj,因此 y 中的 this 指向 obj,y 中的箭頭函數 getX 繼承了 y 中的 this,因此結果是 2。若是咱們先將 y 賦值給全局做用域中的變量 a,a 在運行時,y 中的 this 便指向了全局對象,因此獲得的結果是 1(非嚴格模式)。
5. js事件中調用this.
this 指向了接收事件的 HTML 元素。例如:
<button onclick="this.style.display='block'">顯示</button>
6. 使用call和apply
改變 this 的指向,可使用 call 或 apply 方法,它們均可以改變函數的調用對象。將一個對象做爲第一個參數傳給 call 或 apply,this 便會綁定到這個對象。若是第一個參數不傳或者傳 null 、undefined,默認 this 指向全局對象(非嚴格模式)或 undefined(嚴格模式)。
var x = 1; var obj = { x: 2 } function getX() { console.log(this.x) } getX.call(obj) // 2 getX.apply(obj) // 2 getX.call() // 1 getX.apply(null) // 1 getX.call(undefined) // 1
使用 call 和 apply 時,若是給 this 傳的不是對象,JavaScript 會使用相關構造函數將其轉化爲對象,好比傳 number 類型,會進行 new Number()
操做,傳 string 類型,會進行 new String()
操做。
function demo() { console.log(Object.prototype.toString.call(this)) } demo.call('hello') // [object String] demo.apply(5) // [object Number]
call 和 apply 的區別在於,call 的第二個及後續參數是一個參數列表,apply 的第二個參數是數組。參數列表和參數數組都將做爲函數的參數進行執行。
var x = 1 var obj = { x: 2 } function getSum(y, z) { console.log(this.x + y + z) } getSum.call(obj, 3, 4) // 9 getSum.apply(obj, [3, 4]) // 9
7. bind方法調用this.
bind 方法會建立一個新函數,新函數的 this 會永久的指向 bind 傳入的第一個參數。例如:
var x = 1 var obj_1 = { x: 2 } var obj_2 = { x: 3 } function getX() { console.log(this.x) } var a = getX.bind(obj_1) var b = a.bind(obj_2) getX() // 1 a() // 2 b() // 2 a.call(obj_2) // 2
雖然咱們嘗試給函數 a 從新指定 this 的指向,可是它依舊指向第一次 bind 傳入的對象,即便是使用 call 或 apply 方法也不能改變這一事實。
this 是 JavaScript 中很是重要的關鍵字,不一樣的運行環境和調用方式都會對 this 產生影響。理解它能讓咱們更熟練地使用這門語言!