Method as Argument in Javascript

前些時候談過 在 Go 中使用 method 作為 argument ,它的觀念、適用場合有點像 partial application ,但當然形式完全不同。若把使用語言換為 JavaScript,要傳 function 通常都 是拿來當 callback,常常是 anonymous。如果用到超過一次,通常就會拉出來取 個名字。如果會重複用但參數略有不同,那可以寫個角色像是 factory 的 function 用來產生「要被當成 callback 的 function」。不過並非所有人都像 我一樣那麼不愛用 JavaScript 的(半殘)物件導向,自然免不了會有「想拿 method 當成 callback」的情況。以下程式碼雖然直覺,但就會掉入 this 陷 阱裡:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'use strict';

function Bot(name) {
this.name = name;
}

Bot.prototype.selfintro = function () {
return "I'm " + this.name;
};

function roll(intro) {
console.log(intro());
}

var no5 = new Bot('Number 5');
roll(no5.selfintro);

原因是執行到 roll 裡面時,this 並未被定義,所以呼叫傳入的參數 no5.selfintro 時,裡面 this 也一樣沒有定義。修正方法是用 bind 指 定 this,把最後一行換成:

1
roll(no5.selfintro.bind(no5));

語法很簡單,但在 JavaScript 程式中盡量把一切都化為資料與 function 個人 覺得是蠻好的設計方式。