二、构造jQuery对象3——原型属性和方法

// 涉及外部代码行:48——70
var arr = [];

var document = window.document;

var getProto = Object.getPrototypeOf;

var slice = arr.slice;

var concat = arr.concat;

var push = arr.push;

var indexOf = arr.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var fnToString = hasOwn.toString;

var ObjectFunctionString = fnToString.call(Object);


// 代码行:146——255
// 主要代码
jQuery.fn = jQuery.prototype = {

    // The current version of jQuery being used
    // jquery表示正在使用的jQuery版本号
    jquery: version,

    // constructor指向构造函数jQuery()。
    constructor: jQuery,

    // The default length of a jQuery object is 0
    // length表示当前jQuery对象中元素的个数。
    length: 0,

    // .toArray(),将当前jQuery对象转换为真正的数组,转换后的数组包含了所有的元素
    toArray: function () {
        return slice.call(this);
        // 连同slice()一起声明的还有concat()、push()、indexOf()、toString()、hasOwn()、fnToSting()、objectFunctionSting()这些方法。这里通过声明这些核心方法的引用,使的在jQuery代码中可以借用这些核心方法的功能,执行时可通过方法call()和apply()指定方法执行的环境,即关键字this所引用的对象。
    },

    // Get the Nth element in the matched element set OR
    // Get the whole matched element set as a clean array
    // get([index]),返回当前jQuery对象中指定位置的元素或包含了全部元素的数组。
    get: function (num) {

        // Return all the elements in a clean array
        //如果没有传入参数,则返回包含了所有元素的新数组。
        if (num == null) {
            return slice.call(this);
        }

        // Return just the one element from the set
        // 如果制定了参数index,则返回一个单独的元素;参数index从0开始计算,并且支持负数,负数表示从元素集合末尾开始计算。
        return num < 0 ? this[num + this.length] : this[num];
    },

    // Take an array of elements and push it onto the stack
    // (returning the new matched element set)
    // 创建一个新的空jQuery对象,然后把DOM元素集合放入这个jQuery对象中,并保留对当前jQuery对象的引用。
    // 原型方法pushStack()是核心方法之一,它为以下方法提供支持
    // DOM遍历:parent()、parents()、parentsUntil()、next()、prev()、nextAll()、prevAll()、nextUntil()、prevUntil()、siblings()、children()、contents()
    // jQuery 对象遍历:map()、slice()、first()、last()、eq()
    // DOM插入:jQuery.append(),jQuery.prepend(),jQuery.before(),jQuery.after(),jQuery.replaceWith()
    // DOM查找、过滤:find()、not()、filter()、closest()、add()、andSelf()
    pushStack: function (elems) {
        // 参数elems:将放入新jQuery对象的元素数组(或类数组对象)

        // Build a new jQuery matched element set
        // 构造一个新的空jQuery对象ret,this.constructor指向构造函数函数jQuery,并把参数elems合并到jQuery对象ret中。
        var ret = jQuery.merge(this.constructor(), elems);

        // Add the old object onto the stack (as a reference)
        // 在新的jQuery对象ret上设置属性prevObject,指向当前jQuery对象,从而形成一个链式栈。因此,方法.pushStack()的行为还可以理解为,构建一个新的jQuery对象并入栈,新对象位于栈顶,这也是该方法如此命名的原因所在。
        ret.prevObject = this;

        // Return the newly-formed element set
        // 最后返回新jQuery对象ret。
        return ret;
    },

    // Execute a callback for every element in the matched set.
    // 方法.each()遍历当前jQuery对象,并在每个元素上执行回调函数。每当回调函数执行时,会传递当前循环次数作为参考,循环次数从0开始计数;更重要的是,回调函数是在当前元素为上下文的语境中触发的,即关键字this总是指向当前元素;在回调函数中返回false可以终止遍历。
    each: function (callback) {
        return jQuery.each(this, callback);
    },

    //  .map()遍历当前jQuery对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jQuery对象中。该方法常用于获取或设置DOM元素集合的值。
    map: function (callback) {
        // 执行回调函数时,关键字this指向当前元素。回调函数可以返回一个独立的数据项或数据项数组,返回值将被插入结果集中;如果返回一个数组,数组中的元素会被插入结果集;如果回调函数返回null或undefined,则不会插入任何元素。
        return this.pushStack(jQuery.map(this, function (elem, i) {
            return callback.call(elem, i, elem);
        }));
    },

    // .slice(start,[end])将匹配元素集合缩减为指定范围的子集;
    slice: function () {
        return this.pushStack(slice.apply(this, arguments));
    },

    // .first()将匹配的集合缩减为集合中的第一个元素;
    first: function () {
        return this.eq(0);
    },

    // .last()将匹配的集合缩减为集合中的最后一个元素;
    last: function () {
        return this.eq(-1);
    },

    // .eq(index)将匹配元素集合缩减为集合中指定位置的元素;
    eq: function (i) {
        var len = this.length,
            j = +i + (i < 0 ? len : 0);
        return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
    },

    // 方法.end()结束当前链条中最近的筛选操作,并将匹配元素集合还原为之前的状态。
    end: function () {
        // 返回前一个jQuery对象。如果属性prevObject不存在,则构建一个空的jQuery对象返回。
        // 方法.pushStack()用于入栈。方法.end()则用于出栈。
        return this.prevObject || this.constructor();
    },

    // For internal use only.
    // Behaves like an Array's method, not like a jQuery method.
    // 方法.push(value,...)向当前jQuery对象的末尾添加新元素,并返回新长度。
    // 方法.sort([orderfunc])对当前jQuery对象中的元素进行排序,可以传入一个比较函数来指定排序方式。
    // 方法.splice(start,deleteCount,value,...)向对前jQuery对象中插入、删除或替换元素。
    push: push,
    sort: arr.sort,
    splice: arr.splice
};

 

posted @ 2019-04-01 14:04  道鼎金刚  阅读(178)  评论(0)    收藏  举报