亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

js中call與apply的用法小結

2019-11-20 21:21:25
字體:
來源:轉載
供稿:網友

前天去面試,有個gg問了一些js知識,其中有一道call與apply用法的題目,盡管在365天前用過call方法,但當時還是沒能答上來,今天深入總結一下

call和apply,它們的作用都是將函數綁定到另外一個對象上去運行

兩者的格式和參數定義:

call( thisArg [,arg1,arg2,… ] );       // 參數列表,arg1,arg2,...
apply(thisArg [,argArray] );                 // 參數數組,argArray

上面兩個函數內部的this指針,都會被賦值為thisArg,這可實現將函數作為另外一個對象的方法運行的目的

一、call 的簡單用法

首先,我們先看個簡單的例子(call):

復制代碼 代碼如下:

<!doctype html>

<html>
 <head>
  <title> call-apply </title>
 </head>

 <body>
  <input type="text" id="idTxt" value="input text">

  <script type="text/javascript">
   var value = "global var";

   function mFunc()
   {
    this.value = "member var";
   }

   function gFunc()
   {
    alert(this.value);
   }  

   window.gFunc();         // show gFunc, global var
   gFunc.call(window);        // show gFunc, global var
   gFunc.call(new mFunc());      // show mFunc, member var
   gFunc.call(document.getElementById('idTxt')); // show element, input text
  </script>

  <script language="javascript">
   var func = new function()
   {
    this.a = "func";
   }

   var func2 = function(x)
   {
    var a = "func2";
    alert(this.a);    
    alert(x);
   }

   func2.call(func, "func2");      // show func and func2
  </script>
 </body>
</html>


然后,運行結果如下:

global var
global var
member var
input text
func
func2

測試環境:Google Chrome 10.0.648.45

最后,分析結果

1、全局對象window調用函數gFunc,this指向window對象,因此this.value為global var

2、函數gFunc調用call方法,this默認指向第一個參數window對象,因此this.value也為global var

3、函數gFunc調用call方法,this默認指向第一個參數new mFunc(),即mFunc的對象,因此this.value為mFunc的成員變量member var

4、函數gFunc調用call方法,this默認指向第一個參數input text控件,即id=‘idTxt'的控件,因此this.value為input控件的value值input text

5、函數func2調用call方法,this默認指向第一個參數func函數對象,因此this.value為this.a,即func

6、函數func2調用call方法,第二個參數屬于函數對象func2的參數,因此alert(x)為第二個參數func2


二、call 繼承用法與改進

js使用call模擬繼承

測試代碼:

復制代碼 代碼如下:

<!doctype html>

<html>
 <head>
  <title> call - apply for inherit </title>
 </head>

 <body>
  <script type="text/javascript">
   function baseA()  // base Class A
   {
    this.member = "baseA member";
    this.showSelfA = function()
    {
     window.alert(this.member);
    }
   }

   function baseB()  // base Class B
   {
    this.member = "baseB member";
    this.showSelfB = function()
    {
     window.alert(this.member);
    }
   }

   function extendAB()  // Inherit Class from A and B
   {
    baseA.call(this); // call for A
    baseB.call(this); // call for B
   }

   window.onload = function()
   {
    var extend = new extendAB(); 
    extend.showSelfA();  // show A
    extend.showSelfB();  // show B
   }
  </script>
 </body>
</html>

運行結果如下:

baseB member
baseB member

測試環境:Google Chrome 10.0.648.45

結果分析:

預期的結果,應該是輸出 baseA member 和 baseB member,但實際輸出卻是 baseB member 和 baseB member

(已在IE9、8、6,Maxthon、Chrome、FF、Opera、Safari、360等瀏覽器測試過,結果都是后者:baseB member)

至此,機器是不會錯的,這就需要我們深入分析

我們可能會很容易想到是this引起的,this兩次都指向了baseB對象,但是推測真是這樣嗎?

為了探究實質,我們借助chrome瀏覽器的調試工具,下斷點,進行調試,結果發現:


當調用extend.showSelfA();時,此時的this指向extendAB(并不是我們推測的兩次都指向baseB對象

真實原因是extendAB對象的成員變量member在被baseB.call(this);實例化時,被baseB的成員member覆蓋了,即extendAB的成員member由baseA member賦值成了baseB member

當然,我們也可以對上面baseA代碼稍作修改,來驗證我們調試分析的正確性:

復制代碼 代碼如下:

function baseA()  // base Class A
{
 this.memberA = "baseA member";   // member改成memberA,以區分baseB中的member
 this.showSelfA = function()
 {
  window.alert(this.memberA);    // 顯示memberA
 }
}

再次運行chrome等瀏覽器,結果如下:

baseA  member
baseB member

結果和我們的預期相同,同時chrome調試信息也驗證了我們的正確性:

繼承改進(prototype)

以上模擬繼承方法,仔細分析不是最好的。

因為每次在函數(類)中定義了成員方法,都會導致實例有副本,因此可以借助prototype原型,進行改進

改進舉例如下:

復制代碼 代碼如下:

<!doctype html>

<html>
 <head>
  <title> call - apply for prototype </title>
 </head>

 <body>
  <script type="text/javascript">
   var Class = {
    create: function()    // create Function
    {
     return function()
     {
      this.initialize.apply(this, arguments);
     }
    }
   };

   var Person = Class.create();  // Create Class Person
   Person.prototype = {    // prototype initialize
    initialize: function(obj1, obj2)
    {
     this.obj1 = obj1;
     this.obj2 = obj2;
    },
    showSelf: function()
    {
     alert("obj: " + this.obj1 + " and " + this.obj2);
    }
   }

   // instance Class
   var person = new Person("man", "women"); // two params
   person.showSelf();       // show person
  </script>
 </body>
</html>


運行結果如下:
obj: man and women

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品av在线| 日本在线观看天堂男亚洲| 亚洲综合色av| 91免费版网站入口| 亚洲人成在线电影| 亚洲美女免费精品视频在线观看| 亚洲精品动漫100p| www.欧美精品一二三区| 亚洲一区亚洲二区亚洲三区| 在线视频中文亚洲| 欧美精品videos另类日本| 久久久免费观看视频| 欧美老妇交乱视频| 欧美最顶级的aⅴ艳星| 欧美成人国产va精品日本一级| 久久久久国产精品免费网站| 日韩国产高清视频在线| 欧美一级片久久久久久久| 91伊人影院在线播放| 国产福利精品在线| 欧美激情综合色综合啪啪五月| 伊人青青综合网站| 亚洲国产精品大全| 亚洲欧美激情四射在线日| 一区二区三区视频在线| 一区二区三区四区精品| 亚洲国产精品久久久久| 欧美野外猛男的大粗鳮| 亚洲男人天堂九九视频| 国产亚洲视频在线| 久久中文字幕在线视频| 欧美精品性视频| 久久色精品视频| 国产精品狠色婷| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美日韩一区二区在线播放| 亚洲日韩欧美视频一区| 黑人精品xxx一区| 久久久久日韩精品久久久男男| 国产成人精品视频在线观看| 日韩性生活视频| 亚洲第一男人av| 亚洲视屏在线播放| 伊人av综合网| 精品美女久久久久久免费| 久久精品国产99国产精品澳门| 国产精品视频一| 国产精品69久久久久| 日韩精品黄色网| 法国裸体一区二区| 亚洲国产精品人人爽夜夜爽| 亚洲精品国精品久久99热| 日韩电影免费在线观看中文字幕| 欧洲美女免费图片一区| 色噜噜狠狠狠综合曰曰曰88av| 国产精品美乳一区二区免费| 亚洲日韩中文字幕| 亚洲精品mp4| 国产精品99久久久久久久久久久久| 一区二区三区回区在观看免费视频| 欧美高清视频在线观看| 欧洲成人性视频| 国产精品6699| 91性高湖久久久久久久久_久久99| 中文字幕在线观看日韩| 亚洲成人网在线观看| 亚洲mm色国产网站| 国产成人jvid在线播放| 日本成人免费在线| 欧美成人一区二区三区电影| 4444欧美成人kkkk| 国产精品一区久久久| 国产精品吹潮在线观看| 在线看国产精品| 国产91精品在线播放| 国产欧美在线看| 亚洲第一二三四五区| 国产精品一区二区久久久| 国产午夜精品一区二区三区| 国产主播喷水一区二区| 中文日韩在线观看| 亚洲女同性videos| 精品国产依人香蕉在线精品| 最近的2019中文字幕免费一页| 亚洲欧美日韩国产中文| 亚洲成av人影院在线观看| 国产成人jvid在线播放| 国产一区二区三区直播精品电影| 欧美日韩中文字幕在线| 欧美亚洲视频在线观看| 26uuu国产精品视频| 成人午夜在线影院| 亚洲综合成人婷婷小说| 日韩成人激情在线| 97精品国产97久久久久久| 国产综合久久久久久| 欧美精品久久久久久久免费观看| 欧美日韩亚洲精品内裤| 一区二区三区在线播放欧美| 精品免费在线观看| 精品视频偷偷看在线观看| 91欧美激情另类亚洲| 亚洲男女性事视频| 91日韩在线播放| 这里只有精品久久| 最近2019免费中文字幕视频三| 国产精品美女午夜av| 欧美小视频在线| 亚洲天堂av网| 欧美电影免费观看| 国产亚洲精品久久久久动| 日韩精品久久久久久福利| 亚洲天堂av在线免费观看| 亚洲欧美精品suv| 亚洲视频在线免费观看| 久久久免费高清电视剧观看| 黑人巨大精品欧美一区二区| 91麻豆桃色免费看| 精品成人69xx.xyz| 国产精品免费在线免费| 亚洲一区www| 黑人精品xxx一区| 亚洲国模精品一区| 久久资源免费视频| 亚洲伦理中文字幕| 欧美精品日韩三级| 欧美主播福利视频| 一区二区三区在线播放欧美| 中文精品99久久国产香蕉| 亚洲精品一区二区在线| 国产日韩换脸av一区在线观看| 久久亚洲成人精品| 亚洲午夜女主播在线直播| 俺也去精品视频在线观看| 亚洲国产日韩欧美在线动漫| 91精品国产综合久久男男| 亚洲一区中文字幕| 亚洲最大的免费| 亚洲精品美女在线观看播放| 成人黄色av免费在线观看| 国产免费一区二区三区在线能观看| 欧美日韩国产中字| 日韩欧美国产成人| …久久精品99久久香蕉国产| 国产不卡视频在线| 91久久夜色精品国产网站| 欧美性猛交xxxx黑人| 国产一区二区三区欧美| 欧美激情一区二区三区高清视频| 久久这里有精品| 中文字幕欧美国内| 精品国产一区二区三区在线观看| 国产精品视频大全| 欧美日韩另类视频| 亚洲精品在线看| 国产日韩一区在线| 91精品在线一区| 欧美国产日韩中文字幕在线| 日韩激情av在线播放| 亚洲激情电影中文字幕| 成人国产精品日本在线| 在线观看日韩欧美| 亚洲欧美制服第一页| 国色天香2019中文字幕在线观看|