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.each
和jQuery.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()