zoukankan      html  css  js  c++  java
  • 读Ext之一(实用方法)

    第一句

    window.undefined = window.undefined;  
    

      

    兼容IE6以下的浏览器,有人 解释过了。

     

    定义Ext全局变量

    Ext = {
        version : '3.1.0'
    };
    

    注意这里没有使用var,不使用var声明变量被认为是不好的编程习惯,尤其是函数内声明变量不写var更被称为是无穷无尽的Bug根源。这里则不会,因为变量Ext是该库唯一的全局变量(命名空间)。其它Ext源码中的变量声明都加上了var。

     

    给Ext添加静态apply方法,该方法是核心方法之一,会用其扩展Ext。

    Ext.apply = function(o, c, defaults){
        // no "this" reference for friendly out of scope calls
        if(defaults){
            Ext.apply(o, defaults);
        }
        if(o && c && typeof c == 'object'){
            for(var p in c){
                o[p] = c[p];
            }
        }
        return o;
    };
    

    该方法有两种执行方式:

    其一,只传o,c时直接将c上的所有属性/方法拷贝给o后返回;

    其二,defaults也传时,会将defaults,c上的所有属性/方法都拷贝给o。这里实现的很巧妙,同时有点绕人。

    三个参数都传,会执行Ext.apply(o, defaults),即自身实现中调用自身。defaults为c,即当传两个参数时会直接进行对象拷贝。举个例子一目了然,在Ext.apply中加上一个输出语句

    Ext.apply = function(o, c, defaults){
        // no "this" reference for friendly out of scope calls
        if(defaults){
            Ext.apply(o, defaults);
        }
        if(o && c && typeof c == 'object'){
            for(var p in c){
            	alert(p); // 此处是添加的输出语句
                o[p] = c[p];
            }
        }
        return o;
    };
    var obj = {}, obj1 = {name:'jack'}, obj2 = {age:33};
    Ext.apply(obj,obj1,obj2);
    

    会发现先弹出age,再是name。即先拷贝defaults,再是c。

     

    接下来是个自执行的匿名函数,执行完后给Ext上扩充许多实用属性或方法。先定义了一些局部变量idSeed,浏览器判断之类。idSeed在做Dom缓存时用到。接下来,

    if(isIE6){
        try{
            DOC.execCommand("BackgroundImageCache", false, true);
        }catch(e){}
    }
    

    这段代码用来解决IE6下css背景图不缓存bug,也 有人 解释过了。

     

    接下就是一个Ext.apply(Ext,{...}),给Ext对象扩展许多实用属性及方法。

     

    注意 Ext.isStrict 并非判断html文档模式为严格模式,而是指标准模式,如<!DOCTYPE HTML>声明会返回true。关于文档模式猛击:http://hsivonen.iki.fi/doctype ,国内的 秦歌 翻译了该篇文章。

     

    Ext.isSecure 判断采用https或是其它。

     

    Ext.applyIf 设计的很巧妙,它会把对象没有的属性和方法拷贝下来,已经有的则不拷贝。Ext.apply 则会覆盖已有的属性/方法。

    ECMAScript 5已经发布1年多了,添加了一些新的API方法,如Array的indexOf,forEach等方法,部分新版本浏览器已经支持这些方法来,但我们想为老的浏览器扩展该方法。可能会这样写

    var proto = Array.prototype;
    if(!proto.indexOf){
    	proto.indexOf = function(){
    		// ...
    	}
    }
    if(!proto.forEach){
    	proto.forEach = function(){
    		// ...
    	}
    }
    
    即保证优先使用浏览器原生支持的API方法,不支持的使用自定义实现的。但这里每次都需要判断下Array原型上是否存在该方法。google closure  实现方式类似使用了三元运算符,每次都要判断下,相对丑陋。网上有一些对google closure的 批评 及一些效率低下的 具体分析  ,批评者甚至包括大牛:Dmitry Baranovskiy 。相对来说,Ext.applyif则使的API的扩展很优雅。
     

    Ext.id方法会为HTMLElement元素随机生成一个id,默认以"ext-gen"开头。

     

    接下来是Ext.extend方法,该方法也是核心方法之一,整个ext框架继承都是以该方法来扩展的。该方法实现依赖于Ext.override,先看override

    override : function(origclass, overrides){
        if(overrides){
            var p = origclass.prototype;
            Ext.apply(p, overrides);
            if(Ext.isIE && overrides.hasOwnProperty('toString')){
                p.toString = overrides.toString;
            }
        }
    }
    

    将对象overrides的所有属性/方法拷贝到类origclass的原型上。需要注意的是后面的if判断,IE中for in不能遍历对象的Object的toSting等方法,因此需要特别处理一下。我测试IE9 beta重写对象的内置方法如toString后是可用for in遍历的,见 for in的缺陷  。IE9 beta刚刚发布,不知今后Ext团队是否会修改此处的判断。

     

    Ext.extend是js继承最经典的实现方式了,我曾经模仿其(简化版)应用在 51ditu 。

    extend : function(){
        // inline overrides
        var io = function(o){
            for(var m in o){
                this[m] = o[m];
            }
        };
        var oc = Object.prototype.constructor;
        return function(sb, sp, overrides){
            if(Ext.isObject(sp)){
                overrides = sp;
                sp = sb;
                sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
            }
            var F = function(){},
                sbp,
                spp = sp.prototype;
    
            F.prototype = spp;
            sbp = sb.prototype = new F();
            sbp.constructor=sb;
            sb.superclass=spp;
            if(spp.constructor == oc){
                spp.constructor=sp;
            }
            sb.override = function(o){
                Ext.override(sb, o);
            };
            sbp.superclass = sbp.supr = (function(){
                return spp;
            });
            sbp.override = io;
            Ext.override(sb, overrides);
            sb.extend = function(o){return Ext.extend(sb, o);};
            return sb;
        };
    }(),
    

    整体浏览,可以看到 Ext.extend 的实现是通过一个匿名函数执行,执行后返回function,这个function才是真正的Ext.extend。

    匿名函数中有两个私有函数io,oc。这种组织代码的方式非常简练,通过匿名函数自执行,在匿名函数中你可以做任何复杂的操作,最终的目的返回需要的接口函数或类。

     

    有三个参数,sb、sp、overrides分别代表subClass(子类)、superClass(父类)及覆盖子类的配置参数。

     

    以下分三种情况讨论,第一,二种情况Ext.extend的第二个参数都是对象类型

     

    1, Ext.extend不光是用来实现类继承的,还可以用来写类,一年前 讨论 过 。 

    2, 用来扩展Ext库自身类,这种情况是比较频繁的

    MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
        constructor: function(config) {
            MyGridPanel.superclass.constructor.apply(this, arguments);
        },
        yourMethod: function() {
            // etc.
        }
    });
    

    这里以Ext.grid.GridPanel为基础,生成了一个新类MyGridPanel

     

    3, 真正意义类继承,即第一,二个参数都是类(function)。1年前也总结过js如何实现 继承 及 工具函数 。

     

    篇幅已经很长了,重点说下 Ext.apply, Ext.applyif, Ext.override, Ext.extend 的区别 :

     

    Ext.apply, Ext.applyif, Ext.override 都是对对象 进行扩展的方法,Ext.extend则是对 操作的方法。

     

    Ext.apply 扩展时对已经存在的属性/方法会被覆盖掉, 通常用它来扩展普通对象.

    Ext.applyif 扩展时不会覆盖已经存在的属性/方法,通常用它来扩展核心js,如Array.prototype,String.prototype等。

    Ext.override 扩展某一个类的原型,可以覆盖toString方法。

     

    Ext.extend 用来写类或继承,或者说用来扩展类。

     

     

    Ext-2012-4-21.rar

     

  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/snandy/p/2461256.html
Copyright © 2011-2022 走看看