前言

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 然後參數直接帶入