为什么jQuery.extend被定义为jQuery函数属性,jQuery.fn.extend 被定义为jQuery原型



jQuery被定义为一个函数

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

jQuery.fn.extend被定义为原型对象属性 - 因此在this范围内可用

为什么以这种方式定义jQuery.extend因为jQuery实际上不是一个对象,而是一个函数?

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

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

注意到

jQuery.fn === jQuery.prototype 

这是一个对象{},jQuery是一个函数

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

我在jQuery代码中没有看到jQuery设置为新的jQuery()实例的任何地方。在jQuery结构器中,我看到返回的唯一实例是init函数,即返回新的jQuery.fn.init()。

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

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

现在在我的测试中,扩展函数中的"this"指的是jQuery函数而不是对象实例,因此该函数正在使用函数之外的额外"属性"进行扩展。我不明白的是,当函数尚未使用任何实例创建进行实例化时,如何向函数添加/扩展对象属性?

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()

最新更新