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 相关文章推荐
用于判断用户注册时,密码强度的JS代码
Jan 01 Javascript
js特殊字符转义介绍
Nov 05 Javascript
js中浮点型运算BUG的解决方法说明
Jan 06 Javascript
使用jQuery设置disabled属性与移除disabled属性
Aug 21 Javascript
node.js中实现同步操作的3种实现方法
Dec 05 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
Sep 10 Javascript
JavaScript encodeURI 和encodeURIComponent
Dec 04 Javascript
jQuery插件ajaxFileUpload异步上传文件
Oct 19 Javascript
Vue computed计算属性的使用方法
Jul 14 Javascript
Vue中使用webpack别名的方法实例详解
Jun 19 Javascript
微信小程序实现多选框全选与取消全选功能示例
May 14 Javascript
Vue中使用better-scroll实现轮播图组件
Mar 07 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实现读取手机客户端浏览器的类
2015/01/09 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
解决yii2左侧菜单子级无法高亮问题的方法
2016/05/08 PHP
一段实用的php验证码函数
2016/05/19 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
2016/09/21 PHP
ThinkPHP框架下微信支付功能总结踩坑笔记
2019/04/10 PHP
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
jQuery UI AutoComplete 自动完成使用小记
2010/08/21 Javascript
jQuery中.live()方法的用法深入解析
2013/12/30 Javascript
什么是Node.js?Node.js详细介绍
2014/06/01 Javascript
一个支持任意尺寸的图片上下左右滑动效果
2014/08/24 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
jQuery与Ajax以及序列化
2016/02/01 Javascript
jquery 属性选择器(匹配具有指定属性的元素)
2016/09/06 Javascript
EasyUI创建人员树的实例代码
2017/09/15 Javascript
AngualrJs清除定时器遇到的坑
2017/10/13 Javascript
webpack-dev-server远程访问配置方法
2018/02/22 Javascript
微信小程序实现卡片左右滑动效果的示例代码
2019/05/01 Javascript
构建大型 Vue.js 项目的10条建议(小结)
2019/11/14 Javascript
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python聊天室实例程序分享
2016/01/05 Python
详谈Python2.6和Python3.0中对除法操作的异同
2017/04/28 Python
Java分治归并排序算法实例详解
2017/12/12 Python
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
使用Python生成200个激活码的实现方法
2019/11/22 Python
python统计文章中单词出现次数实例
2020/02/27 Python
Python引入多个模块及包的概念过程解析
2020/09/21 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
2014年商场超市庆元旦活动方案
2014/02/14 职场文书
《浅水洼里的小鱼》听课反思
2014/02/28 职场文书
承诺书样本
2014/08/30 职场文书
预备党员2014年第四季度思想汇报范文
2014/10/25 职场文书
师德先进个人材料
2014/12/20 职场文书
2015年文员个人工作总结
2015/04/09 职场文书
环保建议书作文300字
2015/09/14 职场文书