javascript框架设计读书笔记之种子模块


Posted in Javascript onDecember 02, 2014

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" ? args.pop():true;  //不写,默认为true,默认是覆盖。

   if(args.length == 1){                                      
target = !this.window? this:{};

//如果只有一个对象参数时,就扩展this对象。比如:我在A对象的context中调用mix(B),那么这时的this就是A,因此会把B的属性和方法添加到A对象中。但是如果是在window中调用mix(B),就会把B对象中的属性和方法添加到一个空的对象中,并返回这个空的对象,以防覆盖window对象中同名的属性和方法。(只有window对象拥有window属性)

      i =0;

 }

 while((source = args[i++])){


for(key in source){

                      if(isCover || !(key in target))   //如果覆盖,就直接赋值,如果不覆盖,先判断key是否存在目标对象中,如果存在,就不赋值



   {





target[key] = source[key];

                      }

           }

   }

   return target;

}

大公司面试官很喜欢问数组的查重,大家可以去看看,数组中的每项可以是对象,而对象A和对象B即便一样的属性和方法,但是也是不相等的。字符串和数字,比如123和"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  ? function(nodes,start,end){   return [].slice.call(nodes,start,end);      }

//如果window有dispatchEvent  属性就证明支持[].slice.call方法,能力检测。

                 :function(nodes,start,end){

                       var ret = [],n=nodes.length;



if(end == undefined  ||  typeof end === "number"  && isFinite(end)){   //&&优先级高于||,因此end没写,或者end是有限数字就进入

                                start = parseInt(start,10)  || 0;   //如果start不存在或者不是数字,则就赋值为0.

                                end = end == undefined ? n:parseInt(end,10);    //如果end不存在,则赋值为n.






if(start < 0)    start + = n;






if(end< 0)    end + = n;






if(end>n)    end  = n;






for(var i = start;i<end;i++){

                                      ret[i-start] = nodes[i];     //低版本IE使用数组赋值的形式

                                 }




}




return ret;

}

4.类型的判断

js五种简单数据类型有:null,undefined,boolean,number,string。

还有复杂的数据类型:Object,Function,RegExp,Date,自定义的对象,比如:Person等。

typeof一般用来判断boolean,number,string,instanceof一般用来判断对象类型。但它们都有缺陷。比如:firame里面的数组实例就不是父窗口的Array的实例,调用instanceof会返回false。(这题360校招时问过)。typeof new Boolean(true)     // "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 ? String(obj)  : class2type [ toString.call(obj) ]  || "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 相关文章推荐
javascript parseInt 函数分析(转)
Mar 21 Javascript
基于javascript 闭包基础分享
Jul 10 Javascript
angularjs的一些优化小技巧
Dec 06 Javascript
jQuery使用empty()方法删除元素及其所有子元素的方法
Mar 26 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
Aug 17 Javascript
jQuery实现div拖拽效果实例分析
Feb 20 Javascript
酷炫jQuery全屏3D焦点图动画效果
Mar 22 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
Jun 07 Javascript
详解vue axios中文文档
Sep 12 Javascript
解析Json字符串的三种方法日常常用
May 02 Javascript
小程序开发踩坑:页面窗口定位(相对于浏览器定位)(推荐)
Apr 25 Javascript
微信小程序 checkbox使用实例解析
Sep 09 Javascript
推荐一个封装好的getElementsByClassName方法
Dec 02 #Javascript
CSS3,HTML5和jQuery搜索框集锦
Dec 02 #Javascript
JavaScript和CSS交互的方法汇总
Dec 02 #Javascript
HTML,CSS,JavaScript速查表推荐
Dec 02 #Javascript
javascript函数声明和函数表达式区别分析
Dec 02 #Javascript
javascript常用方法汇总
Dec 02 #Javascript
js时间日期格式化封装函数
Dec 02 #Javascript
You might like
php判断数组元素中是否存在某个字符串的方法
2014/06/14 PHP
thinkPHP实现MemCache分布式缓存功能
2016/03/23 PHP
CodeIgniter基于Email类发邮件的方法
2016/03/29 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
2018/04/21 PHP
dwr spring的集成实现代码
2009/03/22 Javascript
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
innerHTML属性,outerHTML属性,textContent属性,innerText属性区别详解
2015/03/13 Javascript
javascript表单验证大全
2015/08/12 Javascript
JS创建事件的三种方法(实例代码)
2016/05/12 Javascript
微信小程序实现流程进度的图样式功能
2018/01/16 Javascript
基于element-ui的rules中正则表达式
2018/09/04 Javascript
vue使用自定义指令实现拖拽
2021/01/29 Javascript
基于js实现复制内容到操作系统粘贴板过程解析
2019/10/11 Javascript
适合前端Vue开发童鞋的跨平台Weex的使用详解
2019/10/16 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
JS实现网站楼层导航效果代码实例
2020/06/16 Javascript
vue实现登录、注册、退出、跳转等功能
2020/12/23 Vue.js
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
python3实现短网址和数字相互转换的方法
2015/04/28 Python
详解python基础之while循环及if判断
2017/08/24 Python
Python判断两个对象相等的原理
2017/12/12 Python
python实现随机梯度下降法
2020/03/24 Python
只需7行Python代码玩转微信自动聊天
2019/01/27 Python
python实现一个函数版的名片管理系统过程解析
2019/08/27 Python
python绘制彩虹图
2019/12/16 Python
Python连接Oracle之环境配置、实例代码及报错解决方法详解
2020/02/11 Python
在pycharm中创建django项目的示例代码
2020/05/28 Python
Python基于staticmethod装饰器标示静态方法
2020/10/17 Python
大学军训感言600字
2014/02/25 职场文书
结对共建工作方案
2014/06/02 职场文书
2015年公司后勤管理工作总结
2015/05/13 职场文书
寻衅滋事罪辩护词
2015/05/21 职场文书
《钓鱼的启示》教学反思
2016/02/18 职场文书
《颐和园》教学反思
2016/02/19 职场文书
导游词幽默开场白
2019/06/26 职场文书
详解CocosCreator消息分发机制
2021/04/16 Javascript