前言
javaScript this 是會隨著當前的狀態而動態改變的, 複習一下以下程式碼的console.log的回傳。
var name = 'Mars';
const obj={
name:'Guest',
fun:function(){
console.log(this.name);
}
};
obj.fun();//Guest
const useFun = obj.fun;
useFun();//Mars
如果不熟悉的話建議複習一下[JavaScript] this是什麼?這篇文章。
在開發的時候如果需要指定this的物件時要怎麼辦呢?
bind、apply、call均可以達到目的,只是用法稍微不同。
bind、apply、call 簡單整理
bind、apply、call都是function物件的方法,他們的用法都可以指定this、帶入參數。 這邊先做基本的表格整理,
bind | apply | call | |
---|---|---|---|
指定this | V | V | V |
帶入參數 | V | V | V |
是否直接執行 | X | V | V |
bind
bind與其他兩種方法的最大差異為是否直接執行,
bind比較像是回傳一個新的function而已, 若要執行的話需要另外寫執行function的動作。
1. 指定this、是否直接執行
以下面範例來解釋:
const obj={
name:'Mars',
age:18
};
function fun(){
console.log('Name:'+this.name+'_Age:'+this.age);
}
fun();//未使用bind/apply/call,若對this不熟悉將可能出現使用問題
const funBind = fun.bind(obj);//透過bind綁定obj的物件給fun函式
funBind();//並透過新函式來呼叫
-----------------------------
Output:
Name:_Age:undefined
Name:Mars_Age:18
fun() : 單純執行find()未使用bind/apply/call,若對this不熟悉將可能出現使用問題。 const funBind = fun.bind(obj) : 透過bind綁定obj的物件給fun函式(指定this)。 funBind() : 並透過新函式來呼叫(需要另外呼叫來執行)。
2. 帶入參數
bind帶入參數會有一個限制,就是透過bind綁定過後的參數將不能更改。
const obj={
name:'Mars'
};
function fun(age){
console.log('Name:'+this.name+'_Age:'+age);
}
const funBind = fun.bind(obj,18);
funBind();
funBind(65);//嘗試更改Age
-----------------------------
Output:
Name:Mars_Age:18
Name:Mars_Age:18//還是一樣18
funBind(65) : 嘗試更改Age但是結果Age還是一樣18,代表不能更改。
apply、call
apply、call這兩個方法比較相近,直接一起來看, 直接來看程式碼:
const obj={
name:'Mars'
};
function fun(age,sex){
console.log('Name:'+this.name+'_Age:'+age+'_Sex:'+sex);
}
fun.apply(obj,[18,'male']);//或fun.apply(obj,new Array(18,'male'));
fun.call(obj,18,'male');
-----------------------------
Output:
Name:Mars_Age:18_Sex:male
Name:Mars_Age:18_Sex:male
fun.apply(obj,[18,‘male’]); 直接執行 並 指定this 然後參數需要用陣列的方式帶入。
fun.call(obj,18,‘male’);直接執行 並 指定this 然後參數直接帶入。