call、apply、caller、callee使用方法

          一、call 方法
          調用一個對象的一個方法,以另一個對象替換當前對象(其實就是更改對象的內部指針,即改變對象的this指向的內容)。
          Js代碼
          call([thisObj[,arg1[, arg2[, [,.argN]]]]])
          參數
          thisObj
          可選項。將被用作當前對象的對象。
          arg1, arg2, , argN
          可選項。將被傳遞方法參數序列。
          說明
          call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。如果沒有提供 thisObj 參數,那么 Global 對象被用作 thisObj。
          Js代碼

          復制代碼 代碼如下:

          <input type="text" id="myText" value="input text"> Code
          function Obj(){this.value="對象!";}
          var value="global 變量";
          function Fun1(){alert(this.value);}
          window.Fun1(); //global 變量
          Fun1.call(window); //global 變量
          Fun1.call(document.getElementById('myText')); //input text
          Fun1.call(new Obj()); //對象!

          Js代碼
          Code
          復制代碼 代碼如下:

          var first_object = {
          num: 42
          };
          var second_object = {
          num: 24
          };
          function multiply(mult) {
          return this.num * mult;
          }
          multiply.call(first_object, 5); // returns 42 * 5
          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的第二個參數傳入。
          Js代碼
          復制代碼 代碼如下:

          var func=new function(){this.a="func"}
          var myfunc=function(x,y){
          var a="myfunc";
          alert(this.a);
          alert(x + y);
          }
          myfunc.call(func,"var"," fun");// "func" "var fun"
          myfunc.apply(func,["var"," fun"]);// "func" "var fun"

          三、caller 屬性
          返回一個對函數的引用,即調用了當前函數的函數體。
          functionName.caller :functionName 對象是所執行函數的名稱。
          說明:
          對于函數來說,caller 屬性只有在函數執行時才有定義。 如果函數是由 JScript 程序的頂層調用的,那么 caller 包含的就是 null 。如果在字符串上下文中使用 caller 屬性,那么結果和 functionName.toString 一樣,也就是說,顯示的是函數的反編譯文本。
          Js代碼
          復制代碼 代碼如下:

          function CallLevel(){
          if (CallLevel.caller == null)
          alert("CallLevel was called from the top level.");
          else
          alert("CallLevel was called by another function:\n"+CallLevel.caller);
          }
          function funCaller(){
          CallLevel();
          }
          CallLevel();
          funCaller()

          四、callee屬性
          返回正被執行的 Function 對象,也就是所指定的 Function 對象的正文。
          [function.]arguments.callee:可選項 function 參數是當前正在執行的 Function 對象的名稱。
          說明:
          callee 屬性的初始值就是正被執行的 Function 對象。
          callee 屬性是 arguments 對象的一個成員,它表示對函數對象本身的引用,這有利于匿
          函數的遞歸或者保證函數的封裝性,例如下邊示例的遞歸計算1到n的自然數之和。而該屬性
          僅當相關函數正在執行時才可用。還有需要注意的是callee擁有length屬性,這個屬性有時
          用于驗證還是比較好的。arguments.length是實參長度,arguments.callee.length是
          形參長度,由此可以判斷調用時形參長度是否和實參長度一致。
          Js代碼
          復制代碼 代碼如下:

          //callee可以打印其本身
          function calleeDemo() {
          alert(arguments.callee);
          }
          //用于驗證參數
          function calleeLengthDemo(arg1, arg2) {
          if (arguments.length==arguments.callee.length) {
          window.alert("驗證形參和實參長度正確!");
          return;
          } else {
          alert("實參長度:" +arguments.length);
          alert("形參長度: " +arguments.callee.length);
          }
          }
          //遞歸計算
          var sum = function(n){
          if (n <= 0)
          return 1;
          else
          return n +arguments.callee(n - 1)
          }

          五、bind
          Js代碼
          復制代碼 代碼如下:

          var first_object = {
          num: 42
          };
          var second_object = {
          num: 24
          };
          function multiply(mult) {
          return this.num * mult;
          }
          Function.prototype.bind = function(obj) {
          var method = this,
          temp = function() {
          return method.apply(obj, arguments);
          };
          return temp;
          }
          var first_multiply = multiply.bind(first_object);
          first_multiply(5); // returns 42 * 5
          var second_multiply = multiply.bind(second_object);
          second_multiply(5); // returns 24 * 5

          六、JS閉包(Closure)
          所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
          關于閉包,最簡單的描述就是 ECMAScript 允許使用內部函數--即函數定義和函數表達式位于另一個函數的函數體內。而且,這些內部函數可以訪問它們所在的外部函數中聲明的所有局部變量、參數和聲明的其他內部函數。當其中一個這樣的內部函數在包含它們的外部函數之外被調用時,就會形成閉包。也就是說,內部函數會在外部函數返回后被執行。而當這個內部函數執行時,它仍然必需訪問其外部函數的局部變量、參數以及其他內部函數。這些局部變量、參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影響。
          簡而言之,閉包的作用就是在out function執行完并返回后,閉包使得Javascript的垃圾回收機制GC不會收回out function所占用的資源,因為out function的內部函數inner function的執行需要依賴out function中的變量。
          閉包的兩個特點:
          1、作為一個函數變量的一個引用 - 當函數返回時,其處于激活狀態。
          2、一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。
          例1:
          Html代碼
          復制代碼 代碼如下:

          <script type="text/javascript">
          function setupSomeGlobals() {
          // Local variable that ends up within closure
          var num = 666;
          // Store some references to functions as global variables
          gAlertNumber = function() { alert(num); }
          gIncreaseNumber = function() { num++; }
          gSetNumber = function(x) { num = x; }
          }
          </script>
          <button onclick="setupSomeGlobals()">生成 - setupSomeGlobals()</button>
          <button onclick="gAlertNumber()">輸出值 - gAlertNumber()</button>
          <button onclick="gIncreaseNumber()">增加 - gIncreaseNumber()</button>
          <button onclick="gSetNumber(5)">賦值5 - gSetNumber(5)</button>

          例2:
          Html代碼
          復制代碼 代碼如下:

          <script type="text/javascript">
          function newClosure(someNum, someRef) {
          // Local variables that end up within closure
          var num = someNum;
          var anArray = [1,2,3];
          var ref = someRef;
          return function(x) {
          num += x;
          anArray.push(num);
          alert('num: ' + num +
          ' nanArray ' + anArray.toString() +
          ' nref.someVar ' + ref.someVar);
          }
          }
          var closure1 = newClosure(40, {someVar:' never-online'})
          var closure2 = newClosure(99, {someVar:' BlueDestiny'})
          closure1(4)
          closure2(3)
          </script>

          例3:
          Js代碼
          復制代碼 代碼如下:

          <script language="javascript">
          /* 聲明一個全局變量 - getImgInPositionedDivHtml - 并將一次調用一個外部函數表達式返回的內部函數賦給它。
          這個內部函數會返回一個用于表示絕對定位的 DIV 元素包圍著一個 IMG 元素 的 HTML 字符串,這樣一來,
          所有可變的屬性值都由調用該函數時的參數提供:
          */
          var getImgInPositionedDivHtml = (function(){
          /* 外部函數表達式的局部變量 - buffAr - 保存著緩沖數組。這個數組只會被創建一次,生成的數組實例對內部函數而言永遠是可用的
          因此,可供每次調用這個內部函數時使用。
          其中的空字符串用作數據占位符,相應的數據
          將由內部函數插入到這個數組中:
          */
          var buffAr = [
          '<div id="',
          '', //index 1, DIV ID 屬性
          '" style="position:absolute;top:',
          '', //index 3, DIV 頂部位置
          'px;left:',
          '', //index 5, DIV 左端位置
          'px;width:',
          '', //index 7, DIV 寬度
          'px;height:',
          '', //index 9, DIV 高度
          'px;overflow:hidden;\"><img src=\"',
          '', //index 11, IMG URL
          '\" width=\"',
          '', //index 13, IMG 寬度
          '\" height=\"',
          '', //index 15, IMG 調蓄
          '\" alt=\"',
          '', //index 17, IMG alt 文本內容
          '\"><\/div>'
          ];
          /* 返回作為對函數表達式求值后結果的內部函數對象。
          這個內部函數就是每次調用執行的函數
          - getImgInPositionedDivHtml( ... ) -
          */
          return (function(url, id, width, height, top, left, altText){
          /* 將不同的參數插入到緩沖數組相應的位置:
          */
          buffAr[1] = id;
          buffAr[3] = top;
          buffAr[5] = left;
          buffAr[13] = (buffAr[7] = width);
          buffAr[15] = (buffAr[9] = height);
          buffAr[11] = url;
          buffAr[17] = altText;
          /* 返回通過使用空字符串(相當于將數組元素連接起來)
          連接數組每個元素后形成的字符串:
          */
          return buffAr.join('');
          }); //:內部函數表達式結束。
          })();//自調用
          alert(getImgInPositionedDivHtml);//顯示返回的函數
          alert(getImgInPositionedDivHtml("img.gif","img",100,50,0,0,"Test"));
          </script>

          說明:其中的關鍵技巧在于通過執行一個單行(in-line)函數表達式創建一個額外的執行環境,而將該函數表達式返回的內部函數作為在外部代碼中使用的函數。此時,緩沖數組被定義為函數表達式的一個局部變量。這個函數表達式只需執行一次,而數組也只需創建一次,就可以供依賴它的函數重復使用。
          七、原型鏈
          ECMAScript 為 Object 類型定義了一個內部 [[prototype]] 屬性。這個屬性不能通過腳本直接訪問,但在屬性訪問器解析過程中,則需要用到這個內部[[prototype]] 屬性所引用的對象鏈--即原型鏈。可以通過一個公共的 prototype 屬性,來對與內部的 [[prototype]] 屬性對應的原型對象進行賦值或定義。
          例1:
          <script language="javascript">
          function NumObject(formalParameter){
          this.testNumber = formalParameter;
          }
          function StrObject(formalParameter){
          this.testString = formalParameter;
          }
          //用 NumObject類的實例替換了所有與 StrObject類的實例相關聯的原型。
          StrObject.prototype =new NumObject(6);
          var objRef = new StrObject( "String_Value" );
          //當某個屬性訪問器嘗試讀取由 objectRef 所引用的對象的屬性值時,整個原型鏈都會被搜索。
          //不論是在對象或對象的原型中,讀取命名屬性值的時候只返回首先找到的屬性值。而當為對象的命名屬性賦值時,如果對象自身不存在該屬性則創建相應的屬性。
          alert(objRef.testString);//output "String_Value"
          alert(objRef.testNumber);//output "6"
          alert(objRef.toString);
          //StrObject 的實例擁有一個原型鏈。該鏈中的第一個對象是在創建后被指定給 StrObject 構造函數的 prototype 屬性的 NumObject 的一個實例。NumObject 的實例也有一個原型,即與 Object.prototype 所引用的對象對應的默認的 Object 對象的原型。最后, Object.prototype 有一個值為 null 的原型,因此這條原型鏈到此結束。
          objRef.testNumber = 3;//對象自身不存在該屬性則創建相應的屬性
          alert(objRef.testNumber);//自身有了屬性,屬性訪問器不會再進一步搜索原型鏈
          alert(NumObject.prototype.isPrototypeOf(objRef));// output "true"
          </script>

          posted on 2010-06-22 17:06 飛熊 閱讀(281) 評論(0)  編輯  收藏 所屬分類: javaScript

          <2010年6月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 象山县| 景泰县| 宿迁市| 介休市| 右玉县| 花垣县| 彩票| 海安县| 孝义市| 广东省| 玉田县| 玉树县| 安溪县| 岑巩县| 芦山县| 武川县| 昆山市| 蓝山县| 宣恩县| 调兵山市| 昭苏县| 桃园县| 诸城市| 江门市| 霍城县| 德庆县| 温州市| 阿克苏市| 安远县| 阿尔山市| 富宁县| 永济市| 南靖县| 双流县| 长春市| 邻水| 武宁县| 清徐县| 金秀| 泰宁县| 南澳县|