JavaScript中的apply和call函數詳解

本文是翻譯Function.apply and Function.call in JavaScript,但願對你們有所幫助程序員

轉自「http://www.jb51.net/article/52416.htm」數組

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

翻譯原文:函數

Function.apply and Function.call in JavaScriptthis

第一段略。spa

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

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。code

咱們能夠經過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。

相關文章
相關標籤/搜索