资讯专栏INFORMATION COLUMN

jQuery源码解读:部份jQuery工具方法实现

Rindia / 417人阅读

摘要:作为前端最流行的类库,没有之一,源码必须得读一读。本博将不定期更新源码解读内容,如果解读不正确的地方,还请同学们在评论中指正。这里使用的是改变的指向为实例。其实就是中常见的四判断是否是数字函数用于检查其参数是否是无穷大。

jQuery作为前端最流行的类库,没有之一,源码必须得读一读。本博将不定期更新源码解读内容,如果解读不正确的地方,还请同学们在评论中指正。

本系列文章基于jquery-1.9.1.js。(编者注:虽然JQ已经出到2.X,本文所述的方法是基本方法,没有版本之差,对于学习有所帮助)

一、$.type() 判断js数据类型

用法:$.type(new Array()); //array

部份源码(截取关键部份,请忽略源码语法):

//生成typelist的map
class2type = {}
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

//每个对象实例都有toString方法
core_toString = class2type.toString

//主方法
type: function( obj ) {
    if ( obj == null ) {
        return String( obj );
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ core_toString.call(obj) ] || "object" :
        typeof obj;
}

解读:

1、class2type生成后的内容为
var class2type = {
    "[object Boolean]":"boolean",
    "[object Number]":"number",
    "[object String]":"string",
    "[object Function]":"function",
    "[object Array]":"array",
    "[object Date]":"date",
    "[object RegExp]":"regexp",
    "[object Object]":"object",
    "[object Error]":"error"
}
2、core_toString使用的是对象实例的toString

所有继随自Object的对象都有toString方法,为什么一定要使用object.toString,因为array,function虽然有toString方法,但该方法进行了重写,array调用toString打印的数组成员用逗号隔开的字符串。这里使用的是{}.toString.call(obj);改变toString的this指向为object实例。jquery为什么使用的是class2type.toString.call,这样就可以少声明一个object。

var func = function(){};
var arr = [];
console.log({}.toString.call(func)); //[object Function]
console.log({}.toString.call(arr)); //[object Array]

这样就得到class2type的键名,以此判断数据类型。

二、$.each() 遍历一个数组或对象。

each()其实还是使用的for来进行循环的,除了方便外,因其做了一下简单的封装,所以效率还是要比for差,对于大型循环,尽量使用for.

三、$.trim() 去除字符串两端的空格。
rtrim = /^[suFEFFxA0]+|[suFEFFxA0]+$/g
core_version = "1.9.1"
//仅仅是使用字符串的trim方法
core_trim = core_version.trim

//主方法,首先尝试使用字符串原生的trim方法(非IE支持)
//不支持的话,使用String.prototype.trim.call("uFEFFxA0")
//最后使用正则replace
trim: core_trim && !core_trim.call("uFEFFxA0") ?
    function( text ) {
        return text == null ?
            "" :
            core_trim.call( text );
    } :

    // 上述两个方法不支持,使用自定义的方法,清空两边的空格或特殊字符
    function( text ) {
        return text == null ?
            "" :
            ( text + "" ).replace( rtrim, "" );
    }

该方法需要解释的是,“uFEFF”和“xA0”。

某些软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM),转码后是“uFEFF”,因此我们在读取时需要自己去掉这些字符。

“xA0”其实就是HTML中常见的“ ”

四、$.isNumeric() 判断是否是数字
isNumeric: function( obj ) {
    return !isNaN( parseFloat(obj) ) && isFinite( obj );
}

isFinite() 函数用于检查其参数是否是无穷大。如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。

五、$.isEmptyObject() 判断对象是否为空
isEmptyObject: function( obj ) {
    var name;
    for ( name in obj ) {
        return false;
    }
    return true;
}

这个方法很好懂,就不多解释

六、$.parseJSON() 将JSON字符串转换为JSON对象
// JSON RegExp
rvalidchars = /^[],:{}s]*$/,
rvalidbraces = /(?:^|:|,)(?:s*[)+/g,
rvalidescape = /(?:["/bfnrt]|u[da-fA-F]{4})/g,
rvalidtokens = /"[^"
]*"|true|false|null|-?(?:d+.|)d+(?:[eE][+-]?d+|)/g

parseJSON: function( data ) {
    // 如果有原生的JSON对象支持,使用原生对象
    if ( window.JSON && window.JSON.parse ) {
        return window.JSON.parse( data );
    }

    if ( data === null ) {
        return data;
    }

    if ( typeof data === "string" ) {

        // 去掉两端空格,制表符,bom
        data = jQuery.trim( data );

        if ( data ) {
            // 保证输入的字符串是可用的JSON字符串
            if ( rvalidchars.test( data.replace( rvalidescape, "@" )
                .replace( rvalidtokens, "]" )
                .replace( rvalidbraces, "")) ) {
                console.log(data);
                return ( new Function( "return " + data ) )();
            }
        }
    }

    jQuery.error( "Invalid JSON: " + data );
}

这个方法主要是看上面几个正则表达式,从字符串转JSON对象,仅仅是使用return ( new Function( “return ” + data ) )();

七、$.globalEval() 在全局作用域执行一段JS脚本
// 在全局作用域执行JS脚本
globalEval: function( data ) {
    if ( data && jQuery.trim( data ) ) {
        // 在IE中使用execScript
        // 因为使用匿名函数,所以作用域使用的是window
        ( window.execScript || function( data ) {
            window[ "eval" ].call( window, data );
        } )( data );
    }
}

jQuery该方法源于:Jim Driscoll

方法原理:eval作用域问题

var a = "window";
function b(){
    eval("var a = "b"");
}
b();
alert(a); //a的结果为window;IE、chrome、FF结果一致
window.eval和eval不一样的地方:

var a = "window";
function b(){
    window.eval("var a = "b"");
}
b();
alert(a); //IE下还是a的结果还是window,chrome、FF的a的结果b

via Just Jason"s Blog

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85472.html

相关文章

  • 轻轻松松自己写一个jquery库-要不要试试?

    摘要:是现在最流行的工具库。据统计,目前全世界的网站使用它。好,说了这么多我们就看看自己写一个库,有没有你想想的那么难。写法写法三事件的监听四类操作的方法,用于为元素添加一个。 jQuery是现在最流行的JavaScript工具库。据统计,目前全世界57.3%的网站使用它。也就是说,10个网站里面,有6个使用jQuery。如果只考察使用工具库的网站,这个比例就会上升到惊人的91.7%。 因此...

    beita 评论0 收藏0
  • 前端基础进阶(十一):详细图解jQuery对象,以及如何扩展jQuery插件

    摘要:而在构造函数中,返回了的实例对象。在中直接返回过的实例,这里的是的真正构造函数最后对外暴露入口时,将字符与对等起来。因此当我们直接使用创建一个对象时,实际上是创建了一个的实例,这里的正真构造函数是原型中的方法。 showImg(https://segmentfault.com/img/remote/1460000008749398); 早几年学习前端,大家都非常热衷于研究jQuery源...

    RebeccaZhong 评论0 收藏0
  • jQuery的ready函数源码解读

    摘要:学习有许多途径,我们今天从的函数开始。本例中的代码都来自于脚本库。我们在通过函数注册事件处理之前,完成了页面检测代码的注册。当页面完全加载之后,我们注册的函数就被调用了。八参考的函数是如何工作的函数实现原理 如果你对$(document).ready()的理解也仅限于在DOM Tree绘制完毕后触发,那么,你也应该好好研究下ready的工作原理,因为,TST的面试官问过我这个问题。。。...

    soasme 评论0 收藏0
  • cordova研习笔记(二) —— cordova 6.X 源码解读(上)

    摘要:本文源码为版本。的代码结构也是一个很经典的定义结构构造函数实例修改函数原型共享实例方法,它提供事件通道上事件的订阅撤消订阅调用。 前言 cordova(PhoneGap) 是一个优秀的经典的中间件框架,网上对其源代码解读的文章确实不多,本系列文章试着解读一下,以便对cordova 框架的原理理解得更深入。本文源码为cordova android版本6.1.2。 源码结构 我们使用IDE...

    Java_oldboy 评论0 收藏0
  • JavaScript专题系列20篇正式完结!

    摘要:写在前面专题系列是我写的第二个系列,第一个系列是深入系列。专题系列自月日发布第一篇文章,到月日发布最后一篇,感谢各位朋友的收藏点赞,鼓励指正。 写在前面 JavaScript 专题系列是我写的第二个系列,第一个系列是 JavaScript 深入系列。 JavaScript 专题系列共计 20 篇,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里...

    sixleaves 评论0 收藏0

发表评论

0条评论

Rindia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<