1.命名空间

  js里面的命名空间就是使用对象的属性来扩展的。比如,用户定义一个A对象,A对象下面有B属性和C属性,同时B属性和C属性又是对象。因此A={B:{},C:{}},这时用户就可以在B对象和C对象中定义一样的方法,属性了。因此B和C就属于不同的命名空间。我们调用B,C对象里面的方法,就可以通过A.B.like(),A.C.like()调用了。当然A属于window对象中的属性。

  但是有一种情况,比如:boke.jsp页面引入了jquery.js以及prototype.js(他们都会在window对象中添加$属性),这时就出现了冲突的情况。

  因此jquery.js里面就有了noConflict()处理冲突。执行流程:页面首先引入prototype,这时prototype会占有window的$属性,然后再引入jquery时,jquery会把之前window的$属性存放在_$中,然后自己使用$属性。这时,你可以通过$调用jquery的方法。当你现在不需要使用jquery而想使用prototype时,就可以调用$.noConflict(),这时$就会恢复成prototype对象。这时你就可以通过$使用prototype方法了。

复制代码 代码如下:
  var _$ =  window.$,_jQuery= window.jQuery;
  noConflict:function(deep){
           window.$ = _$;
       if(deep)  window.jQuery = _jQuery;
          return jQuery;    //返回值,你可以赋值给其他变量名,比如,chaojidan,这样你就可以通过chaojidan调用jQuery中的方法了。
  }

2.对象扩展

  命名空间对象有了,那我们需要扩展功能。比如:我需要把A对象的属性和方法全部复制到B对象中。我不用一个一个在B对象中去写代码。

复制代码 代码如下:
function mix(target , source){
    var args =  [].slice.call(arguments),i=1,
         isCover = typeof args[args.length-1] =="boolean" "123"等,网上一搜,就能找到很全的方法。

3.数组化

  浏览器下有很多类数组对象,arguments,document.forms,document.links,form.elements,document.getElementsByTagName,childNodes等(HTMLCollection,NodeList)。

还有一种特殊写法的自定义对象

复制代码 代码如下:
var arrayLike = {
       0:"a",
       1:"b",
      length:2
}

此对象写法,就是jQuery对象的写法。

我们需要把上述的类数组对象转换成数组对象。

[].slice.call方法可以解决。但是旧版本IE下的HTMLCollection,NodeList不是Object的子类,不能使用[].slice.call方法。

因此我们可以重写一个slice方法。

复制代码 代码如下:
A.slice = window.dispatchEvent  "number"  && isFinite(end)){   //&&优先级高于||,因此end没写,或者end是有限数字就进入
                                start = parseInt(start,10)  || 0;   //如果start不存在或者不是数字,则就赋值为0.
                                end = end == undefined "object"   ,包装对象。boolean,number,string三种包装对象,js高级程序编程里面有讲。

  有很多人使用typeof document.all来判断是否为IE,其实这是很危险的,因为此属性谷歌和火狐也喜欢,所以在谷歌浏览器下出现了这个情况:typeof document.all    //undefined  但是,document.all    //HTMLAllCollection,用typeof判断是undefined,但是可以读取此属性值。

  但是现在可以使用Object.prototype.toString.call方法判断类型。此方法可以直接输出对象内部的[[Class]].但IE8及以下的window对象不能使用此方法。可以使用   window == document  //  true      document == window  // false      IE6,7,8下。

  nodeType     ( 1:元素 Element    2:属性 attribute     3:文本  Text      9:document)

  jquery中判断类型使用的方法:

复制代码 代码如下:
  class2type ={}
  jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(i,name){
          class2type [ "[object " + name + "]"  ] = name.toLowerCase();
    //class2type = {"[object Boolean]":boolean,"[object Number ]":number ,"[object String ]":string ,"[object Function ]":function ,"[object     Array ]":array ......}
    });
    jQuery.type = function(obj){             //如果obj是null,undefined等,就返回字符串"null","undefined"。如果不是,就调用toString方法,如果可以调用就判断,出错就返回object(IE低版本下的window,Dom等ActiveXobject对象)
    return obj == null "object";
  }

5.domReady

js操作dom节点时,页面必须构建好dom树才行。因此,通常使用window.onload方法。但是onload方法是等所有资源加载结束后才会执行。而为了让页面能更快的响应用户的操作,我们只需要dom树构建完毕,就应该使用js操作。而不需要等待所有资源都加载结束(图片,flash)。

因此出现了DOMContentLoaded事件,Dom树构建完成后触发。但是旧版本IE不支持,因此就有了hack。

复制代码 代码如下:
 if(document.readyState === "complete"){   //以防Dom文档加载完成后才加载js文件。这时通过此判断来执行fn方法(你要执行的方法)。因为文档加载完成后,document.readyState的值为complete
         setTimeout(fn);      //异步执行,可以让它后面的代码先执行。这里是jQuery里面的用法,可以不用理解。
}
else if(document.addEventListener){//支持DOMContentLoaded事件
            document.addEventListener("DOMContentLoaded",fn,false);   //冒泡
    window.addEventListener("load",fn,false);   //以防DOM树构建好之后才加载js文件。这时不会触发DOMContentLoaded事件(已经触发结束了),只会触发load事件
}
else{
  document.attachEvent("onreadystatechange",function(){//针对IE下的iframe安全,有时会优先onload执行,有时不会。
    if(document.readyState ==="complete"){
      fn();
    }
  });
  window.attachEvent("onload",fn);   //总会起到作用,以防其他监听事件没获取到,这样至少可以通过onload事件触发fn方法。
  var top = false;//看是否在iframe中
     try{//window.frameElement即为包含本页面的iframe或frame对象。没有则为null。
          top = window.frameElement == null && document.documentElement;
      }catch(e){}
     if(top && top.doScroll){  //如果没有iframe,并且是IE
            (function doScrollCheck(){
                     try{
          top.doScroll("left");//IE下,如果Dom树构建好,就可以调用html的doScroll方法         
        }catch(e){
                            return setTimeout(doScrollCheck,50);  //如果还没构建好,则继续监听
                    }
                    fn();
            })
    }
}

fn方法中必须包含移除所有的绑定事件。

当然IE还可以使用script defer hack,原理就是:指定了defer的script会在DOM树构建完后才执行。但是这需要添加额外的js文件,很少在单独的库里面用到。

使用原理:在文档中添加script标签,并用script.src = "xxx.js",监听script的onreadystatechange事件,当this.readyState == "complete"时,就执行fn方法。

也就是说,DOM构建好之后,xxx.js才会执行,它的this.readyState才会变成complete。

以上便是javascript框架设计的第一章的读书笔记了,内容比较精简,方便大家更好的理解这章的基本内容。

标签:
javascript,种子模块

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“javascript框架设计读书笔记之种子模块”
暂无“javascript框架设计读书笔记之种子模块”评论...