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 相关文章推荐
基于JQuery实现的类似购物商城的购物车
Dec 06 Javascript
Javascript中设置默认参数值示例
Sep 11 Javascript
JS实现网页标题随机显示名人名言的方法
Nov 03 Javascript
JS模拟实现方法重载示例
Aug 03 Javascript
vue.js评论发布信息可插入QQ表情功能
Aug 08 Javascript
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
Dec 08 Javascript
vue实现图片加载完成前的loading组件方法
Feb 05 Javascript
vue.js使用3DES加密的方法示例
May 18 Javascript
详解webpack运行Babel教程
Jun 13 Javascript
用Golang运行JavaScript的实现示例
Nov 25 Javascript
vue实现公告栏文字上下滚动效果的示例代码
Jun 16 Javascript
JavaScript 实现页面滚动动画
Apr 24 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开发不能违背的安全规则 过滤用户输入
2011/05/01 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
Smarty变量用法详解
2016/05/11 PHP
JQuery datepicker 使用方法
2011/05/20 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
微信小程序  modal详解及实例代码
2016/11/09 Javascript
学习vue.js中class与style绑定
2016/12/03 Javascript
微信小程序 数组(增,删,改,查)等操作实例详解
2017/01/05 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
js实现打地鼠小游戏
2017/02/13 Javascript
详解在 Angular 项目中添加 clean-blog 模板
2017/07/04 Javascript
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
vue中的循环对象属性和属性值用法
2020/09/04 Javascript
[03:40]2014DOTA2国际邀请赛 B神专访:躲箭真的很难
2014/07/13 DOTA
Python 调用VC++的动态链接库(DLL)
2008/09/06 Python
Python中使用装饰器和元编程实现结构体类实例
2015/01/28 Python
Python MySQLdb模块连接操作mysql数据库实例
2015/04/08 Python
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
python3.x上post发送json数据
2018/03/04 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
Python设计模式之代理模式实例详解
2019/01/19 Python
python实现读取excel文件中所有sheet操作示例
2019/08/09 Python
浅析pandas 数据结构中的DataFrame
2019/10/12 Python
python3.8.1+selenium实现登录滑块验证功能
2020/05/22 Python
Pymysql实现往表中插入数据过程解析
2020/06/02 Python
Python 整行读取文本方法并去掉readlines换行\n操作
2020/09/03 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
Laura Geller官网:美国彩妆品牌
2018/12/29 全球购物
乡镇庆八一活动方案
2014/02/02 职场文书
珠宝店促销方案
2014/03/21 职场文书
开学典礼演讲稿
2014/05/23 职场文书
三峡导游词
2015/01/31 职场文书
出国留学导师推荐信
2015/03/26 职场文书
入党心得体会
2019/06/20 职场文书
MySQL系列之开篇 MySQL关系型数据库基础概念
2021/07/02 MySQL
Vue项目打包、合并及压缩优化网页响应速度
2021/07/07 Vue.js