JavaScript中的call,apply,bind區別及應用

今天在讀程序題的時候,遇到call,apply,bind的使用。

const person = { name: 'Lydia' }

function sayHi(age) {
  console.log(`${this.name} is ${age}`)
}

sayHi.call(person, 21)
sayHi.bind(person, 21)

一、談一下上述三者的使用目的:三者都是用來改變this的指向。

二、三者分別是如何定義的及區別(摘自MDN):

apply() 方法調用一個具有給定this值的函數,以及作爲一個數組(或類似數組對象)提供的參數。

MDN關於apply詳細介紹:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply 

注意:call()方法的作用和 apply() 方法類似,區別就是call()方法接受的是參數列表,而apply()方法接受的是一個參數數組

bind()方法創建一個新的函數,在調用時設置this關鍵字爲提供的值。並在調用新函數時,將給定參數列表作爲原函數的參數序列的前若干項。 

MDN關於bind詳細介紹:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。

MDN關於call詳細介紹:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call 

注意:該方法的語法和作用與 apply() 方法類似,只有一個區別,就是 call() 方法接受的是一個參數列表,而 apply() 方法接受的是一個包含多個參數的數組

三、在程序中收穫

<script>
 	var name = 'Lily',
 		age = 13
 	var obj = {
 		name: 'Sam',
 		objAge: this.age,
 		myFunc: function (param1, param2) {
 		console.log(this.name + ' ' + this.objAge + ' ' + this.age + ' ' + param1 + ' '  + param2)
 		// Sam 13 undefined 1 2
 	    }
 	}
 	obj.myFunc(1, 2)
</script>

 非常明確,在obj.myFunc()中,通過this.age是獲取不到定義在window中的age值,因爲在該方法中,this指向的是obj對象。因此值爲undefined,這個時候,可以通過call,apply,bind來更改this的指向,從而獲取值。

<script>
 	var name = 'Lily',
 		age = 13
 	var obj = {
 		name: 'Sam',
 		objAge: this.age,
 		myFunc: function (param1, param2) {
 			console.log(this.name + ' ' + this.objAge + ' ' + this.age + ' ' + param1 + ' '  + param2)
 			// Amy 20 21 1 2
 		}
 	}
 	var db = {
 		name: 'Amy',
 		age: 21,
 		objAge: 20
 	}
 	obj.myFunc.call(db, '1', '2') // db爲this要指向的對象,後面傳入的是參數列表,參數可以是任意類型,當第一個參數爲null、undefined的時候,默認指向window;
    obj.myFunc.apply(db, [1, 2]) // db爲this要指向的對象,參數必須放在一個數組裏面;
 	obj.myFunc.bind(db, '1', '2')() // db爲this要指向的對象,返回的是一個新函數,必須調用纔會去執行。
</script>

四、上述三者的具體應用:

轉自:https://blog.csdn.net/wyyandyou_6/article/details/81488103

另:用 apply 將數組添加到另一個數組

我們可以使用push將元素追加到數組中。並且,因爲push接受可變數量的參數,我們也可以一次推送多個元素。但是,如果我們傳遞一個數組來推送,它實際上會將該數組作爲單個元素添加,而不是單獨添加元素,因此我們最終得到一個數組內的數組。如果那不是我們想要的怎麼辦?在這種情況下,concat確實具有我們想要的行爲,但它實際上並不附加到現有數組,而是創建並返回一個新數組。 但是我們想要附加到我們現有的陣列......那麼現在呢? 寫一個循環?當然不是嗎?

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

最後迴歸最初的讀程序,結果是

Lydia is 21 function

undefined

使用這兩種方法,我們都可以傳遞我們希望 this 關鍵字引用的對象。但是,.call 是立即執行的。

.bind 返回函數的副本,但帶有綁定上下文!它不是立即執行的。

 

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