jQuery的封装和扩展方式

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title></title>
    </head>

    <body>
    </body>
    <script type="text/javascript">
(function(){

function jQuery(){
    // 一个对象工厂,以后生成新对象不用new了,直接执行这个方法即可。
    return new jQuery.fn.init();
}

// jQuery的初始方法
jQuery.fn = jQuery.prototype = {
    init:function(){

    }
};

jQuery.prototype.init.prototype = jQuery.fn;
// 修正构造器指向
jQuery.prototype.constructor = jQuery;

// 扩展方法
// 这个方法外部用依赖jQuery.type和jQuery.isPlainObject方法。
// 内部第一次用不会用到jQuery.type和jQuery.isPlainObject。
// 1.只有一个参数,且类型是对象,则对jQuery或者jQuery实例进行扩展
// 2.第一个参数是bool值,则来确定是否深拷贝。
// 3.深拷贝是指 拷贝值和被拷贝值都是对象,则进一步遍历复制,而不是直接覆盖。
// 比如{a:{"1":1}},{a:{"2":2}},浅拷贝结果是{a:{"2":2}},深拷贝结果是{a:{"1":1,"2":2}}
// 4.拷贝时要进行循环引用判断
// 5.对被拷贝值不是数组,不是普通对象,强行生成一个新的。
// 6.可以对多个参数进行合并
jQuery.extend = jQuery.fn.extend = function() {

    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // 第一个参数是bool值,第二个参数是目标值,索引从第三个参数开始
    // 第一个参数bool为true表示深拷贝
    if ( typeof target === "boolean" ) {
        deep = target;
        target = arguments[1] || {};
        i = 2;
    }

    // target不是object,不是array,不是正则,不是日期,不是function,则目标值是一个空对象。
    // typeof object,array,正则,日期 == "object"
    // typeof这个判断方法让人很揪心呐
    // 确定被拷贝对象是个{}类型
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }

    // 确定被拷贝对象是个{}类型,自己写的
    //    var targetType = jQuery.type(target);
    //    var targetType_arr = ["object","function","array","date","regexp"];
    //    if(targetType_arr.indexOf(targetType) == -1){
    //        target = {};
    //    }

    // 只有一个参数传入,目标值是jQuery函数自己,或者jQuery对象。看谁调用了。
    if ( length === i ) {
        target = this;
        --i;
    }

    // 开始遍历复制
    for ( ; i < length; i++ ) {
        // 不是null或undefined的参数才可以,要知道null == undefined是true
        if ( (options = arguments[ i ]) != null ) {

            for ( name in options ) {
                // 拿到老,新同个key对应的value值
                src = target[ name ];
                copy = options[ name ];

                // 防止循环引用
                // 当拷贝值是被拷贝的对象,跳出循环
                if ( target === copy ) {
                    continue;
                }

                // 深拷贝,拷贝值非undefined,是普通对象或者是数组
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        // 确定一下 被拷贝值也是个数组
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // 递归调用
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // 只要不是undefined,就可以赋值
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // 返回被拷贝的对象
    return target;
};

// jQuery的类方法
jQuery.extend({
    type:function(obj){
        return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
    },
    isArray :Array.isArray,
    isNumeric : function( obj ) {
        // 不是无穷,不是NaN就是数字
        return !isNaN( parseFloat(obj) ) && isFinite( obj );
    },
    isPlainObject:function(obj){
        //普通对象不是DOM节点 或者 不是window对象 或者 是‘object‘
        if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
            return false;
        }

        // 当然类似window.location这种对象也不是普通对象,因为它不是来自Object
        // 一切普通对象来自Object。而Object.prototype.isPrototypeOf存在
        if ( obj.constructor &&
                !Object.hasOwnProperty.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }

        return true;
    },
    isEmptyObject: function( obj ) {
        var name;
        for ( name in obj ) {
            return false;
        }
        return true;
    },
    isFunction: function( obj ) {
        return jQuery.type(obj) === "function";
    },
    isWindow:function(obj){
        // window对象里面有window属性
        return obj != null && obj === obj.window;
    }

});

// jQuery的实例方法
jQuery.fn.extend({
    css:function(){
        alert("css");
    }
});

// 模块化和挂载
~function(){
    // CMD
    if ( typeof module === "object" && module && typeof module.exports === "object" ) {
        module.exports = jQuery;
    } else {
    // AMD
        if ( typeof define === "function" && define.amd ) {
            define( "jquery", [], function () { return jQuery; } );
        }
    }

    // 挂载全局变量
    if ( typeof window === "object" && typeof window.document === "object" ) {
        window.jQuery = window.$ = jQuery;
    }
}();

})();

        var arr = jQuery.extend({},{"c":[5,6]})
        console.log(arr);

        var a = jQuery.type(999);
        alert(a)
    </script>

</html>

  

时间: 2024-11-08 21:57:41

jQuery的封装和扩展方式的相关文章

利用jQuery对插件进行扩展时,方法$.extend()、$.fn.extend()区别与联系

  利用JQ开发插件的方法: 1.jQuery.extend(); 2.jQuery.fn.extend(); 3.通过$.widget()应用jQuery UI的部件工厂方式创建. 由于第三种方式通常用于开发比较高级的jQuery的部件,开发难度较大,所以第一种和第二种方式用的更为广泛,下面主要对前两种方式的区别和联系以及使用的方法做一些介绍. 简要的说明一下: jQuery是一个封装的非常好的类,$(“#btn”)就相当于创建了一个jQuery的实例. 1.方法jQuery.fn .exte

jQuery中插件开发两种方式

最近挺多人写jQuery的,都是关于jQuery扩展方面的,使用方面的讲的比较多,但是关于详细的一个基础的过程讲的比较少一点,做web开发的基本上都会用到jQuery,本人就根据jQuery的使用经验讲讲插件开发.jQuery插件开发两种方式:一种是类扩展的方式开发插件,jQuery添加新的全局函数(jQuery的全局函数是属于jQuery命名空间的函数),如果将jQuery看成一个类,那么就相当于给jQuery类本身添加方法.第二种是对象扩展的方式开发插件,即jQuery对象添加方法. 类扩展

用GCD的方式,加载网络图片(主线程加载图片+类扩展方式)

用GCD的方式,加载网络图片(主线程加载图片+类扩展方式) 用两种方法来实现网络加载图片 方法1:实现的效果:先加载背景色灰色,两秒后加载图片 - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor=[UIColor grayColor]; //刷新UI(在主线程中刷新UI!!!) --- 一般方法 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PR

jQuery Ajax封装通用类 (linjq)

jQuery Ajax封装通用类 (linjq) $(function(){ /** * ajax封装 * url 发送请求的地址 * data 发送到服务器的数据,数组存储,如:{"date": new Date().getTime(), "state": 1} * async 默认值: true.默认设置下,所有请求均为异步请求.如果需要发送同步请求,请将此选项设置为 false. * 注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行. * t

SeaJS中jQuery插件模块化及其调用方式

转载自:http://my.oschina.net/briviowang/blog/208587#OSC_h3_1 jQuery插件本质上是将命名空间挂在全局的jQuery或jQuery.fn上而非使用define定义的模块. JQuery的这种扩展机制同模块化要求模块的独立性,以及模块互相隔离有点冲突. jQuery插件数目众多,我们不打算做大量的转换工作,为模块化而模块化,甚至改变插件的调用方式, 这样对开发带来的价值不大.只希望通过模块加载器实现自动的依赖管理,按需加载,并且使用方式自然.

Python基础-封装与扩展、静态方法和类方法

一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个良好的合作基础--或者说,只要接口这个基础约定不变,则代码改变不足为虑. 实例: 1 #类的设计者 2 class Room: 3 def __init__(self,name,owner,width,length,high): 4 self.name=name 5 self.owner=owner

jQuery内部原理和实现方式浅析

这篇文章主要介绍了jQuery内部原理和实现方式浅析,本文试图从整体来阐述一下jQuery的内部实现,需要的朋友可以参考下 这段时间在学习研究jQuery源码,受益于jQuery日益发展强大,研究jQuery的大牛越来越多,学习的资料也比前两年好找了,有很多非常不错的资源,如高云的jQuery1.6.1源码分析系列.这些教程非常细致的分析了jQuery内部原理和实现方式,对学习和理解jQuery有非常大的帮助.但是个人认为很多教程对jQuery的整体结果把握不足,本人试图从整体来阐述一下jQue

QGIS功能扩展方式

在QGIS使用时,经常需要对QGIS现有功能进行扩展或是在其基础上定制开发行业应用程序,一般有以下五种方法: 在PYTHON控制台直接执行PYTHON脚本利用在PYTHON控制台编写PYTHON脚本进行地图数据处理. 优点:没有任何编程基础的人也可以上手. 缺点:只能在控制台执行脚本,没有任何图形交互界面.一般只适用于地图数据处理这类需求使用.详细见:https://user.qzone.qq.com/2665146134/blog/1521197818 插件开发这种方式是QGIS官方推荐使用的

jQuery框架-3.jQuery自定义封装插件和第三方插件

一.jQuery的封装扩展 1.jQuery中extend方法使用 (挂在到jQuery和jQuery.fn两对象身上的使用) 1.1.官方文档定义: jQuery.extend   Merge the contents of two or more objects together into the first object.把两个或者多个对象合并到第一个对象当中: jQuery.fn.extend   Merge the contents of an object onto the jQue