JavaScript中的bind,call和apply函數的用法和區別

一直沒怎麼使用過JavaScript中的bind,call和apply, 今天看到一篇比較好的文章,以爲講的比較透徹,因此記錄和總結以下javascript

首先要理解的第一個概念,JavaScript中函數調用的方式,總結下來,有如下4種java

1. 方法調用程序員

2. 正常函數調用數組

3. 構造器函數調用瀏覽器

4. apply/call 調用app

要明白的第2個概念, JavaScript 中的函數,不管是上面哪一種函數調用方式,除了你函數聲明時定義的形參外,還會自動給函數添加兩個形參,分別是this 和 arguments函數

要明白的第3個概念,  Javascript中的函數,存在函數上下文(context) 這麼一個概念, 而函數上下文又存在【定義時上下文】,【運行時上下文】,【上下文是能夠改變的】這樣子的狀況, 而第2個概念中的this, 指向的就是當前函數中的上下文this

要明白的第4個概念, 也是咱們今天在這裏要講的call, apply函數的目的 => 它們在JavaScript函數中存在的目的,就是爲了改變某個函數運行時的上下文(context)而存在的, 換句話說,是爲了改變函數體內部this的指向spa

 

如今咱們一個一個來看prototype

1. 方法調用函數的方式

應該能夠理解,所謂方法調用函數的方式,就是說把一個函數定義爲一個對象的方法,而後經過調用這個對象的該方法,來達到調用該函數的目的

直接上代碼

 

var myValue = {

     para: 5,
     setFunc: function(xvalue){

         this.para = xvalue;

      }
}

myValue.setFunc(0);

 

在這裏,函數setFunc做爲變量myValue的也給方法存在,因此使用myValue.setFunc()的形式就能夠調用它。在這裏,函數setFunc中的this,綁定的上下文就是myValue, 因此this.para取到的就是對象myValue的para屬性

2.  正常函數調用

function setValue(xvalue)
{
    this.para = xvalue;
}

setValue(5);

 上面,咱們正常的定義了一個函數setValue,而後正常的調用setValue(5).  在這裏,函數setValue裏面的this綁定的是全局對象. 若是這段JavaScript代碼是運行在瀏覽器中,那麼這裏的this指向的就是瀏覽器的全局對象window. 因此這裏this.para 等價於 window.para. 那有人確定會很奇怪,若是當前瀏覽器的window中不存在para屬性呢,那麼這個時候,在這裏,javascript會自動給全局對象window加上para屬性,同時在這裏賦值爲5

3. 構造器函數調用

JavaScript 中的構造函數,你們知道,首先做爲構造函數的函數名首字母須要大寫,在函數內部必須有this關鍵字。 咱們來看一下構造函數的調用

function SetValue(xvalue)
{
     this.para = xvalue;
}

var myFunc = new SetValue(5);

在這裏,SetValue函數不是一個普通函數,它是一個構造函數, 調用它是使用new 關鍵字來生成一個新的對象myFunc, 在這裏,this綁定的上下文就再也不是window對象了,而是新的對象myFunc

因此  console.log(myFunc.para)  // 輸出5

4. apply/call 來調用函數

 咱們能夠看到,上面三種函數調用方式,this指向都不同,可是咱們程序員都沒法自定義或者說更改this的綁定指向。 那麼,若是咱們須要在程序中本身指定this的綁定上下文,有沒用方法呢。這就是apply/call的用處了

JavaScript 中全部函數都有一個公共的prototype => Function, 而Function 這個原型自帶了很多的屬性和方法,其中就有apply, call, bind方法。 咱們首先來看看apply 和 call方法

apply => 當一個對象沒有某個方法時,但這個方法在其餘地方存在。可能使用這個方法的apply方法,把這個方法運用到這個對象上。 它有兩個參數 apply(thisObj, [arg1,arg2,arg3...])

               第1個參數是傳遞給這個函數用來綁定this的值(指定這裏this所綁定的上下文是哪個)

                第2個參數是一個數組

咱們直接上代碼,來看一個例子

 

function setValue(xvalue)
{
    this.para = xvalue;
}

var applyObj = {};

setValue.apply(applyObj,[10]);

alert(setValue.para); // undefined
alert(applyObj.para);  //10

能夠看到,剛開始對象applyObj是咱們定義的一個空對象,而後經過函數原型默認持有的apply方法,咱們把函數setValue經過apply方法應用到空對象applyObj上去,使得對象applyObj擁有了setValue方法,同時,經過第一個參數,指定this所綁定的當前上下文是applyObj對象,傳入的參數爲10

call 方法和apply方法幾乎沒有區別,惟一的區別是, 它的第二個參數不是以數組的形式,而是經過逗號來列出參數的形式   call(thisObj,arg1,arg2,arg3...)  咱們直接來看代碼

function addValue(xvalue, yvalue)
{
    this.para = xvalue + yvalue;
}

var applyObj = {};

addValue.call(applyObj,2,3);

alert(addValue.para); // undefined
alert(applyObj.para);  //5

固然, 若是在call 或者apply方法中,你傳入的第一個參數是null, 那麼在這種狀況下,函數中的this 指向的依然會是全局對象window

而後,咱們來看一看bind

bind的功能和上面同樣,它接受的參數和call同樣. 惟一的區別是,函數使用bind方法後會生成一個新的函數,你想何時調用新的函數,就何時調用. 咱們來看一個例子

var myObj = {    
    "x" : 4
};
function addValue(y) {    
    alert(this.x + y);
}
addValue.apply(myObj, [5]);
addValue.call(myObj, 5);
var foo1 = addValue.bind(myObj, 5);
foo1();
相關文章
相關標籤/搜索