zoukankan      html  css  js  c++  java
  • (242-528)

    我们的extend在前面已经分析过了,我们执行jQuery.extend({}),实际就是向jQuery函数同名对象中添加属性。

    1. expando: "jQuery" + ( version + Math.random() ).replace( /D/g, "" ), ,随机生成一组字符串,这是当前页面jQuery的唯一标识,几乎不可能被外部访问到。

     isReady: true, jQuery是否准备好,先假设为true, error 方法后面讲。 jQuery.noop 就是一个空函数,比如当一个函数需要传入回调函数,我们又不需要执行回调的时候,传入它就可以了。

    2.在学习 isFunction 之前我们先研究一下其辅助 type 工具

    var class2type = {}
    var toString = class2type.toString;
    jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    });
    function type( obj ) {
            if ( obj == null ) {
                return obj + '' ;
            }
            // Support: Android < 4.0, iOS < 6 (functionish RegExp)
            return typeof obj === "object" || typeof obj === "function" ?
                class2type[ toString.call(obj) ] || "object" :
                typeof obj;
    }

    在JS中,toString在一些类中定义了特定的版本,如数组类的toString是将数组的每个元素转化为字符串,并通过,号结合成结果字符串。其它的一些类也都有相应的特定toString。对象的toString与他们不同(继承自Object.prototype),它将可以返回对象的类。格式为"object class"。注意是下面是对象的toString方法。

    console.log(Object.prototype.toString.call([])) //"[object Array]"
    console.log(Object.prototype.toString.call("")) //"[object String]"

    可以利用这个特定判断目标的类型,同时考虑null和undefined

    function classOf(o){
        if( o == null ) return o + '';
        return Object.prototype.toString.call(o).slice(8,-1).toLowerCase();
    }
    console.log(classOf(null)) //"null"
    console.log(classOf()) //"undefined"
    console.log(classOf(1)) //"number"
    console.log(classOf('')) //"string"
    console.log(classOf(false)) //"boolean"
    console.log(classOf({})) //"object"
    console.log(classOf([])) //"array"
    console.log(classOf(/./)) //"regexp"
    console.log(classOf(new Date())) //"date"
    console.log(classOf(window)) //"window"(客户端宿主对象)
    function f(){}
    console.log(classOf(new f())) //"object"

    jQuery的实现方法也大同小异。考虑了一些对手机兼容的处理。

     isFunction 实际就是调用type return jQuery.type(obj) === "function" 

    3. isArray: Array.isArray, 就是直接引用数组的方法。

     isWindow 实现的方法很多,jQuery是通过判断obj对象等同于其window属性。 return obj != null && obj === obj.window; 

     isNumeric 的主要是通过parseFloat和Number实现的判断。

    console.log(parseFloat('123a')); // 123 
    console.log(Number('123a')); // NaN 

    parseFloat可以很好的转换为数字,但有一个缺点就是字符串里有字符和数字时,它仍然会转化出数字。而Number可以解决这个问题。

    return obj - parseFloat( obj ) >= 0;

    这里利用 - 运算符,隐式转化obj为数字,然后通过关系运算符>=转化为布尔型,为什么用>=而不是==,<=,这里parseFloat('0xff') ,当其是以0开头的字符串,值为0,而实际它是数字。 所以 255 - 0>=0;在此基础上作者作了一些兼容,我们自己写的时候也可以按自己需求判断。

    4.纯粹对象指的是一般我们{}或new Object()创建的对象,这类对象继承的原型Object.prototype有自身的方法isPrototypeOf。

    {}.hasOwnProperty.call( a.constructor.prototype, "isPrototypeOf" )

    作者亦加入了一些辅助判断,排除不是对象类型,DOM节点,window对象。

     isEmptyObject 作者采用for in 如果有属性则不为空。这里的判断包括继承来的属性

    5. globalEval 主要利用eval来实现,下面分析下eval的几个不同表现,ES5下。

    //非严格,间接调用,在全局中定义
    function a(){
        var geval = eval;
        geval('var h = 1')
    }
    a();
    console.log(h) //1
    //非严格,直接调用,在全局中定义
    function a(){
        eval('var h = 1')
    }
    a();
    console.log(h) // h未定义
    //严格,直接或非直接调用,在全局中定义
    function a(){
        var geval = eval;
        eval('"use strict";var h = 1')
        eval('"use strict";var h = 1')
    }
    a();
    console.log(h) // h未定义

    在严格模式中,定义的变量是在私有作用域中。

    原理明白了,jQuery中的globalEval就很容易理解。它通过判断是否是严格模式,如果是,则创建一个脚本插入到页面中让它执行,如果不是,则利用Eval的,非严格间接调用。

     nodeName 判断节点标签名(elem.nodeName)与我们期望的是不是同一个,来判断是不是某类型节点。这方法在jQuery内部使用,比如当判断点击的是不是Input,nodeName(obj,'input')即可。

    each,trim之前已经讲过。

    6.虽然jQuery是类数组对象,可以[num],访问,也可以像数组那样遍历,但它还缺少一些对数组的内置方法(如.pop().reverse())。通过makeArray转化之后就可以使用这些方法。

    它考虑的情况有类数组对象,和非类数组对象,在分数组对象,就当一般元素直接插入。如果是类数组对象,比如$('div'),则将其元素依次插入空数组并返回。这里还有一个问题需要注意,字符串也是类数组对象,但我们希望它当做字符串处理。考虑到这些东西,源码就很容易理解了。jQuery.merge之前讲过,这里重复一遍它的作用,是将第二个数组类数组的元素,以此插入到第一个数组或类数组中,同时设置了length。

     inArray 方法是通过对目标调用indexOf,判断目标是否存在,作用扩大到类数组对象。 indexOf.call( arr, elem, i ) 

     grep 是过滤数组中的元素,功能思想是,遍历,执行回调函数,判断是否是期望的元素,是则插入到新建的期望数组中。最后返回期望数组。

    7. guid 针对目标的全局唯一标识。方便移除,事件部分细说。

     proxy :如果你了解 Function.prototype.bind ,那么这个方法你就很容易理解。下面给出一个简化的bind

    Function.prototype.bind = function (scope) {
        var fn = this;//这里fn为this,也就是调用bind的函数,方便下面调用
        return function () {//返回的是一个可以运行函数
            return fn.apply(scope);//利用apply方法,使用scope对象调用fn,
        };
    } 
    var b = {
        a : 1,
    }
    function fn(){
        console.log(this);
    }
    fn() //window
    var fnB = fn.bind(b); fnB()//{a:1}

    实现返回一个对原函数指定上下文的函数。

    回到源码,作者增加了对如下情况的处理

    var b = {
        a : 1,
        fn:function(){
            console.log(this)
        }
    }

    它是通过判断第二个是否为字符串,重新指定函数和要绑定的对象。

     !jQuery.isFunction( fn ) 判断如果还不是函数,就直接返回undefined;

    为实现部分参数调用,源码中的代码如下

        args = slice.call( arguments, 2 );
            proxy = function() {
                return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
            };

    它将先前已经传入的参数和后传入参数合并,做回retrun新函数的参数。

     proxy.guid = fn.guid = fn.guid || jQuery.guid++; 因为他们实际是一个函数,这里将原函数和生成函数指定为同一个GUID。方便移除。在事件中重点将Guid;

     now: Date.now  当前时间

     support  属性包含表示不同浏览器特性或漏洞的属性集。截止源码到这里还是引用的空对象,后面根据功能支持会产生属性。

  • 相关阅读:
    springboot @ConfigurationProperties 中文乱码解决方案
    Centos 7安装Mysql 5.7详细教程,Linux安装Mysql 5.7详细教程
    Centos7 mysql Unit not found,Centos7 在线安装mysql 5.7
    Windows Tomcat安装配置,Tomcat 启动闪退,Windows Tomcat中文乱码解决
    ubuntu 切换到 root 用户
    一行代码完成定时任务调度,基于Quartz的UI可视化操作组件 GZY.Quartz.MUI
    快速实现一个室内空气质量检测仪
    外设驱动库开发笔记36:NTC负温度系数热电阻测温驱动
    外设驱动库开发笔记34:OLED显示屏驱动
    滤波器开发之五:基于算术平均的限幅滤波器
  • 原文地址:https://www.cnblogs.com/winderby/p/4153723.html
Copyright © 2011-2022 走看看