为什么 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.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()
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.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()