为什么 jQuery.extend 定义为 jQuery 函数 属性 而 jQuery.fn.extend 定义为 jQuery 原型对象 属性

Why is jQuery.extend defined as a jQuery function property and jQuery.fn.extend defined as a jQuery prototype object property

jQuery 定义为 函数

jQuery.extend 被定义为一个 函数 属性 并且它本身就是一个函数 - 但不适用于任何 this 作用域。

jQuery.fn.extend 被定义为原型 object 属性 - 因此在 this

范围内可用

为什么要这样定义 jQuery.extend,因为 jQuery 实际上不是一个对象,它是一个函数?

作为参考,令人困惑的代码行是:

jQuery.extend = jQuery.fn.extend = function() {...} 

注意到

jQuery.fn === jQuery.prototype 

这是一个对象 {} 并且 jQuery 是一个函数

这意味着直接使用 jQuery.extend 没有为 this 上下文实例化的对象。

我在 jQuery 代码的任何地方都没有看到 jQuery 被设置为新的 jQuery() 实例。在 jQuery 构造函数中,我看到的唯一实例 returned 是针对 init 函数的,即 return new jQuery.fn.init().

在文档就绪函数的运行时,如果您检查对象的类型 jQuery 和 $ 是什么,您将看到它仍然是一个函数(不是对象实例)。因此,每当使用一个参数调用 jQuery.extend 时,该函数将尝试扩展 jQuery 本身,但使用 "this" 作为目标对象,即代码片段

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

现在在我的测试中,extend 函数中的 "this" 指的是 jQuery function 而不是对象实例,因此该函数被额外扩展"properties"关闭功能。我不明白的是,当尚未使用任何 new 实例创建实例化函数时,如何 add/extend 对象属性到函数?

jQuery.extend 实际上只是一个用于合并对象的实用函数。它类似于 jQuery 库启动时不存在的更现代的 Object.assign()

它在核心中广泛用于向 jQuery 对象本身添加属性,但也可供开发人员使用 $.extend(target [, object1 ] [, objectN ] )

合并他们自己的对象

因为它被用作静态方法,所以没有 new 个实例。

还有其他几种 jQuery 方法既在内部用作实用函数又公开公开,例如 jQuery.eachjQuery.fn.each,它们先于现代 Array#forEach() 但也可以用来迭代对象


在您自己的代码中使用它可以让您做到

var a = {x:1},
    b = {y:2},
    res = $.extend({}, a, b)

console.log(res) // new object { "x": 1,  "y": 2}
console.log(a) // unmodified - still {x:1}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


至于您提到的 target = this; 部分,可以使用具有 属性 功能的简单对象来解释。由于调用上下文,函数中的 this 是对象本身。

在源核心中调用时,对象是 jQuery

简单对象示例:

var obj = function() {};
obj.x = 1;
obj.log = function() {
  // `this` is `obj`
  console.log('this.x = ', this.x)
}


obj.log()