深入学习jquery源码之jQuery的构造函数与实例化

2023-10-30

深入学习jquery源码之jQuery的构造函数与实例化

创建jQuery对象的整个流程如下:

1、调用$()方法;

2、调用jQuery.prototype.init()构造函数;

3、根据选择器不同返回不同的jQuery对象;

4、不同jQuery对象中公用的方法写在jQuery.prototype中;

5、将jQuery.prototype传递给jQuery.prototype.init.prototype,这样新创建的对象才可以访问公用方法;

 

创建jquery对象的四个步骤

第一步:创建jquery构造函数,并且实例化jQuery.fn.init(jquery的构造函数)。因为实例化的不是jQuery对象所以这上面不会挂载jQuery的方法,同时通过原型链也访问不到,jQuery使用了无new构造:将init()构造函数的定义放在了jQuery.prototype里面

jQuery = function (selector, context) {
            // The jQuery object is actually just the init constructor 'enhanced'
            // Need init if jQuery is called (just allow error to be thrown if not included)
            return new jQuery.fn.init(selector, context);
}

 

在jQuery中,$是jQuery的别名,执行“$()”就是执行“jQuery()”,执行“$()”返回的是一个jQuery对象

    var
        // Map over jQuery in case of overwrite
        _jQuery = window.jQuery,

        // Map over the $ in case of overwrite
        _$ = window.$;

    jQuery.noConflict = function (deep) {
        if (window.$ === jQuery) {
            window.$ = _$;
        }

        if (deep && window.jQuery === jQuery) {
            window.jQuery = _jQuery;
        }

        return jQuery;
    };

    // Expose jQuery and $ identifiers, even in
    // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
    // and CommonJS for browser emulators (#13566)
    if (typeof noGlobal === strundefined) {
        window.jQuery = window.$ = jQuery;
    }
    return jQuery;

 

第二步:此方法则是用来扩展jQuery的实例方法,也就是说jQuery类的实例对象可以调用此函数

   $.fn.extend({

   theAlert:function(){

      alert("自定义的函数");

    }

  })

  $("thediv").theAlert()

jQuery.fn指向jQuery.prototype,jQuery.fn执行jQuery的原型对象。我们可以通过实例化的静态方法也就是我们的工具方法挂载在jQuery上,也可以获得jQuery.prototype上的属性。这样我们调用的时候不需要去实例化,而是可以直接去调用,将对象的方法挂载到jQuery.prototype上,我们系需要实例化之后才能够使用,针对的this的操作。

    jQuery.fn = jQuery.prototype = {
        // The current version of jQuery being used
        jquery: version,

        constructor: jQuery,

        // Start with an empty selector
        selector: "",

        // The default length of a jQuery object is 0
        length: 0,

        toArray: function () {
            return slice.call(this);
        },

        // Get the Nth element in the matched element set OR
        // Get the whole matched element set as a clean array
        get: function (num) {
            return num != null ?

                // Return just the one element from the set
                (num < 0 ? this[num + this.length] : this[num]) :

                // Return all the elements in a clean array
                slice.call(this);
        },

        // Take an array of elements and push it onto the stack
        // (returning the new matched element set)
        pushStack: function (elems) {

            // Build a new jQuery matched element set
            var ret = jQuery.merge(this.constructor(), elems);

            // Add the old object onto the stack (as a reference)
            ret.prevObject = this;
            ret.context = this.context;

            // Return the newly-formed element set
            return ret;
        },

        // Execute a callback for every element in the matched set.
        // (You can seed the arguments with an array of args, but this is
        // only used internally.)
        each: function (callback, args) {
            return jQuery.each(this, callback, args);
        },

        map: function (callback) {
            return this.pushStack(jQuery.map(this, function (elem, i) {
                return callback.call(elem, i, elem);
            }));
        },

        slice: function () {
            return this.pushStack(slice.apply(this, arguments));
        },

        first: function () {
            return this.eq(0);
        },

        last: function () {
            return this.eq(-1);
        },

        eq: function (i) {
            var len = this.length,
                j = +i + (i < 0 ? len : 0);
            return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
        },

        end: function () {
            return this.prevObject || this.constructor(null);
        },

        // For internal use only.
        // Behaves like an Array's method, not like a jQuery method.
        push: push,
        sort: deletedIds.sort,
        splice: deletedIds.splice
    };

 

第三步:jQuery.fn.extend(object)为jQuery对象添加方法,此方法是用来扩展jQuery类,它所方法是全局性,直接用jQuery类即可引用

$.extend({minValue:function(a,b){return a<b?a:b;}})

$.minValue(5.6);
    jQuery.extend = jQuery.fn.extend = function () {
        var src, copyIsArray, copy, name, options, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        // Handle a deep copy situation
        if (typeof target === "boolean") {
            deep = target;

            // skip the boolean and the target
            target = arguments[i] || {};
            i++;
        }

        // Handle case when target is a string or something (possible in deep copy)
        if (typeof target !== "object" && !jQuery.isFunction(target)) {
            target = {};
        }

        // extend jQuery itself if only one argument is passed
        if (i === length) {
            target = this;
            i--;
        }

        for (; i < length; i++) {
            // Only deal with non-null/undefined values
            if ((options = arguments[i]) != null) {
                // Extend the base object
                for (name in options) {
                    src = target[name];
                    copy = options[name];

                    // Prevent never-ending loop
                    if (target === copy) {
                        continue;
                    }

                    // Recurse if we're merging plain objects or arrays
                    if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && jQuery.isArray(src) ? src : [];

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

                        // Never move original objects, clone them
                        target[name] = jQuery.extend(deep, clone, copy);

                        // Don't bring in undefined values
                    } else if (copy !== undefined) {
                        target[name] = copy;
                    }
                }
            }
        }

        // Return the modified object
        return target;
    };

$.each方法的实现

	$.each(obj,function(j,k){})
	
	jQuery.extend({
	        // args is for internal usage only
        each: function (obj, callback, args) {
            var value,
                i = 0,
                length = obj.length,
                isArray = isArraylike(obj);

            if (args) {
                if (isArray) {
                    for (; i < length; i++) {
                        value = callback.apply(obj[i], args);

                        if (value === false) {
                            break;
                        }
                    }
                } else {
                    for (i in obj) {
                        value = callback.apply(obj[i], args);

                        if (value === false) {
                            break;
                        }
                    }
                }

                // A special, fast, case for the most common use of each
            } else {
                if (isArray) {
                    for (; i < length; i++) {
                        value = callback.call(obj[i], i, obj[i]);

                        if (value === false) {
                            break;
                        }
                    }
                } else {
                    for (i in obj) {
                        value = callback.call(obj[i], i, obj[i]);

                        if (value === false) {
                            break;
                        }
                    }
                }
            }

            return obj;
        }
  });

 

第四步:定义jquery的init构造方法

    // A central reference to the root jQuery(document)
    var rootjQuery,

        // Use the correct document accordingly with window argument (sandbox)
        document = window.document,

        // A simple way to check for HTML strings
        // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
        // Strict HTML recognition (#11290: must start with <)
        rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

        init = jQuery.fn.init = function (selector, context) {
            var match, elem;

            // HANDLE: $(""), $(null), $(undefined), $(false)
            if (!selector) {
                return this;
            }

            // Handle HTML strings
            if (typeof selector === "string") {
                if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
                    // Assume that strings that start and end with <> are HTML and skip the regex check
                    match = [null, selector, null];

                } else {
                    match = rquickExpr.exec(selector);
                }

                // Match html or make sure no context is specified for #id
                if (match && (match[1] || !context)) {

                    // HANDLE: $(html) -> $(array)
                    if (match[1]) {
                        context = context instanceof jQuery ? context[0] : context;

                        // scripts is true for back-compat
                        // Intentionally let the error be thrown if parseHTML is not present
                        jQuery.merge(this, jQuery.parseHTML(
                            match[1],
                            context && context.nodeType ? context.ownerDocument || context : document,
                            true
                        ));

                        // HANDLE: $(html, props)
                        if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
                            for (match in context) {
                                // Properties of context are called as methods if possible
                                if (jQuery.isFunction(this[match])) {
                                    this[match](context[match]);

                                    // ...and otherwise set as attributes
                                } else {
                                    this.attr(match, context[match]);
                                }
                            }
                        }

                        return this;

                        // HANDLE: $(#id)
                    } else {
                        elem = document.getElementById(match[2]);

                        // Check parentNode to catch when Blackberry 4.6 returns
                        // nodes that are no longer in the document #6963
                        if (elem && elem.parentNode) {
                            // Handle the case where IE and Opera return items
                            // by name instead of ID
                            if (elem.id !== match[2]) {
                                return rootjQuery.find(selector);
                            }

                            // Otherwise, we inject the element directly into the jQuery object
                            this.length = 1;
                            this[0] = elem;
                        }

                        this.context = document;
                        this.selector = selector;
                        return this;
                    }

                    // HANDLE: $(expr, $(...))
                } else if (!context || context.jquery) {
                    return (context || rootjQuery).find(selector);

                    // HANDLE: $(expr, context)
                    // (which is just equivalent to: $(context).find(expr)
                } else {
                    return this.constructor(context).find(selector);
                }

                // HANDLE: $(DOMElement)
            } else if (selector.nodeType) {
                this.context = this[0] = selector;
                this.length = 1;
                return this;

                // HANDLE: $(function)
                // Shortcut for document ready
            } else if (jQuery.isFunction(selector)) {
                return typeof rootjQuery.ready !== "undefined" ?
                    rootjQuery.ready(selector) :
                    // Execute immediately if ready is not present
                    selector(jQuery);
            }

            if (selector.selector !== undefined) {
                this.selector = selector.selector;
                this.context = selector.context;
            }

            return jQuery.makeArray(selector, this);
        };

    
	//init()构造函数最后返回了这个新对象的引用,并用jQuery的原型覆盖了init()的原型。等价于jQuery.prototype.init = function() {...return this;}
    // Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;

    // Initialize central reference
    rootjQuery = jQuery(document);	

    新创建的对象无法访问jQuery.prototype中的其他属性,解决方法是:将jQuery.prototype传递jQuery.prototype.init.prototype:
    只有jQuery.fn.init的原型指向jQuery.fn(jQuery.prototype),这样我们在使用的时候就能够通过实例化的对象访问到挂载在jQuery.fn上的属性。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入学习jquery源码之jQuery的构造函数与实例化 的相关文章

  • 深入学习jquery源码之trigger()与triggerHandler()

    深入学习jquery源码之trigger 与triggerHandler trigger type data 概述 在每一个匹配的元素上触发某类事件 这个函数也会导致浏览器同名的默认行为的执行 比如 如果用trigger 触发一个 subm
  • 深入学习jquery源码之before()和after()

    深入学习jquery源码之before 和after after content fn 概述 在每个匹配的元素之后插入内容 参数 content String Element jQuery 插入到每个目标后的内容 function Func
  • 深入学习jquery源码之map()

    概述 将一组元素转换成其他数组 不论是否是元素数组 你可以用这个函数来建立一个列表 不论是值 属性还是CSS样式 或者其他特别形式 这都可以用 map 来方便的建立 参数 callback 给每个元素执行的函数 把form中的每个input
  • 深入学习jquery源码之Deferred对象与holdReady()

    深入学习jquery源码之Deferred对象与holdReady jQuery的Deferred对象也有resolve reject then方法 还有done fail always 方法 jQuery就是用这个Deferred对象来注
  • 深入学习jquery源码之jQuery的构造函数与实例化

    深入学习jquery源码之jQuery的构造函数与实例化 创建jQuery对象的整个流程如下 1 调用 方法 2 调用jQuery prototype init 构造函数 3 根据选择器不同返回不同的jQuery对象 4 不同jQuery对
  • 深入学习jquery源码之jQuery的选择器引擎Sizzle(一)

    深入学习jquery源码之jQuery的选择器引擎Sizzle Sizzle是一个纯javascript CSS选择器引擎 jquery1 3开始使用sizzle Sizzle一反传统采取了相反的Right To Left的查询匹配方式 效
  • 深入学习jquery源码之弹出框插件实现

    深入学习jquery源码之弹出框设计 jquery自带的提示框 messager confirm 提示 您确定通过吗 function r if r 弹出框插件 function window undefined var COOKIE US
  • 深入学习jquery源码之is()与not()

    深入学习jquery源码之is 与not is expr obj ele fn 概述 根据选择器 DOM元素或 jQuery 对象来检测匹配元素集合 如果其中至少有一个元素符合这个给定的表达式就返回true 如果没有元素符合 或者表达式无效
  • 深入学习jquery源码之attr()与removeAttr()

    深入学习jquery源码之attr 与removeAttr attr name properties key value fn 概述 设置或返回被选元素的属性值 参数 name String 属性名称 properties Map 作为属性
  • 深入学习jquery源码之noConflict()

    深入学习jquery源码之noConflict jQuery noConflict extreme 概述 运行这个函数将变量 的控制权让渡给第一个实现它的那个库 执行 var jq noConflict 后 将不再控制当前的jQuery 而
  • 深入学习jquery源码之empty()与返回值remove()

    深入学习jquery源码之empty 与返回值remove empty 概述 删除匹配的元素集合中所有的子节点 把所有段落的子元素 包括文本节点 删除 p Hello span Person span a href and person a
  • 深入学习jquery源码之查询选择插件的实现

    深入学习jquery源码之上传查询选择插件的实现 function var defaults url fieldCode multi false area 40 80 code code name 注意顺序 先是code 再是name fu
  • 深入学习jquery源码之wrap()和wrapAll()

    深入学习jquery源码之wrap 和wrapAll wrap html element fn 概述 把所有匹配的元素用其他元素的结构化标记包裹起来 这种包装对于在文档中插入额外的结构化标记最有用 而且它不会破坏原始文档的语义品质 这个函数
  • 深入学习jquery源码之获取url中参数插件

    深入学习jquery源码之获取url中参数插件 function window undefined 定义 通用工具方法 扩展对象基元 coreUtil function return Object apply this arguments
  • 深入学习jquery源码之each()

    each 遍历一个数组或对象 可以是DOM json等格式 等价于for循环 返回值 jQuery each callback 参数 对于每个匹配的元素所要执行的函数 概述 以每一个匹配的元素作为上下文来执行一个函数 意味着 每次执行传递进
  • 深入学习jquery源码之append()和prepend()

    深入学习jquery源码之append 和prepend append content fn 概述 向每个匹配的元素内部追加内容 这个操作与对指定的元素执行appendChild方法 将它们添加到文档中的情况类似 参数 content St
  • 深入学习jquery源码之isFunction()和isPlainObject()

    深入学习jquery源码之isFunction 和isPlainObject isArray obj 概述 测试对象是否为数组 参数 obj Object 用于测试是否为数组的对象 b append isArray b true b isF
  • 深入学习jquery源码之replaceWith()和replaceAll()

    深入学习jquery源码之replaceWith 和replaceAll replaceWith content fn 概述 将所有匹配的元素替换成指定的HTML或DOM元素 参数 content String Element jQuery
  • 深入学习jquery源码之data()

    深入学习jquery源码之data jQuery data element key value 概述 在元素上存放数据 返回jQuery对象 注意 这是一个底层方法 你应当使用 data 来代替 此方法在jQuery 1 8中删除 但你仍然
  • 深入学习jquery源码之addClass()和toggleClass()与hasClass()

    深入学习jquery源码之addClass 和toggleClass 与hasClass addClass class fn 概述 为每个匹配的元素添加指定的类名 参数 class String 一个或多个要添加到元素中的CSS类名 请用空

随机推荐

  • 7-3 组个最小数 (20 分)

    7 3 组个最小数 20 分 给定数字0 9各若干个 你可以以任意顺序排列这些数字 但必须全部使用 目标是使得最后得到的数尽可能小 注意0不能做首位 例如 给定两个0 两个1 三个5 一个8 我们得到的最小的数就是10015558 现给定数
  • 【数据结构】链表的基本操作

    文章目录 1 单链表的定义 2 单链表上的基本操作 2 1采用头插法建立单链表 2 2采用尾插法建立单链表 2 3按序号查找结点数据 2 4按值查找表结点 2 5插入节点操作 2 6删除节点操作 3 代码演示 4 编译结果 1 单链表的定义
  • Android 调用微信登陆、支付、分享,出现的白屏、黑屏、闪屏问题。

    当我在去调用微信的登录界面 或者其他支付界面 WXEntryActivity又一个界面 这样看起来很不协调 WXEntryActivity类finish的时候会有闪屏的效果 为了让用户感觉只是拉起了一个授权界面 需要加上 android t
  • python自然语言处理入门-新手上路

    新手上路 博主微信公众号 左 Python 智能大数据 AI学习交流群 右 欢迎关注和加群 大家一起学习交流 共同进步 目录 摘要 1 自然语言与编程语言 2 自然语言处理的层次 2 1 语音 图像和文本 2 2 中文分词 词性标注和命名实
  • 1400*A. World Football Cup(模拟)

    Problem 19A Codeforces 解析 模拟 记录总得分 净胜球 进球数 坑点 其中注意净胜球是进球数的差 己方进球数 对手进球数 可以为负数 排序即可 include
  • 前端大文件下载方案

    前端大文件下载方案 文章目录 前端大文件下载方案 JSZip StreamSaver js 与 JSZip 结合使用 mitm sw 配置 tags Streams API Service Worker StreamSaver js JSZ
  • 安装kubeadm

    kubeadm是一个部署K8S的一个方式 又是一个芬兰人 又是一个高中生 但是貌似不支持生产目前 但是对于尝鲜学习K8S是一个不错的方式 安装其实不麻烦 但是吧有些东西因为某些限制导致你安装不了 下载不下来 就好比原先下载安卓的SDK挂一晚
  • 点灯游戏2-15游戏解答

    快来快来学一学 点灯游戏 2 15求解 N N 解法遍历 储存 local A local B local C local N 0 local t local s 0 local function addt local t N N 灯变化记
  • Obsidian中如何创作思维导图Mind-map

    使用插件 obsidian mind map 1 直接在社区下载安装 设置快捷键或者在左侧竖形打开命令面板搜索关键字 mind 或者为了便于使用 设置快捷键 在设置 第三方插件中 选择快捷键 然后按下你想设置的快捷键就可以 我这里设置成了C
  • Permission denied: user=dr.who, access=READ_EXECUTE, inode="/tmp":root:supergroup:drwx------

    今天在做Hadoop 分布式实例的时候遇到了这个错误 Permission denied user dr who access READ EXECUTE inode tmp root supergroup drwxrwx 出错原因 tmp
  • sql企业版和标准版区别_一张图看懂OPPO Reno 3标准版和Pro版的区别

    随着发布会的临近 OPPO Reno 3系列的硬件参数被彻底曝光 虽然普通版和Pro版都支持双模5G网络 但是为了不同的定位 这2款手机在主要硬件配置上区别还是蛮大的 根据官方和工信部的消息 亓纪将两款手机的的硬件参数做了一个对比 通过一张
  • 云计算、大数据、人工智能时代,为什么不能错过Linux?

    随着这些年互联网技术的迅猛发展 在快速步入大数据 云计算 虚拟技术和人工智能时代 技术为王现象在信息科技领域越来越凸显出来 随之而来的是高端Linux运维人才出现了极度紧缺的现象 为什么要选择Linux 说起Linux 大家可能都知道好 优
  • 免费开源的箱包制造行业ERP管理系统介绍

    用Odoo免费开源ERP按需打造可持续商业模型 广东百立皮具是一家集生产 采购 定制 销售为一体的箱包及配饰贸易公司 专营各类箱包皮革制品 产品业务规模遍布全世界 百立皮具距今运营已有十余年之久 拥有千余名员工 且在多国都开设了分公司 多年
  • matplotlib中堆积图、分块图、气泡图的绘制

    本文介绍matplotlib中堆积图 分块图 气泡图的绘制 堆积图的绘制 堆积图常用于综合展示不同分类的指标趋势以及它们的总和的趋势 比如说 我们想看一下5名同学期末的总分情况 同时 我们又想看一下这5名同学的各科成绩以及它们各自的占比 这
  • uni-app——小程序实现本地图片的上传以及身份证的智能识别

    文章目录 前言 一 示例图 二 实现过程 1 完成提交图片的api地址 2 获取本地图片 3 将本地图片上传至开发者服务器 三 具体实现代码 四 身份证的智能识别 总结 前言 上传本地图片的功能很常见 那么具体该如何实现呢 一 示例图 二
  • 顶尖程序员的五种思维模式

    一 勇于研究你不懂的代码 通过研究不同的代码 从而熟悉不同的代码结构和设计模式 二 精通代码调试 几乎所有的代码都不是一遍写好 学会怎么去调试代码 三 重视能够节约时间的工具 工具是很重要的 它们能帮我们节省大量的时间 四 优化你的迭代速度
  • python调用自己写的py文件

    目录 python如何调用自己写的py文件呢 如果是不同目录怎么调用呢 如果需要调用的多个文件在多个目录呢 关于 init py的解释 关于sys path的解释 python如何调用自己写的py文件呢 同一个目录下直接写import xx
  • IP地址网段表示法

    http blog sina com cn s blog 4a1d691b010004qx html 1 IP地址 共分为四类 A B C D类 各类范围详见RFC参考 2 子网掩码 子网掩码的作用是用来表示IP地址中的多少位用来表示主机号
  • 23种设计模式之模板模式

    文章目录 概述 模版模式的优缺点 优点 缺点 模版模式的使用场景 模板模式的结构和实现 模式结构 模式实现 总结 概述 模板模式指 一个抽象类中 有一个主方法 再定义1 n个方法 可以是抽象的 也可以是实际的方法 定义一个类 继承该抽象类
  • 深入学习jquery源码之jQuery的构造函数与实例化

    深入学习jquery源码之jQuery的构造函数与实例化 创建jQuery对象的整个流程如下 1 调用 方法 2 调用jQuery prototype init 构造函数 3 根据选择器不同返回不同的jQuery对象 4 不同jQuery对