欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
js再論call和apply

因為繼續研究Ajax Framework的原因,更多的接觸了call和apply。
故再次論述call和apply,
1)無(wú)疑關(guān)于call,最簡(jiǎn)單的解釋就是:把隱藏的第一個(gè)參數顯示化。因為通常一個(gè)函數(Function)的調用,會(huì )有一個(gè)額外的隱藏參數,就是函數(Function)所屬的對象(如果沒(méi)有所特指,則為global(如window)對象),在函數內你可用this關(guān)鍵字訪(fǎng)問(wèn)之。
從call的構造式 -- call(thisArg[,arg1,arg2…] ]);可看出
call(apply)方法可將一個(gè)函數的對象上下文(Function Context)從初始的上下文改變?yōu)橛?thisObj 指定的新對象,這就是利用call(apply)的最大優(yōu)勢。說(shuō)到此,我們不妨提提所謂的Function Context到底是為何物。先看看下面FunctionContextDemo:

var changed=item:"banana"act: "eating" };
var original={
        item: 
"chair",
        act: 
"sitting in",
        ask: 
function(){
              
return "who's been "+this.act+" my "+this.item;
        }
};
alert(
"Original " + original.ask());
alert(
"Not so simple,that have been changed to: " + original.ask.call(changed));

解析上述代碼:
最初存在2個(gè)對象changed和original,changed即就是一個(gè)數組,分別有item和act屬性,而original除了具有和changed一樣的item和act屬性,還具有一個(gè)ask函數(詢(xún)問(wèn)到底是誰(shuí)坐在椅子上),故當調用original.ask()時(shí),可以看到意料中的結果:who's been sitting in my chair.而仔細往下看,當我們調用original.ask.call(changed)時(shí),你覺(jué)得會(huì )出現什么的結果呢?在此,是利用了call把original的方法(函數)ask給與changed對象來(lái)執行,原來(lái)changed是沒(méi)有ask方法(函數),如此綁定之后,函數的對象上下文(Function Context)即就是changed對象,故在方法(函數)ask里所調用的this就應該是changed對象,則可推知original.ask.call(changed)的結果應該是:who's been eating my banana.

通過(guò)FunctionContextdemo例子可看出如果我們需要在編程過(guò)程中需要替換函數的對象上下文(Function Context),call就是不錯的選擇。
你可以試著(zhù)把FunctionContextdemo例子修改如下,再看看是什么結果:
var changed={ item:"banana", act: "eating" };
var original={item: "chair",act: "sitting in"};
function ask(){
   return "who's been "+this.act+" my "+this.item;
}
alert("Original : " + ask.call(original));
alert("changed: " + ask.call(changed));

2)javascript如何利用call來(lái)模擬面向對象中的繼承的,而且可以實(shí)現多重繼承

// 多重繼承
function base1() {
    
this.member = " base1_Member";
    
this.showSelf = function() {
        window.alert(
this.member);
    }
}
function base2() {
    
this.person = " base2_Member";
 
this.act = " is dancing happily";
    
this.showAction = function() {
        window.alert(
this.person + this.act);
    }
}
function extend() {
    base1.call(
this);
    base2.call(
this);
}
window.onload
=function(){
   
var demo = new extend();
   demo.showSelf();
   demo.showAction();
}

但仔細深入看看,這樣的繼承是有問(wèn)題的,直接在類(lèi)函數體里面定義成員方法,將導致每個(gè)實(shí)例都有副本,重復占用了內存。
最為優(yōu)雅簡(jiǎn)潔的方式應該算是基于原型(prototype)繼承。
3)接下來(lái)我們再次來(lái)看看javascript框架prototype里是如何利用apply來(lái)創(chuàng )建一個(gè)定義類(lèi)的模式:
var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
};
解析:
從代碼看,該對象僅包含一個(gè)方法:Create,其返回一個(gè)函數,即類(lèi)。但這也同時(shí)是類(lèi)的構造函數,其中調用initialize,而這個(gè)方法是在類(lèi)創(chuàng )建時(shí)定義的初始化函數,如此就可以實(shí)現prototype中的類(lèi)創(chuàng )建模式.目的是規定如此一個(gè)類(lèi)創(chuàng )建模式,讓類(lèi)的初始化函數名一定是initialize(),而this.initialize.apply(this, arguments);(令人有些費解)則是保證initialize一定會(huì )在類(lèi)的實(shí)例創(chuàng )建后調用,既方便管理又體現Object-Oriented的思想。

注意: 里邊的this其實(shí)是同一對象,即相當于類(lèi)本身調用自己的構造函數來(lái)創(chuàng )建Class對象! 因為apply方法的第二個(gè)參數本身要求是一個(gè)數組,所以傳遞給該函數的參數也傳遞給類(lèi)的initialize方法,如果直接寫(xiě)為 this.initialize(arguments); 則所有的參數是作為一個(gè)數組傳遞給了initialize構造函數。

var vehicle=Class.create();
vehicle.prototype
={
    initialize:
function(type){
        
this.type=type;
    }
    showSelf:
function(){
        alert(
"this vehicle is "+ this.type);
    }
}

var moto=new vehicle("Moto");
moto.showSelf();

4) 活用apply(javascript框架prototype的事件綁定):
Function.prototype.bind = function() {
  var __method = this; 
  var args = $A(arguments); 
  var object = args.shift();
  return function() { 
    // 調用函數的apply方法執行函數, 其中的object為目標對象, args為bind方法中的參數列表(除了第一個(gè)參數以外的參數構成的數組)
    return __method.apply(object, args.concat($A(arguments)));// 事實(shí)上, 這里的$A(arguments)一定是一個(gè)空數組
  }
}
代碼解析:
該bind用途在于將某個(gè)函數綁定到特定的函數去執行,
a) var __method = this;這首先把Function Context重新賦值到一個(gè)本地變量,使得在Closure(這是一個(gè)javascript的特性,可解釋為"閉包")中都能訪(fǎng)問(wèn)到,如此在下邊就可以方便獲取了。它實(shí)質(zhì)就是bind方法的調用者, 是一個(gè)函數對象。
b) var args = $A(arguments);這里因為arguments本就是一個(gè)類(lèi)數組的對象,通過(guò)$A(arguments)將傳入到bind方法的參數都轉化為array.
c) var object = args.shift();通過(guò)截取args的第一個(gè)參數獲取Target Object(目標對象),此時(shí)args為除了第一個(gè)參數以外的參數構成的數組(array)
d) 這是最關(guān)鍵的一步,返回一個(gè)新的函數對象(不帶有任何的參數的函數),在此通過(guò)apply把__method(bind方法的調用者)綁定到Target Object(目標對象),并給與除了Target Object(目標對象)之外的所有參數構成的數組args.concat($A(arguments)),最終Target Object(目標對象)就可執行__method了。
如此費勁周折的綁定某一個(gè)函數所換來(lái)的優(yōu)勢是,從此你不需要顧及Function Context的混亂所帶來(lái)的額外顧慮。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
JavaScript中的apply和call函數詳解
bind,call,apply模擬實(shí)現
Js apply 方法 詳解
javascript的動(dòng)態(tài)this與動(dòng)態(tài)綁定
javascript之Function類(lèi)型
arguments.callee 調用自身
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久