javascript中apply方法和call方法的作用以及prototype.js中的應用

來源:互聯網
上載者:User

說明白一點其實就是更改對象的內部指標,即改變對象的this指向的內容。這在物件導向的js編程過程中有時是很有用的。

call函數和apply方法的第一個參數都是要傳入給當前對象的對象,及函數內部的this。後面的參數都是傳遞給當前對象的參數。

對於apply和call兩者在作用上是相同的,但兩者在參數上有區別的。
對於第一個參數意義都一樣,但對第二個參數:
apply傳入的是一個參數數組,也就是將多個參數組合成為一個數組傳入,而call則作為call的參數傳入(從第二個參數開始)。
如 func.call(func1,var1,var2,var3)對應的apply寫法為:func.apply(func1,[var1,var2,var3])

同時使用apply的好處是可以直接將當前函數的arguments對象作為apply的第二個參數傳入。

(reference:http://www.cnblogs.com/beyondnet/archive/2007/12/06/985216.html)

TEST:

function cls1()
{
   this.b='111';
   this.c ='222';
   this.d ='333';
   this.f = function()
   {
       alert("nihao");
}
}

function cls2()
{
   this.a='aaa';
  
   cls1.apply(this); //這裡用的是類(也可直接看成函數)直接來apply的。不是用執行個體。此時,cls2類擁有                                cls1類的所有屬性和方法.
  
}
var st = new cls2();

alert(st.d);

/*注意,這裡可以在第2個類中,用第一個類的名稱來實現所有屬性和方法的複製。方法可以用如下方法複製:ss.f.apply(this);可以正常運行。而屬性ss.c.apply(this);則會報錯,

function cls2()
{
   this.a='aaa';
   var ss = new cls1;
   ss.c.apply(this); //這裡會報錯。如果為ss.f.apply(this);則正確。如果是屬性,則用類名,如果是方法,即                                     可用類名,也可用執行個體加方法的形式應該(var ss = new cls1;ss.f.apply(this);)

如下形式(***正確****)。
  
}
var st = new cls2();

alert(st.c);

****正確*******
function cls2()
{
   this.a='aaa';
  
   cls1.apply(this); //如果是屬性,則用類名,如果是方法,即可用類名,也可用執行個體加方法的形式

}

var st = new cls2();

alert(st.c);

_______________________________________________

function simpleApplyDemo(sim) {
this.sim_name = sim;
}
function handleSPA(hand) {
    this.hand_name = hand ;
simpleApplyDemo.apply(this, new Array('222222222222'));   //這裡用的是類名

////此處用Array()數組,是將這個數組的初始化值賦給simpleApplyDemo函數中的參數。也就是sim = 222222222222,在JS手冊中,apply([thisObj[,argArray]])的argArra是可選項,解釋為將被傳遞給該函數的參數數組。(也就是說argArray同下的arguments是一樣的)

alert(this.sim_name);
}                     

handleSPA();

上面的方法和下面的方法實現的效果一樣

function simpleApplyDemo(sim) {
this.sim_name = sim;
}
function handleSPA(hand) {
    this.hand_name = hand ;
simpleApplyDemo.apply(this,arguments);   //這裡用的是類名

/* 此處用arguments,是將handleSPA('55555555')中5555555作為arguments(arguments代表本身的參數的集合,此處只代表5555555)將arguments傳到simpleApplyDemo()中,也就是sim = arguments =55555 */

alert(this.sim_name);
}                     

handleSPA('55555555');

call方法在msdn中的解釋   調用一個對象的一個方法,以另一個對象替換當前對象。

apply方法在msdn中的解釋 應用某一對象的一個方法,用另一個對象替換當前對象。

這個解釋也是非常抽象的,這兩個方法的作用基本是一樣的,舉個例子

<script>
function cls1()
{
   this.a='123';
}
cls1.prototype.fun1=function()
{
   alert(this.a);
}
function cls2()
{
   this.a='456';
}
var o1=new cls1();
var o2=new cls2();
o1.fun1.apply(o2); //這裡用的是執行個體名,如果寫成 o1.apply(o2)則報錯
</script>

只有o1對象的類cls1中有fun1這個方法,但是,這時我們需要用o2對象替代o1對象,所以這個時候顯示的this.a會是456,呵呵很神奇吧,換成call方法也是一樣的,這兩種方法使用的不同點僅僅是參數的使用方法上不同,這裡就不多做解釋了。

大家可以在prototype.js裡看到
var Class = {
   create: function() {
     return function() {
       this.initialize.apply(this, arguments);
     }
   }
}
這種代碼,相當的誇張,很多人很容易被這種bt的代碼弄糊塗,其實仔細分析其中的道理卻也不難

顯然這種寫法代表了Class是聲明的一個Object對象,其中create是這個object對象的一個屬性,這個屬性就是一個函數。這個函數執行過後返還一個函數。可能這樣解釋太複雜了,那不如做一個實驗好了。

<script>
var x=function(){return function(){alert(123);}}
var n=x();
n();
</script>
很好玩吧,這裡n就是x函數執行過後返還給的一個函數也就是n現在等於了function(){alert(123);}再執行n()的時候就跳出了123

現在開始講痛點 this.initialize.apply(this, arguments);

這句表達了什麼含義,其實現在先看看prototype.js裡怎麼調用的就明白了

var Template = Class.create();

Template.prototype = {
   initialize: function(template, pattern) {
     this.template = template.toString();
     this.pattern   = pattern || Template.Pattern;
   },....省略代碼若干

var template = new Template(replacement);

第一句話Class.create(); 就是返還給Template 一個函數,這個函數是
function() {
       this.initialize.apply(this, arguments);
     }
當執行var template = new Template(replacement);時,就變成了要執行這個函數,而這個函數的作用是
執行當前類中initialize這個函數

所以prototype.js中的每一個類都預留了
Template.prototype = {
   initialize: function(template, pattern) {
     this.template = template.toString();
     this.pattern   = pattern || Template.Pattern;
   },....
這麼個函數,如果沒有這個的話,程式將會出錯

知其然,知其所以然,為什麼要這麼寫呢?

一般我們聲明的時候funciton fun(){} var o=new fun();這樣感覺fun又是類又是建構函式很彆扭,為了分開這種不是很友好的代碼方案,所以prototype.js使用了如上方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.