日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bind()、call()、apply()理解及用法

發布時間:2024/4/14 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bind()、call()、apply()理解及用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

apply和call都是為了改變某個函數運行時的上下文而存在的(就是為了改變函數內部this的指向),Function對象的方法,每個函數都能調用;

使用apply或call方法,其運行的上下文指向第一個參數,apply的第二個參數是一個參數數組,call的第二個及其以后的參數都是數組里面的元素。

apply和call的常用用法:

  • 數組之間的追加;

    例如:多維數字轉一維

    let arr=[1,[7,8],[5,6]];res=[].concat.apply([],arr)
  • 擴充作用域擁有Math的min和max方法,獲取數組中的最大值和最小值;

    let numbers = [5, 458 , 120 , -215 ];
    let maxInNumbers = Math.max.apply(Math, numbers), //458

    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
  • 驗證是否是數組;

    function isArray(obj){

    return Object.prototype.toString.call(obj) === '[object Array]' ;

    }

  • 讓類數組擁有方法;

    比如: arguments對象,獲取到的文檔節點等,并沒有數組的那些方法:

    Array.prototype.slice.apply(argument);
    //理論上來說這個比較快,直接在原型上查找slice方法
    //但實際上比較慢
    或者
    [].slice.apply(arguments);
    //理論上來說這個比較慢,因為要Array做一個實例化再查找slice方法
    //實際上比較快,因為現在的各種自動化工具會把上一種方法轉換為這種,而第二種代碼比較簡潔,所以會比較快;

  • binde 方法的使用

    也是改變函數體內this的指向,bind()是es5中的方法,bind會創建一個新函數,稱為綁定函數,當調用這個函數的時候,綁定函數會以創建它時傳入bind()方法的第一個參數作為this,傳入bind()方法的第二個及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數;
    例如:(后面的代碼皆取自張鑫旭大神的博客)

    var button = document.getElementById("button"),text = document.getElementById("text");button.onclick = function() {alert(this.id); // 彈出text}.bind(text);

    但由于ie6~ie8不支持該方法,所以若想在這幾個瀏覽器中使用,我們就要模擬該方法,這也是面試常考的問題,模擬的代碼如下:

    if (!function() {}.bind) {Function.prototype.bind = function(context) {var self = this;var args = Array.prototype.slice.call(arguments);return function() {return self.apply(context, args.slice(1)); }}; }

    上面的代碼中this的指向是個容易理解錯的地方。

    首先,我們判斷是否存在bind方法,然后,若不存在,向Function對象的原型中添加自定義的bind方法。

    這里面var self = this這段代碼讓我很困擾,按理說,prototype是一個對象,對象的this應該指向對象本身,也就是prototype,但真的是這樣嗎。看看下面的代碼:

    function a(){};a.prototype.testThis = function(){console.log(a.prototype == this);};var b = new a();b.testThis();//false

    顯然,this不指向prototype,而經過測試,它也不指向a,而指向b。所以原型中的this值就明朗了。指向調用它的對象

    Array.prototype.slice.call(arguments);

    上面這段代碼,它的作用是將一個類數組轉化為真正的數組,arguments是傳給call的那個上下文(由于arguments自己沒有slice方法,這里屬于借用Array原型的slice方法)。而且經過測試,若果你不給slice傳參數,那就等于傳了個0給它,結果就是返回一個和原來數組一模一樣的副本。

    這之后的代碼就很好理解,返回一個函數,該函數把傳給bind的第一個參數當做執行上下文,由于args已經是一個數組,排除第一項,將之后的部分作為第二部分參數傳給apply,前面講過apply的用法。

    如此,我們自己的這個bind函數的行為就同es5中的bind一樣了。

    總之三個的使用區別:

    • 都是用來改變函數的this對象的指向的;
    • 第一個參數都是this要指向的對象;
    • 都可以利用后續參數傳參;
    • bind是返回對應函數,便于稍后調用,apply、call是立即調用;

    總結

    以上是生活随笔為你收集整理的bind()、call()、apply()理解及用法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。