//<button>獲取隨機的人</button> //<input type="text"> var user = { data:[ {name:"張三", age:37}, {name:"李四", age:43} ], clickHandler:function (event) { var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // 隨機獲取 0 或者 1 // 從數組中取出值,賦值到 Input 文本框內 $ ("input").val (this.data[randomNum].name + " " + this.data[randomNum].age); } } // 綁定事件 $ ("button").click (user.clickHandler);
當點擊的時候,會報錯,由於 clickHandler 方法中的 this 指向的是 button 元素。javascript
爲了解決這個問題,咱們可使用 bind 方法。
使用以下代碼:java
$ ("button").click (user.clickHandler.bind (user));
代替以前:數組
$ ("button").click (user.clickHandler);
可是,在 IE9 如下和 Firefox 3.x 的瀏覽器中,是不支持 Bind 方法的,因此能夠考慮加入以下方法。瀏覽器
// 判斷是否支持 Bind 方法 if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { throw new TypeError (" Function.prototype.bind - 綁定錯誤"); } var aArgs = Array.prototype.slice.call (arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { return fToBind.apply (this instanceof fNOP && oThis ? this : oThis, aArgs.concat (Array.prototype.slice.call (arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP (); return fBound; }; }
咱們繼續咱們的例子,考慮以下代碼:app
// 全局變量 var data = [ {name:"王五", age:12}, {name:"陳六", age:14} ] var user = { // 局部變量 data:[ {name:"張三", age:37}, {name:"李四", age:43} ], showData:function (event) { var randomNum = ((Math.random () * 2 | 0) + 1) - 1; console.log (this.data[randomNum].name + " " + this.data[randomNum].age); } } var showDataVar = user.showData; showDataVar (); // 王五 12 (這裏說明是從 全局變量而不是局部變量中取數據)
當執行 showDataVar() 時,this 指向的是全局變量,而不是局部變量。這是由於 showDataVar() 是做爲全局函數執行的,它是綁定的是全局做用域,也就是瀏覽器的 window 對象。dom
一樣,咱們能夠經過使用 bind 方法指定 this 的值來解決這個問題:函數
// 把 showData 綁定到 user 對象 var showDataVar = user.showData.bind (user); // 如今咱們獲得了 user 的值 showDataVar (); // 張三 43
咱們知道在 JavaScript 中咱們能夠傳遞函數,返回函數和借調函數。Bind() 方法會使借調函數變地很是簡單易用。
以下代碼:this
// 這裏有個 cars 對象,它裏面沒有任何函數。 var cars = { data:[ {name:"黎明", age:14}, {name:"劉德華", age:2} ] } // 咱們能夠從上面例子中借調 user 對象中 showData () 函數。 // 咱們綁定 user.showData 函數處理 cars 對象。 cars.showData = user.showData.bind (cars); cars.showData (); // 黎明 14
這樣寫的代碼有個問題,就是會在 cars 對象中,新加一個函數(showData),這可能不是咱們的本意,由於可能 cars 對象中此前已經有了一個叫 showData 的屬性或者函數了。咱們不想意外覆蓋它。在下文中會說明,最好的借調方式是使用 Apply 或者 Call。url
柯里化:是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。百度百科的定義prototype
首先,看如下代碼,是個有三個參數的方法 greet():
function greet (gender, age, name) { // 若是性別爲男,使用 "先生", 不然使用 "女士"。 var salutation = gender === "male" ? "先生" : "女士"; if (age > 25) { return "你好," + name + salutation + "。"; } else { return "你好," + name + "。"; } }
接下來,咱們使用 bind() 來進行函數柯里化()。
// 由於咱們不想使用 this 關鍵字,因此第一個參數咱們傳遞 null。 var greetAnAdultMale = greet.bind (null, "male", 45); greetAnAdultMale ("李連杰"); // "你好,李連杰先生。" var greetAYoungster = greet.bind (null, "", 16); greetAYoungster ("成龍"); // "你好, 成龍。" greetAYoungster ("李小龍"); // "你好,李小龍。"
當咱們使用 bind() 進行柯里化的時候,除了最後一個外,全部的參數都被預設置好了。