聊聊Function的bind()

bind顧名思義,綁定。數組

bind()方法會建立一個新函數,當這個新函數被調用時,它的this值是傳遞給bind()的第一個參數,它的參數是bind()的其餘參數和其本來的參數。緩存

上面這個定義最後一句有點繞,咱們來理一下。函數

bind()接受無數個參數,第一個參數是它生成的新函數的this指向,好比我傳個window,無論它在何處調用,這個新函數中的this就指向window,這個新函數的參數就是bind()的第二個、第三個、第四個....第n個參數加上它本來的參數。(行吧,我本身都蒙圈了)學習

咱們仍是看看栗子比較好理解,舉個bind()最基本的使用方法:this

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在這種狀況下,"this"指向全局做用域

// 建立一個新函數,將"this"綁定到module對象
// 新手可能會被全局的x變量和module裏的屬性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

這裏很明顯,咱們在window對象下調用retrieveX,獲得的結果確定是window下的x,咱們把module對象綁定到retrieveX的this上,問題就解決了,無論它在何處調用,this都是指向module對象。spa

還有bind()的其餘參數,相信第一次接觸bind()的朋友看到上面的定義都會蒙圈。prototype

仍是舉個栗子:指針

function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// 建立一個擁有預設初始參數的函數
var leadingThirtysevenList = list.bind(undefined,[69,37],{a:2});

var list2 = leadingThirtysevenList(); // [[69,37],{a:2}]
var list3 = leadingThirtysevenList(1, 2, 3); // [[69,37],{a:2}, 1, 2, 3]

list函數很簡單,把傳入的每一個參數插入到一個數組裏,咱們用bind()給list函數設置初始值,由於不用改變list中this的指向,因此直接傳undefined,從第二個參數開始,就是要傳入list函數的值,list2和list3的返回值很好的說明了一切。code

我本身通常使用的bind()的場景是配合setTimeout函數,由於在執行setTimeout時,this會默認指向window對象,在使用bind()以前,我是這麼作的:對象

    function Coder(name) {
        var that = this;
        that.name = name;
        that.getName = function() {
            console.log(that.name)
        };
        that.delayGetName = function() {
            setTimeout(that.getName,1000)
        };
    }
    var me = new Coder('Jins')
    me.delayGetName()//延遲一秒輸出Jins

在函數內頂層定義一個that緩存this的指針,這樣不論怎麼調用,that都是指向 Coder的實例,可是多定義一個變量老是讓人不太舒服。

使用bind()就簡單多了:

    function Coder(name) {
        this.name = name;
        this.getName = function() {
            console.log(this.name)
        };
        this.delayGetName = function() {
            setTimeout(this.getName.bind(this),1000)
        };
    }
    var me = new Coder('Jins')
    me.delayGetName()//延遲一秒輸出Jins

 這樣就OK了,直接把setTimeout的this綁定到外層的this,這確定是咱們想要的!

行吧,先聊這麼多,堅持學習!

最後附上參考地址:

Function.prototype.bind()

相關文章
相關標籤/搜索