(推薦)js apply()、call()和bind()的區別,手寫Bind的實現原理

手寫bind()

描述:

bind()和apply還有call均可以改變關鍵詞this的做用域,它們的用法有所不一樣,各有千秋,如下是對三個函數的描述和使用例子:

  • apply:func.apply(obj,[arg1,arg2,...]) 把函數func內部的this做用域指向obj,而後把傳給func的參數分別放到數組中傳給func
    數組

  • call:func.call(obj,arg1,arg2,...) 與apply相似,不過傳參的方式是一個一個傳,不用放在數組裏邊
    app

  • bind:func.bind(obj,arg1,arg2,...)(other-arg); 與call和apply不一樣的是,bind()能夠預約義參數,arg1和arg2爲預約義的參數,other-arg爲其餘參數,這麼作的好處在於,咱們能夠用先用一個變量var vary = func.bind(obj,arg1,arg2,...),而後再使用vary(other-arg)來傳入其餘參數,如此一來,就至關於給函數預先傳入了一些相對不變參數,一些須要變化的參數再另外傳入,這是apply和call都作不到的。
    bind的用法舉例及其效果
    bind用法
    效果函數

手寫bind代碼部分:

// 定義在Function.prototype上,好讓使用Function構造器建立新函數的時候都自帶bind()方法
    Function.prototype.bind=function(obj,arg){
    // 獲取從第二個參數起也就是除了obj以外的其他參數
    var arg=Array.prototype.slice.call(arguments,1);
    // 把this做用域賦給context,由於關鍵詞this的做用域在不一樣的地方不同
    var context=this;
    // 定義一個函數,使之能夠拼接原bind函數傳入的參數,即bind(obj,args1)(args2) == bind(obj,args1,args2)
    // 這裏默認讓newArg爲一個對象,否則會報錯
    var bound=function(newArg={}){
    arg=arg.concat(Array.prototype.slice.call(newArg));
    return context.apply(obj,arg);
    }
    // 接下來就是建立一個新函數,使它的prototype(原型對象)等於Function的prototype,而後再把要return的函數bound的prototype指向F這個構造函數,
    // 就把bind()方法放到Function.prototype中去了
    var F=function(){}
    F.prototype=context.prototype;
    bound.prototype=new F();
    return bound;
    }

附一張原型鏈圖方便你們理解:

原型鏈

參考文章(對原型鏈的理解):

https://www.jianshu.com/p/423f72d502c2 還不懂原型鏈的建議看看this

相關文章
相關標籤/搜索