提供本身手動綁定this的方法windows
首先在js裏函數調用有4種模式:方法調用、正常函數調用、構造器函數調用、apply/call 調用。同時,不管哪一種函數調用除了你聲明時定義的形參外,還會自動添加2個形參,分別是 this 和 arguments。數組
在js裏,咱們編寫的函數,也是屬於對象, 由系統定義好的Function函數來建立出來的。因此函數都會有一個共有的原型對象,Fuction.prototype.而這個原型自帶有好幾個屬性和方法,其中就有這裏困惑的 bind、call、apply方法。
而三個函數有一個共同的特色就是能夠設置this的值。上面的3種函數調用方式,你能夠看到,this都是自動綁定的,沒辦法由你來設,當你想設的時候,就能夠用他們了app
它讓咱們構造一個參數數組(函數運行所需的參數)傳遞給函數,同時能夠本身來設置 this 的值,這就是它最強大的地方,。apply 函數接收 2 個參數,第一個是傳遞給這個函數用來綁定 this 的值,第二個是一個參數數組。函數
它容許咱們傳入不定長參數(函數運行所需的參數),同時能夠本身來設置 this 的值。 只是參數和apply不同。this
bind() 函數,上面講的不管是 call() 也好, apply() 也好,都是立馬就調用了對應的函數,而 bind() 不會, bind() 會生成一個新的函數,bind() 函數的參數跟 call() 一致,返回函數的this綁定爲第一個參數,後面接受傳遞給函數的不定參數。 bind() 生成的新函數返回後,你想何時調就何時調prototype
這兩個方法的用途都是在特定的做用域中調用函數,實際上等於函數體內this對象的值, 他們會當即執行code
做用在方法上的理解
當對象o上不存在方法f時,咱們經過call去指定 this時,就至關於在o上新增一個f方法,而後調用完成以後刪除。
f.call(o); f.apply(o); // 假設o中不存在m方法,則等價於: o.m = f; //將f存儲爲o的臨時方法 o.m(); //調用它,不傳入參數 delete o.m; //將臨時方法刪除
對象
實例:繼承
window.color = "red"; var o = {color: "blue"}; function sayColor(){ console.log(this.color); // 打印調用對象的顏色值 } sayColor(); // 打印 全局對象window 的color值 sayColor.call(window); // 打印 全局對象window 的color值 sayColor.call(this);// 打印 全局對象window 的color值 sayColor.call(o); // 打印 o 對象的 color值 console.log(o); // sayColor.call(o)等價於: // o.sayColor = sayColor; // o.sayColor(); //blue // delete o.sayColor;
function class1(){ this.name = function(x){ alert("我是class1的name(x)方法"+",我是class1name函數的參數(" + x + ")"); } } function class2(){ class1.call(this); // this 就是class的對象 } var c1 = new class2(); //c1.name(20); console.log(c1); // class2();
function sum(num1, num2){ console.log("num1:" + num1 + " num2:" + num2); return num1 + num2; } function applySum1(num1, num2){ return sum.apply(this,arguments); } function applySum2(num1, num2){ return sum.apply(this,[num1,num2]); } function callSum(num1, num2){ return sum.call(this,num1,num2); } console.log(callSum(1,2));
bind() 函數,上面講的不管是 call() 也好, apply() 也好,都是立馬就調用了對應的函數,而 bind() 不會, bind() 會生成一個新的函數,bind() 函數的參數跟 call() 一致,第一個參數也是綁定 this 的值,後面接受傳遞給函數的不定參數。 bind() 生成的新函數返回後,你想何時調就何時調作用域
var m = { "x" : 1 } function foo(y){ console.log(this.x + y); } foo.apply(m, [5]); // apply 接收數組 會自動展開 foo.call(m,5); // call 接受可變參數 var foo1 = foo.bind(m); foo1(5);
其實這裏的this改變你能夠認爲,是給對象添加了一個方法,以後刪除。可能這樣好理解點。而對於參數而言,其實就是一個要求數組,兩個要是不定長參數,視狀況用,還有就是bind返回的是一個新函數,不會當即執行。