call,apply,bind

來源:互聯網
上載者:User

標籤:作用   上下   asc   ext   reference   comm   this   上下文   extern   

在JavaScript中,callapplybindFunction對象內建的三個方法,都是為了改變函數體內部 this 的指向。

           apply 、 call 、bind 三者第一個參數都是 this 要指向的對象,也就是想指定的上下文;

           apply 、 call 、bind 三者都可以利用後續參數傳參;

                        bind 是返回對應 函數,便於稍後調用;apply 、call 則是立即調用 。

例子:

1.

function fruits() {}     fruits.prototype = {          color: ‘red‘,          say: function() {          console.log(‘My color is‘ + this.color);               }         }   var apple = new fruits; apple.say();   // 此時方法裡面的this 指的是fruits // 結果: My color is red

但是如果我們有一個對象 banana= {color : ‘yellow‘} ,我們不想重新定義 say 方法,那麼我們可以通過 call 或 apply 用 apple 的 say 方法:

banana = {color: ‘yellow‘}apple.say.call(banana); //此時的this的指向已經同過call()方法改變了,指向的是banana,this.color就是banana.color=‘yellow‘;//結果是My color is yellow  apple.say.apply(banana);//同理,此時的this的指向已經同過apply()方法改變了,指向的是banana,this.color就是banana.color =‘yellow‘;//My color is yellow// 如果傳入的是 null:apple.say.apply(null); // null是window下的,此時,this 就指向了window ,但是window下並沒有clolr這個屬性,因此this.clolr就是window.color=undefined;//My color is undefined

2.對於 apply、call 二者而言,作用完全一樣,只是接受 參數 的方式不太一樣。call 是把參數按順序傳遞進去,而 apply 則是把參數放在數組 裡。

var array1 = [12,‘foo‘,{name:‘Joe‘},-2458];var array2 = [‘Doe‘ , 555 , 100];Array.prototype.push.call(array1, array2);// 這裡用 call 第二個參數不會把 array2 當成一個數組,而是一個元素//等價於array1.push(‘‘‘Doe‘ , 555 , 100’’);//array1.length=5; Array.prototype.push.apply(array1, array2); // 這裡用 apply 第二個參數是一個數組 // 等價於:  array1.push(‘Doe‘ , 555 , 100);//array1.length=7;
3.類(偽)數組使用數組方法
var divElements = document.getElementsByTagName(‘div‘); //雖然 divElements 有length屬性,但是他是一個偽數組,不能使用數組裡面的方法Array.isArray(divElements);// false var domNodes = Array.prototype.slice.call(document.getElementsByTagName(‘div‘));// 將數組對象Array裡的this指向偽數組document.getElementsByTagName(‘div‘), //slice() 方法可從已有的數組中返回選定的元素,不傳參數是,返回整個數組 Array.isArray(domNodes);// true
4. 驗證一個對象的類型可以用:
Object.prototype.toString.call(obj) 

5.bind() 方法,MDN 的解釋是:bind() 方法會建立一個 新函數,稱為綁定函數,當調用這個綁定函數時,

綁定函數會以建立它時傳入 bind() 方法的第一個參數 作為 this,傳入 bind() 方法的 第二個以及以後的參

數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。

var bar = function(){    console.log(this.x);}var foo = {    x:3}bar(); // undefinedvar func = bar.bind(foo); //此時this已經指向了foo,但是用bind()方法並不會立即執行,而是建立一個新函數,如果要直接調用的話 可以 bar.bind(foo)()func(); // 3

6.在 Javascript 中,多次 bind() 是無效的。更深層次的原因, bind() 的實現,相當於使用函數在內部包了一個 call / apply ,第二次 bind() 相當於再包住第一次 bind() ,故第二次以後的 bind 是無法生效的。

var bar = function(){  console.log(this.x);}var foo = {  x:3}var sed = {  x:4}var func = bar.bind(foo).bind(sed);func(); //3  var fiv = {  x:5}var func = bar.bind(foo).bind(sed).bind(fiv);func(); //3

7.apply、call、bind 三者相比較,之間又有什麼異同呢?何時使用 apply、call,何時使用 bind 呢。簡單的一個例子:

var obj = {  x: 81,};  var foo = {  getX: function() {    return this.x;  }}console.log(foo.getX.bind(obj)());  //81console.log(foo.getX.call(obj));    //81console.log(foo.getX.apply(obj));   //81

參考:

  • 深入淺出 妙用Javascript中apply、call、bind
  • Function.prototype.bind()
  • Function.prototype.call()
  • Function.prototype.apply()

call,apply,bind

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.