<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA & XML & JAVASCRIPT & AJAX & CSS

    Web 2.0 技術儲備............

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      77 隨筆 :: 17 文章 :: 116 評論 :: 0 Trackbacks

    轉自 : http://www.bjcan.com/hengxing/readlou.asp?id=1162

    ?2). 反射機制在JavaScript中的實現
    ?------
    ? JavaScript中通過for..in語法來實現了反射機制。但是JavaScript中并不
    明確區分“屬性”與“方法”,以及“事件”。因此,對屬性的類型考查在JS
    中是個問題。下面的代碼簡單示例for..in的使用與屬性識別:
    //---------------------------------------------------------
    // JavaScript中for..in的使用和屬性識別
    //---------------------------------------------------------
    var _r_event = _r_event = /^[Oo]n.*/;
    var colorSetting = {
    ? method: 'red',
    ? event: 'blue',
    ? property: ''
    }

    var obj2 = {
    ? a_method : function() {},
    ? a_property: 1,
    ? onclick: undefined
    }

    function propertyKind(obj, p) {
    ? return? (_r_event.test(p) && (obj[p]==undefined || typeof(obj[p])=='function')) ? 'event'
    ??? : (typeof(obj[p])=='function') ? 'method'
    ??? : 'property';
    }

    var objectArr = ['window', 'obj2'];

    for (var i=0; i<objectArr.length; i++) {
    ? document.writeln('<p>for ', objectArr[i], '<hr>');

    ? var obj = eval(objectArr[i]);
    ? for (var p in obj) {
    ??? var kind = propertyKind(obj, p);
    ??? document.writeln('obj.', p, ' is a ', kind.fontcolor(colorSetting[kind]), ': ', obj[p], '<br>');
    ? }

    ? document.writeln('</p>);
    }

    一個常常被開發者忽略的事實是:JavaScript本身是沒有事件(Event)系統的。通
    常我們在JavaScript用到的onclick等事件,其實是IE的DOM模型提供的。從更內核
    的角度上講:IE通過COM的接口屬性公布了一組事件接口給DOM。

    有兩個原因,使得在JS中不能很好的識別“一個屬性是不是事件”:
    ? - COM接口中本身只有方法,屬性與事件,都是通過一組get/set方法來公布的。
    ? - JavaScript中,本身并沒有獨立的“事件”機制。

    因此我們看到event的識別方法,是檢測屬性名是否是以'on'字符串開頭(以'On'開
    頭的是Qomo的約定)。接下來,由于DOM對象中的事件是可以不指定處理函數的,這
    種情況下事件句柄為null值(Qomo采用相同的約定);在另外的一些情況下,用戶可
    能象obj2這樣,定義一個值為 undefined的事件。因此“事件”的判定條件被處理
    成一個復雜的表達式:
    ?? ("屬性以on/On開頭" && ("值為null/undefined" || "類型為function"))

    另外,從上面的這段代碼的運行結果來看。對DOM對象使用for..in,是不能列舉出
    對象方法來的。

    最后說明一點。事實上,在很多語言的實現中,“事件”都不是“面向對象”的語
    言特性,而是由具體的編程模型來提供的。例如Delphi中的事件驅動機制,是由Win32
    操作系統中的窗口消息機制來提供,或者由用戶代碼在Component/Class中主動調用
    事件處理函數來實現。

    “事件”是一個“如何驅動編程模型”的機制/問題,而不是語言本身的問題。然
    而以PME(property/method/event)為框架的OOP概念,已經深入人心,所以當編程語
    言或系統表現出這些特性來的時候,就已經沒人關心“event究竟是誰實現”的了。


    ?3). this與with關鍵字的使用
    ?------
    ?在JavaScript的對象系統中,this關鍵字用在兩種地方:
    ?? - 在構造器函數中,指代新創建的對象實例
    ?? - 在對象的方法被調用時,指代調用該方法的對象實例

    ?如果一個函數被作為普通函數(而不是對象方法)調用,那么在函數中的this關鍵字
    將指向window對象。與此相同的,如果this關鍵字不在任何函數中,那么他也指向
    window對象。

    ?由于在JavaScript中不明確區分函數與方法。因此有些代碼看起來很奇怪:
    //---------------------------------------------------------
    // 函數的幾種可能調用形式
    //---------------------------------------------------------
    function foo() {
    ? // 下面的this指代調用該方法的對象實例
    ? if (this===window) {
    ??? document.write('call a function.', '<BR>');
    ? }
    ? else {
    ??? document.write('call a method, by object: ', this.name, '<BR>');
    ? }
    }

    function MyObject(name) {
    ? // 下面的this指代new關鍵字新創建實例
    ? this.name = name;
    ? this.foo = foo;
    }

    var obj1 = new MyObject('obj1');
    var obj2 = new MyObject('obj2');

    // 測試1: 作為函數調用
    foo();

    // 測試2: 作為對象方法的調用
    obj1.foo();
    obj2.foo();

    // 測試3: 將函數作為“指定對象的”方法調用
    foo.call(obj1);
    foo.apply(obj2);

    在上面的代碼里,obj1/obj2對foo()的調用是很普通的調用方法。——也就
    是在構造器上,將一個函數指定為對象的方法。

    而測試3中的call()與apply()就比較特殊。

    在這個測試中,foo()仍然作為普通函數來調用,只是JavaScript的語言特性
    允許在call()/apply()時,傳入一個對象實例來指定foo()的上下文環境中所
    出現的this關鍵字的引用。——需要注意的是,此時的foo()仍舊是一個普通
    函數調用,而不是對象方法調用。

    與this“指示調用該方法的對象實例”有些類同的,with()語法也用于限定
    “在一段代碼片段中默認使用對象實例”。——如果不使用with()語法,那
    么這段代碼將受到更外層with()語句的影響;如果沒有更外層的with(),那
    么這段代碼的“默認使用的對象實例”將是window。

    然而需要注意的是this與with關鍵字不是互為影響的。如下面的代碼:
    //---------------------------------------------------------
    // 測試: this與with關鍵字不是互為影響的
    //---------------------------------------------------------
    function test() {
    ? with (obj2) {
    ??? this.value = 8;
    ? }
    }
    var obj2 = new Object();
    obj2.value = 10;

    test();
    document.writeln('obj2.value: ', obj2.value, '<br>');
    document.writeln('window.value: ', window.value, '<br>');

    你不能指望這樣的代碼在調用結束后,會使obj2.value屬性置值為8。這幾行
    代碼的結果是:window對象多了一個value屬性,并且值為8。

    with(obj){...}這個語法,只能限定對obj的既有屬性的讀取,而不能主動的
    聲明它。一旦with()里的對象沒有指定的屬性,或者with()限定了一個不是對
    象的數據,那么結果會產生一個異常。


    ?4). 使用in關鍵字的運算
    ?------
    ?除了用for..in來反射對象的成員信息之外,JavaScript中也允許直接用in
    關鍵字去檢測對象是否有指定名字的屬性。

    ?in關鍵字經常被提及的原因并不是它檢測屬性是否存在的能力,因此在早期
    的代碼中,很多可喜歡用“if (!obj.propName) {}” 這樣的方式來檢測propName
    是否是有效的屬性。——很多時候,檢測有效性比檢測“是否存有該屬性”更
    有實用性。因此這種情況下,in只是一個可選的、官方的方案。

    ?in關鍵字的重要應用是高速字符串檢索。尤其是在只需要判定“字符串是否
    存在”的情況下。例如10萬個字符串,如果存儲在數組中,那么檢索效率將會
    極差。
    //---------------------------------------------------------
    // 使用對象來檢索
    //---------------------------------------------------------
    function arrayToObject(arr) {
    ? for (var obj=new Object(), i=0, imax=arr.length; i<imax; i++) {
    ??? obj[arr[i]]=null;
    ? }
    ? return obj;
    }

    var
    ? arr = ['abc', 'def', 'ghi']; // more and more...
    ? obj = arrayToObject(arr);

    function valueInArray(v) {
    ? for (var i=0, imax=arr.length; i<imax; i++) {
    ??? if (arr[i]==v) return true;
    ? }

    ? return false;
    }

    function valueInObject(v) {
    ? return v in obj;
    }

    這種使用關鍵字in的方法,也存在一些限制。例如只能查找字符串,而數
    組元素可以是任意值。另外,arrayToObject()也存在一些開銷,這使得它
    不適合于頻繁變動的查找集。最后,(我想你可能已經注意到了)使用對象
    來查找的時候并不能準確定位到查找數據,而數組中可以指向結果的下標。

    posted on 2006-03-20 09:39 Web 2.0 技術資源 閱讀(355) 評論(0)  編輯  收藏 所屬分類: Javascript
    主站蜘蛛池模板: 亚洲码一区二区三区| 一级毛片免费播放男男| 国产高清免费的视频| 一级看片免费视频| 亚洲人成依人成综合网| 在线免费观看污网站| APP在线免费观看视频| 亚洲另类无码专区丝袜| 亚洲人成在线播放网站| 在线观看免费成人| 日韩免费高清播放器| 亚洲中文无码mv| 亚洲男人第一av网站| 免费人成视频在线观看视频| 美丽姑娘免费观看在线观看中文版| 亚洲精品成a人在线观看☆| 亚洲AV无码日韩AV无码导航| 国产免费人成视频在线观看 | 亚洲国产天堂久久综合| 1000部拍拍拍18勿入免费视频下载 | 最近中文字幕2019高清免费| 老司机午夜免费视频| 亚洲一区无码中文字幕乱码| 国产亚洲日韩一区二区三区| 成人免费视频观看无遮挡| 男人都懂www深夜免费网站| 亚洲AⅤ男人的天堂在线观看 | 免费观看91视频| 水蜜桃视频在线观看免费| 亚洲六月丁香婷婷综合| 亚洲日本一区二区三区| 久久精品国产亚洲精品| 成人a视频片在线观看免费| 久久久久久国产精品免费无码| 一区二区在线免费视频| 亚洲AV噜噜一区二区三区| 亚洲性无码av在线| 久久精品国产亚洲av日韩| 亚洲日韩乱码中文无码蜜桃臀网站| 国产精品美女自在线观看免费| 无码国产精品久久一区免费 |