首頁  >  文章  >  web前端  >  JavaScript中的apply和call函數詳解_jquery

JavaScript中的apply和call函數詳解_jquery

WBOY
WBOY原創
2016-05-16 16:41:43849瀏覽

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

翻譯原文:

Function.apply and Function.call in JavaScript

第一段略。

每個JavaScript函數都會有很多附屬的(attached)方法,包括toString()、call()以及apply()。聽起來,你是否會感到奇怪,一個函數可能會有屬於它自己的方法,但是記住,JavaScript中的每個函數都是一個物件。看一下 這篇文章 ,複習一下(refresher)JavaScript特性。你可能也想知道JavaScript中函數和方法的差異。我認為「函數」和「方法」的描述,只是JavaScript的習慣約定而已。函數立足於它們自己(例如:alert()),而方法是函數內部一個物件的屬性(dictionary),我們透過物件來呼叫方法。每個JavaScript物件都有一個toString()方法,以下透過程式碼舉例說明,在一個函數物件中,我們可以使用toString()方法。

function foo(){
 alert('x');
}
alert(foo.toString());

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

我們從下面的程式碼開始:

var x = 10;
function f(){
 alert(this.x);
}
f();

我們定義了一個全域函數f()。 f()透過this關鍵字存取變數x,但是需要注意的是,我們不能透過一個物件的實例來呼叫這個函數。 this指向的是什麼物件呢? this會指向這個全域物件。我們的變數x就是在這個全域物件中定義的。上面的程式碼能夠正常運作,運行結果會顯示一個對話框,對話框中顯示10。

我們可以透過this來呼叫call()和apply()。如以下的範例顯示如何使用call():

var x = 10;
var o = { x : 15};
function f(){
 alert(this.x);
}
f();
f.call(o);

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

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

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

var x = 10;
var o = { x : 15};
function f(){
 alert(this.x);
}
f();
f.call(o);

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

var x = 10;
var o = {x : 15};
function f(message) {
 alert(message);
 alert(this.x);
}
f('invoking f');
f.apply(o, ['invoking f through apply']);

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

var o = {x : 15};
function f1(message1) {
 alert(message1 + this.x);
}
function f2(message1, message2) {
 alert(message1 + (this.x * this.x) + message2);
}
function g(object, func, args) {
 func.apply(object, args);
}
g(o, f1, ['the value of x = ']);
g(o, f2, ['the value of x squared = ', '. Wow!']);

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

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

function f(message) {
 alert(message);
}
f('H', 'e', 'l', 'l', 'o');

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

function f(message) {
 // message的值和arguments[0]是一样的
 for(var i = 1; i < arguments.length; i++){
  message += arguments[i];
 }
 alert(message);
}
// 结果显示“Hello”
f('H', 'e', 'l', 'l', 'o');

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

var o = {x : 15};
function f(message1, message2) {
 alert(message1 + ( this.x * this.x) + message2);
}
function g(object, func) {
 // arguments[0] = object
 // arguments[1] = func
 var args = [];
 for(var i = 2; i < arguments.length; i++) {
  args.push(arguments[i]);
 }
 func.apply(object, args);
}
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。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn