call,apply and bind in the javascript

根據javascript高級程序設計第三版 “事實上,傳遞參數並非apply()和call()真正用武之地,他們真正強大的地方是能夠擴充函數賴以運行的作用域“ && “擴充作用域的最大好處,就是對象不需要與方法有任何耦合關係”

Chapter 1

        //A有方法,B沒有,通過call B可以引用A的方法
        function cat(){
           }
        cat.prototype={
            food:"fish",
            say: function(word){
            alert("I love "+this.food+" and talk "+word);
            }
        }

        var blackCat = new cat;
        //blackCat.say('miaomiao');

        var whiteDog = {food:"bone"}
        blackCat.say.call(whiteDog,'wangwang');
        //blackCat.say.apply(whiteDog,['wangwang']);

這裏blackCat繼承了Cat的say方法,而whiteDog如果在不想定義say方法的情況下使用,就需要call的出現了,這裏whiteDog可是引用到blackCat的say方法

Chapter 2

        // call實現繼承
         var Parent = function(){
             this.name = "yjc";
             this.age = 22;
         }
         var child = {};
         console.log(child);//Object {} ,空對象
         Parent.call(child);
         console.log(child); //Object {name: "yjc", age: 2}

通過call來實現屬性的繼承

Chapter 3

        // call將參數轉爲數組
        function exam(a, b, c, d, e) {

            // 先看看函數的自帶屬性 arguments 什麼是樣子的
            console.log(arguments);
            // 使用call/apply將arguments轉換爲數組, 返回結果爲數組,arguments自身不會改變
            var arg = [].slice.call(arguments);

            console.log(arg);
        }

        exam(2, 8, 9, 10, 'guguji');

        // result: 
        // { '0': 2, '1': 8, '2': 9, '3': 10, '4': 'guguji','length':5 }
        // [ 2, 8, 9, 10, 3 ]

[].slice.call()這種方法可以將帶有length的key爲自然數的json轉換爲數組,也常常使用該方法將DOM中的nodelist轉換爲數組。

[].slice.call( document.getElementsByTagName('li')

call和apply功能相同,只是寫法不一樣而已。

fun.call(this,1,2,'dukuan');
fun.apply(this,[1,2,'dukuan']);//參數以數組的方式傳入

e.g. Math.max(a,b,…,x,y)函數用於取若干值(不是隻能比較兩個)中的最大值,所以求一個數組中([1,4,5,2,65,7,5])的最大值可以藉助apply

var arr=[1,2,2,1,4,5,6,6,8,9,55];
var Max=Math.max.apply(null,arr);//最大值爲55

bind vs call,apply

MDN bind的定義是:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

bind方法創建一個新函數,當被調用時會改變this的值以及傳入一串新函數調用的預設參數。
偶發現bind和call,apply的一個不同是bind會返回一個新函數並且帶有一些預設參數(不會執行)而call,apply會調用這個函數。

bind的兩大功能,改變this和預設參數。

爲了兼容低版本瀏覽器bind可以重寫:

Function.prototype.Bind = function(index){
            var that = this;
            var arg = Array.prototype.slice.call(arguments,1)
            return function(){
                var arg1 = Array.prototype.slice.call(arguments);
                that.apply(index,arg.concat(arg1))
            }
          }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章