JavaScript的bind方法

bind()

方法建立一個新的函式,在 bind() 被呼叫時,這個新函式的 this 被指定為 bind() 的第一個引數,而其餘引數將作為新函式的引數,供呼叫時使用。

const module = { x: 42, getX: function() { return this。x; }};const unboundGetX = module。getX;console。log(unboundGetX()); // The function gets invoked at the global scope// expected output: undefinedconst boundGetX = unboundGetX。bind(module);console。log(boundGetX());// expected output: 42

語法

function。bind(thisArg[, arg1[, arg2[, 。。。]]])

thisArg

呼叫繫結函式時作為 this 引數傳遞給目標函式的值。 如果使用new運算子構造繫結函式,則忽略該值。當使用 bind 在 setTimeout 中建立一個函式(作為回撥提供)時,作為 thisArg 傳遞的任何原始值都將轉換為 object。如果 bind 函式的引數列表為空,或者thisArg是null或undefined,執行作用域的 this 將被視為新函式的 thisArg。

arg1, arg2, ...

當目標函式被呼叫時,被預置入繫結函式的引數列表中的引數。

建立繫結函式

bind() 最簡單的用法是建立一個函式,不論怎麼呼叫,這個函式都有同樣的

this

值。JavaScript新手經常犯的一個錯誤是將一個方法從物件中拿出來,然後再呼叫,期望方法中的 this 是原來的物件(比如在回撥中傳入這個方法)。如果不做特殊處理的話,一般會丟失原來的物件。基於這個函式,用原始的物件建立一個繫結函式,巧妙地解決了這個問題:

this。x = 9; // 在瀏覽器中,this 指向全域性的 “window” 物件var module = { x: 81, getX: function() { return this。x; }};module。getX(); // 81var retrieveX = module。getX;retrieveX();// 返回 9 - 因為函式是在全域性作用域中呼叫的// 建立一個新函式,把 ‘this’ 繫結到 module 物件// 新手可能會將全域性變數 x 與 module 的屬性 x 混淆var boundGetX = retrieveX。bind(module);boundGetX(); // 81

偏函式 Partially applied functions

bind() 的另一個最簡單的用法是使一個函式擁有預設的初始引數。只要將這些引數(如果有的話)作為 bind() 的引數寫在 this 後面。當繫結函式被呼叫時,這些引數會被插入到目標函式的引數列表的開始位置,傳遞給繫結函式的引數會跟在它們後面。

function list() { return Array。prototype。slice。call(arguments);}function addArguments(arg1, arg2) { return arg1 + arg2}var list1 = list(1, 2, 3); // [1, 2, 3]var result1 = addArguments(1, 2); // 3// 建立一個函式,它擁有預設引數列表。var leadingThirtysevenList = list。bind(null, 37);// 建立一個函式,它擁有預設的第一個引數var addThirtySeven = addArguments。bind(null, 37);var list2 = leadingThirtysevenList();// [37]var list3 = leadingThirtysevenList(1, 2, 3);// [37, 1, 2, 3]var result2 = addThirtySeven(5);// 37 + 5 = 42var result3 = addThirtySeven(5, 10);// 37 + 5 = 42 ,第二個引數被忽略

配合 setTimeout

在預設情況下,使用 window。setTimeout() 時,this 關鍵字會指向 window (或 global)物件。當類的方法中需要 this 指向類的例項時,你可能需要顯式地把 this 繫結到回撥函式,就不會丟失該例項的引用。

function LateBloomer() { this。petalCount = Math。ceil(Math。random() * 12) + 1;}// 在 1 秒鐘後宣告 bloomLateBloomer。prototype。bloom = function() { window。setTimeout(this。declare。bind(this), 1000);};LateBloomer。prototype。declare = function() { console。log(‘I am a beautiful flower with ’ + this。petalCount + ‘ petals!’);};var flower = new LateBloomer();flower。bloom(); // 一秒鐘後, 呼叫 ‘declare’ 方法