国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

js中call與apply的用法小結(jié)

2019-11-20 21:21:25
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前天去面試,有個(gè)gg問(wèn)了一些js知識(shí),其中有一道call與apply用法的題目,盡管在365天前用過(guò)call方法,但當(dāng)時(shí)還是沒(méi)能答上來(lái),今天深入總結(jié)一下

call和apply,它們的作用都是將函數(shù)綁定到另外一個(gè)對(duì)象上去運(yùn)行

兩者的格式和參數(shù)定義:

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

上面兩個(gè)函數(shù)內(nèi)部的this指針,都會(huì)被賦值為thisArg,這可實(shí)現(xiàn)將函數(shù)作為另外一個(gè)對(duì)象的方法運(yùn)行的目的

一、call 的簡(jiǎn)單用法

首先,我們先看個(gè)簡(jiǎn)單的例子(call):

復(fù)制代碼 代碼如下:

<!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>


然后,運(yùn)行結(jié)果如下:

global var
global var
member var
input text
func
func2

測(cè)試環(huán)境:Google Chrome 10.0.648.45

最后,分析結(jié)果

1、全局對(duì)象window調(diào)用函數(shù)gFunc,this指向window對(duì)象,因此this.value為global var

2、函數(shù)gFunc調(diào)用call方法,this默認(rèn)指向第一個(gè)參數(shù)window對(duì)象,因此this.value也為global var

3、函數(shù)gFunc調(diào)用call方法,this默認(rèn)指向第一個(gè)參數(shù)new mFunc(),即mFunc的對(duì)象,因此this.value為mFunc的成員變量member var

4、函數(shù)gFunc調(diào)用call方法,this默認(rèn)指向第一個(gè)參數(shù)input text控件,即id=‘idTxt'的控件,因此this.value為input控件的value值input text

5、函數(shù)func2調(diào)用call方法,this默認(rèn)指向第一個(gè)參數(shù)func函數(shù)對(duì)象,因此this.value為this.a,即func

6、函數(shù)func2調(diào)用call方法,第二個(gè)參數(shù)屬于函數(shù)對(duì)象func2的參數(shù),因此alert(x)為第二個(gè)參數(shù)func2


二、call 繼承用法與改進(jìn)

js使用call模擬繼承

測(cè)試代碼:

復(fù)制代碼 代碼如下:

<!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>

運(yùn)行結(jié)果如下:

baseB member
baseB member

測(cè)試環(huán)境:Google Chrome 10.0.648.45

結(jié)果分析:

預(yù)期的結(jié)果,應(yīng)該是輸出 baseA member 和 baseB member,但實(shí)際輸出卻是 baseB member 和 baseB member

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

至此,機(jī)器是不會(huì)錯(cuò)的,這就需要我們深入分析

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

為了探究實(shí)質(zhì),我們借助chrome瀏覽器的調(diào)試工具,下斷點(diǎn),進(jìn)行調(diào)試,結(jié)果發(fā)現(xiàn):


當(dāng)調(diào)用extend.showSelfA();時(shí),此時(shí)的this指向extendAB(并不是我們推測(cè)的兩次都指向baseB對(duì)象

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

當(dāng)然,我們也可以對(duì)上面baseA代碼稍作修改,來(lái)驗(yàn)證我們調(diào)試分析的正確性:

復(fù)制代碼 代碼如下:

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

再次運(yùn)行chrome等瀏覽器,結(jié)果如下:

baseA  member
baseB member

結(jié)果和我們的預(yù)期相同,同時(shí)chrome調(diào)試信息也驗(yàn)證了我們的正確性:

繼承改進(jìn)(prototype)

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

因?yàn)槊看卧诤瘮?shù)(類(lèi))中定義了成員方法,都會(huì)導(dǎo)致實(shí)例有副本,因此可以借助prototype原型,進(jìn)行改進(jìn)

改進(jìn)舉例如下:

復(fù)制代碼 代碼如下:

<!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>


運(yùn)行結(jié)果如下:
obj: man and women

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 固原市| 华宁县| 汉中市| 阳朔县| 北碚区| 金湖县| 宣武区| 施秉县| 巴彦淖尔市| 静海县| 定远县| 五指山市| 专栏| 民和| 金溪县| 海南省| 宝丰县| 武冈市| 嘉祥县| 体育| 辉南县| 大名县| 全南县| 勃利县| 三明市| 子洲县| 区。| 若羌县| 黄石市| 横峰县| 肥东县| 墨竹工卡县| 专栏| 石河子市| 康平县| 台北市| 武鸣县| 万全县| 崇州市| 玉田县| 淮滨县|