JavaScript中的apply和call函數詳解

來源:互聯網
上載者:User

標籤:

本文是翻譯Function.apply and Function.call in JavaScript,希望對大家有所協助

轉自“http://www.jb51.net/article/52416.htm”

第一次翻譯技術文章,見笑了!

翻譯原文:

Function.apply and Function.call in JavaScript

第一段略。

每個JavaScript函數都會有很多附屬的(attached)方法,包括toString()、call()以及apply()。聽起來,你是否會感到奇怪,一個函數可能會有屬於它自己的方法,但是記住,JavaScript中的每個函數都是一個對象。看一下 這篇文章 ,複習一下(refresher)JavaScript特性。你可能還想知道JavaScript中函數和方法的區別。我認為“函數”和“方法”的描述,僅僅是JavaScript的習慣約定而已。函數立足於它們自己(例如:alert()),而方法是函數內部一個對象的屬性(dictionary),我們通過對象來調用方法。每個JavaScript對象都有一個toString()方法,下面通過代碼舉例說明,在一個函數對象中,我們可以使用toString()方法

1 <script> 2 function foo(){3    alert(‘x‘);4 }5 alert(foo.toString());6 </script>

 

因為函數都是對象,它們有自己的屬性和方法。我們可以把它們看作資料(data)。這篇文章,我們只關注兩個函數的方法apply()以及call()。

我們從下面的代碼開始:

1 var x = 10;2 function f(){3  alert(this.x);4 }5 f();

 

我們定義了一個全域函數f()。f()通過this關鍵字訪問變數x,但是需要注意的是,我們不能通過一個對象的執行個體來調用這個函數。this指向的是什麼對象呢?this會指向這個全域對象。我們的變數x就是在這個全域對象中定義的。上面的代碼能夠正常運行,運行結果會顯示一個對話方塊,對話方塊中顯示10。

我們可以通過this來調用call()和apply()。正如下面的例子展示如何使用call():

1 var x = 10;2 var o = { x : 15};3 function f(){4  alert(this.x);5 }6 f();7 f.call(o);

首先調用f()將會顯示10的對話方塊,因為this這個時候指向的是全域對象。然後我們調用f函數的call()方法,傳入的參數是o,運行結果顯示的是o中x屬性的值15。call()方法會用它的第一個參數作為f函數的this指標。也就是說,我們會告訴運行時,f函數中的this指向的是哪個對象。

this跳轉聽起來有些滑稽,甚至對於C++、Java以及C#程式員來說有些反常。這些都是ECMAScript中有趣的部分。

通過call()也可以給函數傳遞參數:

1 var x = 10;2 var o = { x : 15};3 function f(){4  alert(this.x);5 }6 f();7 f.call(o);

 

apply()和call()類似的,只是apply()要求第二個參數必須是一個數組。這個數組會作為參數傳遞給目標函數。

1 var x = 10;2 var o = {x : 15};3 function f(message) {4  alert(message);5  alert(this.x);6 }7 f(‘invoking f‘);8 f.apply(o, [‘invoking f through apply‘]);

apply()方法是很有用的,因為我們可以建立一個函數而不用去關心目標方法的參數。這個函數可以通過apply()的第二個數組參數來傳遞額外的參數給方法。

 1 var o = {x : 15}; 2 function f1(message1) { 3  alert(message1 + this.x); 4 } 5 function f2(message1, message2) { 6  alert(message1 + (this.x * this.x) + message2); 7 } 8 function g(object, func, args) { 9  func.apply(object, args);10 }11 g(o, f1, [‘the value of x = ‘]);12 g(o, f2, [‘the value of x squared = ‘, ‘. Wow!‘]);

這樣的文法有點問題。為了調用apply()方法,我們強制目標函數使用數組中的參數。幸運的是,有一個方法可以讓這種文法更簡單。在此之前,我們必須先介紹一個:參數標識符。

在JavaScript中,其實每個函數都有一個可變長度的參數列表。這意味著,即使一個函數只有一個參數的時候,我們也可以傳遞5個參數給它。下面的代碼不會有錯誤,而且結果顯示的是“H”。

1 function f(message) {2  alert(message);3 }4 f(‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘);

在f()中,如果我們不想去接受其他的參數,我們可以用關鍵字arguments。arguments代表一個參數對象,它有一個代表長度的屬性類似於數組。

1 function f(message) {2  // message的值和arguments[0]是一樣的3  for(var i = 1; i < arguments.length; i++){4   message += arguments[i];5  }6  alert(message);7 }8 // 結果顯示“Hello”9 f(‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘);

你應該知道,嚴格來講,arguments不是一個數組。arguments有一個length屬性,但是沒有split、push、pop方法。在前面的g()函數中,我們可以從arguments中拷貝需要的參數,組成數組,然後把這個數組傳遞給apply()。

 1 var o = {x : 15}; 2 function f(message1, message2) { 3  alert(message1 + ( this.x * this.x) + message2); 4 } 5 function g(object, func) { 6  // arguments[0] = object 7  // arguments[1] = func 8  var args = []; 9  for(var i = 2; i < arguments.length; i++) {10   args.push(arguments[i]);11  }12  func.apply(object, args);13 }14 g(o, f, ‘The value of x squared = ‘, ‘. Wow!‘);

 

當我們調用g(),we can pass additional arguments as parameters instead of stuffing the arguments into an array。

JavaScript中的apply和call函數詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.