JavaScript方法call,apply,caller,callee,bind的使用詳解及區別

weixin_34126215發表於2015-05-18

一、call 方法

呼叫一個物件的一個方法,以另一個物件替換當前物件(其實就是更改物件的內部指標,即改變物件的this指向的內容)。

即  “某個方法”當做“指定的某個物件”的“方法”被執行。

Js程式碼

call([thisObj[,arg1[, arg2[, [,.argN]]]]])

引數

thisObj

可選項。將被用作當前物件的物件。

arg1, arg2, , argN

可選項。將被傳遞方法引數序列。

說明

call 方法可以用來代替另一個物件呼叫一個方法。call 方法可將一個函式的物件上下文從初始的上下文改變為由 thisObj 指定的新物件。如果沒有提供 thisObj 引數,那麼 Global 物件被用作 thisObj。

舉例一:

01 <input type="text" id="myText" value="input text">
02 function Obj(){
03     this.value = "物件!";
04 }
05  
06 var value = "global 變數";
07  
08 function Fun1() {
09     alert(this.value);
10 }
11  
12 window.Fun1(); //global 變數
13 Fun1.call(window); //global 變數
14 Fun1.call(document.getElementById('myText')); //input text
15 Fun1.call(new Obj()); //物件!

舉例二:

01 var first_object = {
02     num: 42
03 };
04  
05 var second_object = {
06     num: 24
07 };
08  
09 function multiply(mult) {
10     return this.num * mult;
11 }
12  
13 multiply.call(first_object, 5); // returns 42 * 5
14 multiply.call(second_object, 5); // returns 24 * 5

 

二、apply方法

apply方法的第一個引數也是要傳入給當前物件的物件,即函式內部的this。後面的引數都是傳遞給當前物件的引數。

對於apply和call兩者在作用上是相同的,但兩者在引數上有區別的。對於第一個引數意義都一樣,但對第二個引數:apply傳入的是一個引數陣列,也就是將多個引數組合成為一個陣列傳入,而call則作為call的引數傳入(從第二個引數開始),如 func.call(func1,var1,var2,var3)對應的apply寫法為:func.apply(func1, [var1,var2,var3])。同時,使用apply的好處是可以直接將當前函式的 arguments物件 作為apply的第二個引數傳入

01 var func = new function() {
02     this.a = "func";
03 }
04  
05 var myfunc = function(x, y) {
06     var a = "myfunc";
07     alert(this.a);
08     alert(x + y);
09 }
10  
11 myfunc.call(func, "var""fun"); // "func" "var fun"
12 myfunc.apply(func, ["var""fun"]); // "func" "var fun"

三、caller 屬性

返回一個對函式的引用,即呼叫了當前函式的函式體。

functionName.caller :functionName 物件是所執行函式的名稱。

說明

對 於函式來說,caller 屬性只有在函式執行時才有定義。 如果函式是由 JScript 程式的頂層呼叫的,那麼 caller 包含的就是 null 。如果在字串上下文中使用 caller 屬性,那麼結果和 functionName.toString 一樣,也就是說,顯示的是函式的反編譯文字。

01 function CallLevel(){
02     if (CallLevel.caller == null) {
03         alert("CallLevel was called from the top level.");
04     else {
05         alert("CallLevel was called by another function:\n" + CallLevel.caller);
06     }
07 }
08  
09 function funCaller(){
10     CallLevel();
11 }
12  
13 CallLevel();
14 funCaller()

四、callee屬性

返回正被執行的 Function 物件,也就是所指定的 Function 物件的正文。

[function.]arguments.callee:可選項 function 引數是當前正在執行的 Function 物件的名稱。

說明

callee 屬性的初始值就是正被執行的 Function 物件。
callee 屬性是 arguments 物件的一個成員,它表示對函式物件本身的引用,這有利於匿 函式的遞迴或者保證函式的封裝性,例如下邊示例的遞迴計算1到n的自然數之和。而該屬性僅當相關函式正在執行時才可用。還有需要注意的是callee擁有length屬性,這個屬性有時用於驗證還是比較好的。arguments.length 是實參長度,arguments.callee.length 是形參長度,由此可以判斷呼叫時形參長度是否和實參長度一致。

01 // callee可以列印其本身
02 function calleeDemo() {
03     alert(arguments.callee);
04 }
05  
06 // 用於驗證引數
07 function calleeLengthDemo(arg1, arg2) {
08     if (arguments.length == arguments.callee.length) {
09         window.alert("驗證形參和實參長度正確!");
10         return;
11     else {
12         alert("實參長度:" + arguments.length);
13         alert("形參長度: " + arguments.callee.length);
14     }
15 }
16  
17 //遞迴計算
18 var sum = function(n){
19     if (n <= 0) {
20         return 1;
21     else {
22         return n + arguments.callee(n - 1);
23     }
24 }

五、bind

01 var first_object = {
02     num: 42
03 };
04  
05 var second_object = {
06     num: 24
07 };
08  
09 function multiply(mult) {
10     return this.num * mult;
11 }
12  
13 Function.prototype.bind = function(obj) {
14     var method = this,
15     temp = function() {
16         return method.apply(obj, arguments);
17     };
18  
19     return temp;
20 }
21  
22 var first_multiply = multiply.bind(first_object);
23 first_multiply(5); // returns 42 * 5
24  
25 var second_multiply = multiply.bind(second_object);
26 second_multiply(5); // returns 24 * 5

 

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++

 

caller 與 callee 區別的一些舉例:

 

01 <script type = 'text/javascript'>
02 function a() {
03     b();
04 }
05  
06 function b() {
07     alert(b === arguments.callee)
08     alert(b.caller === a)
09     alert(arguments.callee.caller === a)
10 }
11 a();
12  
13 </script>

//———-

01 <script type="text/javascript">
02 function calleeTest() {
03     arguments.callee.say("Mr.CT""您好!"); // 獲取當前函式控制程式碼
04 }
05  
06 calleeTest.say = function(userName, value) {
07     alert(userName + "說:" + value);
08 };
09  
10 function callerTest() {
11     (function() {
12         arguments.callee.caller.goodbye("Mr.CT""Canca Torvals"); // 獲取呼叫當前函式的函式
13     })();
14 }
15  
16 callerTest.goodbye = function(userName, userName2) {
17     alert(userName + " 向 " + userName2 + " 說再見.");
18 };
19  
20 calleeTest();
21 callerTest();
22 </script>

 

相關文章