zhuhuiwen Front-end Dev Engineer

js原生框架第一天

2016-12-11

12/11/2016 8:18:15 AM

jq框架预备知识

创建对象的方式

1. {} [] /abc/ function(){}
2. 构造函数
3. 工厂模式

创建jq对象的方式

1. $()
2. jQuery()
3. jq创建对象是工厂模式

函数的return结果

  1. 因为返回的是

什么是伪数组

  1. 概念
    1. 伪数组是一个非数组类型的对象
    2. 有一个length属性,值为number类型
    3. 以下标的方式存储数据

jq对象是不是伪数组

  1. jq对象就是伪数组

实例成员和静态成员

  1. 实例成员
    1. 供实例使用的属性与方法就叫实例成员
  2. 静态成员
    1. 供构造函数自己使用的属性与方法
  3. 总结
    1. 实例只能访问实例成员
    2. ,,,

分析jq结构

闭包的作用

  1. 作用
    1. 效率
    2. 避免全局污染

jq对不同参数的处理

  1. 入口函数的作用
    1. 传入的函数会在dom构建完毕后执行
      1. 执行时机被控制了
    2. 可以有多个入口函数???
    3. 返回是实例

jq对不同参数的处理结果

  1. 传入转换为布尔类型为false的数据,得到空数据
  2. jq对函数的处理
  3. 传入字符串
    1. html,则创建
    2. 不是,获取元素

jq是伪数组,也是以

length

  1. 函数默认就有length属性,是参数的个数 形参的个数
  2. window也有length , 代表页面中有iframe元素
    1. 页面的子页面
    2. 加个百度 加个163 是2个window.length 12/11/2016 4:01:48 PM

in

  1. in运算符
    1. 属性名 in 对象.判断对象是否拥有某个属性的使用权
    2. in不在乎是不是自己的,只要可以用
  2. hasowenpropoty
    1. 是方法
      1. 判断一个属性是不是自己的

ie8中apply的bug

  1. 无法平铺用户自定义的伪数组
  2. 借用数组的slice 方法,可以通过伪数组=获取一个真数组

  3. call 和 apply 对于框架来说比较多
  4. 使用常量进行缓存
  5. 入口函数对函数处理的实现方式 12/11/2016 6:45:30 PM

创建对象的方式

  1. 创建对象的方式:
    1. new 构造函数
    2. 字面量
    3. 工厂模式
  2. new 构造函数
    1. 代码 function Person(){}; var p = new Person();
  3. 字面量创建对象的方式
    1. 代码

        var obj = {};
      	 var arr = [];
        var reg = /abc/;
        var fn = function(){};
      
  4. 工厂方式创建对象
    1. 代码

       //工厂方式创建对象
       function getPerson(){
           //直接进行返回一个对象
           return new Person();
       }
       function Person(){};
       getPerson();
      

创建jQ对象的方式

  1. 两种方式
    1. $()
    2. jQuery()
  2. 代码 /* * 创建jQ对象的方式: * 1、$() * 2、jQuery() * / //jQ创建对象是工厂模式 /[prevObject: jQuery.fn.init[1]]/ /console.log($(‘span’));//获取元素 console.log(jQuery(‘body’));*/

     //$.prototype.constructor是一个工厂函数
     //还是指向的$的工厂函数
     //console.log($.prototype.constructor('div'));
     //console.log($('div'));
     /*
     * 真正的构造函数
     * 直接进行创建一个script对象
     * */
     //[script, script, prevObject: jQuery.fn.init[1]]
     //这个也是获取
     console.log(new $.prototype.init('div'));
    
     页面结构
     <!--<div>1</div>-->
     <span></span>
    

函数的return结果

  1. 还是之前的
    1. 普通的函数不写return,返回值就是undefiend
    2. 构造函数调用的方式
      1. 没有返回值或是返回简单的数据类型,就是new创建的对象
      2. 返回的是复杂的数据的类型,则复杂的数据类型将新创建出来的对象进行覆盖了
  2. 代码 function add(a,b){ return a+b; }; function fn(){}; function arr(){ return []; };

         console.log(add(10, 1));//11
         console.log(fn());//undefined
    	
         console.log(new add(10, 11));//add {}
    	
         //下面这两种第一种new的方式创建,返回的是[]是设置的返回值
         //直接进行函数的调用方式,返回的也是[]
         console.log(new arr());//[]
         console.log(arr());//[]
    

伪数组

  1. 什么是伪数组
    1. 伪数组是一个非数组类型的对象
    2. 有一个length属性,值为number类型
    3. 以下标的方式存储数据,
      1. 注意:
        1. 下标是数值类型
        2. 比如 0 1 2
  2. 代码解释

     var obj2 = {
         0 : 'waxun',
         1 : '17',
         2 : false,
         length : 3
     }
     //对象的形式....  伪数组这个,length指的是下标是数值类型的数据
     for(var i=0;i<obj2.length;i++){
         console.log(obj2[i]);//进行输出
     }
    

jQ对象就是伪数组

  1. console.log($(‘script’));
    1. 就是获取script标签

jQ中创建伪数组的原理

  1. 思路
    1. 这是工厂函数
    2. 这是构造函数
      1. 给新创建的实例对象添加属性
      2. 简写方式,是将数组的this指向了这个new出来的对象,
      3. 使用call改变this的指向,并且可以使用真的数组的push方法
    3. 调用
      1. $()得到的仍然是实例对象,不过这个实例对象拥有一个length属性,
      2. 并且值为–,那么这个实例对象又多了一个称呼,叫伪数组对象。
  2. 代码

     //这是工厂函数
     function $(){
         return new init();
     }
     //这是构造函数
     function init(){
         //给新创建的实例对象添加属性
       /*  this[0] = 'w';
         this[1] = '1';
         this[2] = '2';
         this[3] = '4';
         this[4] = '1';
         this[5] = '0';
         this.length = 6;*/
    
         //简写方式,是将数组的this指向了这个new出来的对象,
         // 使用call改变this的指向,并且可以使用真的数组的push方法
         [].push.call(this,'w','1','2','4','1','0');
     }
     //$()得到的仍然是实例对象,不过这个实例对象拥有一个length属性,
     //并且值为--,那么这个实例对象又多了一个称呼,叫伪数组对象。
     console.log($());//0-5键值对 和 length:6
     console.log($().length);//6
    

实例成员和静态成员

  1. 概念
    1. 什么是实例成员
      1. 供实例使用的属性与方法就叫实例成员
      2. 就是可以给对象使用的属性和方法
    2. 什么是静态成员
      1. 供构造函数自己使用的属性与方法就叫静态成员
  2. 注意点
    1. 实例能否使用静态成员? 不能
    2. 构造函数能否使用实例成员?不能
  3. 代码

         function Person(age){
             //这是实例成员
             this.name = age;
         }
    	
         //原型添加一些方法
         Person.prototype = {
             //这也是实例成员
             run : function(){
                 console.log('running...');
             }
         }
    	
         //这是静态成员
         Person.Max_AGE = 120;
    	
    	
         //实例能否使用静态成员? 不能
         var p1 = new Person(11);
         p1.run();//running...
         console.log(p1.Max_AGE);//undefined
    	
         //构造函数能否使用实例成员?不能
         console.log(Person.Max_AGE);//20
         console.log(Person.age);//undefined
    

jQ中的实例成员和静态成员

  1. 代码

     //以下是jQ的实例成员
     $().css();
     $().attr();
    
     // 以下是jQ的静态成员
     $.ajax({});
    

jQ框架简单分析

抽取jQ框架的结构

  1. 思路分析
    1. jQ整体是一个自调函数结构
    2. 对外暴露$
    3. $的函数本体,是一个工厂函数
    4. 给原型提供一个简称$.fn
    5. 在原型上定义构造函数
    6. 把构造函数的原型替换为工厂函数的原型,
      1. 为的是让实例能给访问$.fn上的成员,
      2. 准确的说就是为了实现插件机制
  2. IFFE传过来一个参数window
    1. 为了实现压缩
    2. 可以提高查询变量的效率
  3. 基本结构的代码

         //1.jQ整体是一个自调函数结构
        (function(window){
            //3. $的函数本体,是一个工厂函数
            var jQuery = function(){
                return new jQuery.fn.init();
            }
            // 4、给原型提供一个简称$.fn
            jQuery.fn = jQuery.prototype = {
                constructor : jQuery
            }
            //5、在原型上定义构造函数
            var init = jQuery.fn.init =function(){
             /*
             6.把构造函数的原型替换为工厂函数的原型,
             *为的是让实例能给访问$.fn上的成员,
             * 准确的说就是为了实现插件机制。
             * */
                init.prototype = jQuery.fn;
            }
         //2. 对外暴漏$
            window.jQuery = window.$ = jQuery;
        })(window);
    	
         //外面调用一下子
        console.log($());//jQuery.fn.init
    	
        // 扩展一个jQ弹出框插件
        $.fn.alert = function(msg){
             alert(msg);
        }
        // 实例的继承结构:init实例 ==> init.prototype ==> Object.prototype ==> null
        //第一种创建实例的方法
         $().alert('hi01');//创建的对象可以进行访问
         //第二种创建实例的方法
        new $.fn.init().alert('hi02');//创建的对象可以进行访问扩展的插件
    

jQ对不同函数的处理

  1. 代码

     console.log($('title'));//获取dom  该用法使用频率最高
     console.log($('<div>1</div><div>2</div>'));//[div, div]
     console.log($([1, 2, 3, 4]));//很少使用
     console.log($(function() {})); // 该用法使用频率其次
        
     //传入的函数会在DOM构建完毕后执行
     $(function(){
         console.log($('span'));
     });
    

jQ对不用参数的处理结果

  1. 5种处理结果
    1. 传入转换为布尔类型为false的数据,得到空实例
    2. 传入函数,得到空实例,不过这个函数会在DOM树构建完毕后执行
    3. 传入字符串,如果是html字符串,则创建元素;如果不是,则当做选择器去页面中获取元素
    4. 传入数组或者伪数组(arguments,jQ实例,自定义的伪数组),把他们下标存储的数据依次存储到实例中
    5. DOM元素,以及其他数据类型,直接把数据以下标为0存储到实例中
  2. 代码

     /*
     * jQ对不用参数的处理结果:
     * 1、传入转换为布尔类型为false的数据,得到空实例
     * 2、传入函数,得到空实例,不过这个函数会在DOM树构建完毕后执行
     * 3、传入字符串,如果是html字符串,则创建元素;如果不是,则当做选择器去页面中获取元素
     * 4、传入数组或者伪数组(arguments,jQ实例,自定义的伪数组),把他们下标存储的数据依次存储到实例中
     * 5、DOM元素,以及其他数据类型,直接把数据以下标为0存储到实例中
     * */
    
     // 1、传入转换为布尔类型为false的数据,得到空实例
     console.log($(undefined));
     console.log($(null));
     console.log($(0));
     console.log($());
     console.log($(NaN));
     console.log($(''));
    
     // 2、传入函数,得到空实例,不过这个函数会在DOM树构建完毕后执行
     console.log($(function () {
         console.log('DOM树构建完毕后执行');
     }));
    
     // 3、传入字符串,如果是html字符串,则创建元素
     console.log($('<span><a>a1</a></span><span><a>a2</a></span>'));
    
     // 3、传入字符串,如果不是html字符串,则当做选择器去页面中获取元素
     console.log($('div'));
    
     // 4、传入数组或者伪数组(arguments,jQ实例,自定义的伪数组),把他们下标存储的数据依次存储到实例中
     console.log($([1, 2, 3, 4]));
     console.log($({0:'abc', 1:'cba', length:2}));
     console.log($( document.querySelectorAll('div') ));
    
     // 5、DOM元素,以及其他数据类型
     console.log($(document.querySelector('body')));
     console.log($( 123 ));
     console.log($( new Date() ));
     console.log($( {age: 16, name: '小花'} ));
    

    </script> span1 span2 span3

、、注意 jQ中数据都是以伪数组的形式进行存储的

函数的length&window的length

  1. 函数默认就有length属性,代表该函数形参的个数
  2. window的length属性,代表页面中有多少iframe元素
  3. window对象有一个特征:window有一个window属性,指向自己
  4. 代码

         /*
         *函数默认就有length属性,代表该函数形参的个数
             * window的length属性,代表页面中有多少iframe元素
         * window对象有一个特征:window有一个window属性,指向自己
         * */
         function fn(){};
         console.log(fn.length);//0
    	
         function fn2(a,b,c){};
         console.log(fn2.length);//3  是参数的个数,是形参的个数
    	
         $(function(){
             console.log(window.length);//1  是window中iframe中的个数
         });
         console.log(window.window === window);//true
    	
     </script>
     <iframe src="http://www.baidu.com" frameborder="0"></iframe>
    

in和hasOwnProperty

  1. 总结
    1. in运算符:
      1. 属性名 in 对象,判断对象是否拥有某个属性的使用权
      2. ,in不在乎是不是自己。
      3. ,in是运算符
    2. hasOwnProperty是方法
      1. hasOwnProperty判断一个属性是不是自己的
  2. 代码

     var obj = {
         val : false
     }
     console.log('val' in obj);//true  obj有val这个属性
     console.log(obj.hasOwnProperty('val'));//true
    
     console.log('toString' in obj);//true  在其原型链上
     console.log(obj.hasOwnProperty('toString'));//只在自己的身上找 false
    

通过伪数组获取一个真数组

  1. 借用数组的slice方法,可以通过伪数组获取一个真数组
  2. call将obj的指向[],可以调用slice方法,slice之后返回的是是一个数组对象
  3. 对数组的值进行操作
  4. 代码

     /*
     *
     * */
     var obj = {
         0:1,
         1:10,
         2:100,
         length:3
     };
     var arr = [1,2,3,4,5,6,7];
     //[1,2,3,4,5,6,7]
    
     console.log(arr.slice());
     console.log(arr.slice(1, -1));//[2, 3, 4, 5, 6]
    
    
     // 借用数组的slice方法,可以通过伪数组获取一个真数组
     //call将obj的指向[],可以调用slice方法,slice之后返回的是是一个数组对象
     //对数组的值进行操作
     console.log([].slice.call(obj));//[1, 10, 100] 12/11/2016 11:52:12 PM 
    

如何判断DOM树已经构建完毕


Similar Posts

Comments