【JS特性】解析各大框架的插件系统
2023/02/10 14:18:37
jQuery 对象扩展
如何扩展 jQuery 对象
jQuery 中提供了 $.extend()
和 $.fn.extend()
两个方法来扩展 jQuery 对象。
$.extend()
可以给 $
对象绑定属性,绑定后可通过 $.
的形式访问:
$.extend({
getName() {
console.log("extend name");
},
});
$.getName();
$.fn.extend()
可以给 jQuery 的原型对象绑定属性,绑定后所有的 jQuery 对象都可以访问:
$.fn.extend({
getFnName() {
console.log("fn extend name");
},
});
$().getFnName();
解析 jQuery 的插件系统
实际上这两个方法其实是一个方法:$.extend === $.fn.extend === function () {}
。
这里只考虑传入单个对象作为参数的情况,关键源码如下:
jQuery.extend = jQuery.fn.extend = function () {
var options,
name,
copy,
target = arguments[0] || {},
i = 1,
length = arguments.length,
// 只传一个参数时
if (i === length) {
target = this;
i--;
}
for (; i < length; i++) {
// 参数不为 null (赋值语句),options为传入的对象
if ((options = arguments[i]) != null) {
for (name in options) {
copy = options[name]; // name为传入对象属性的 key,copy 为 value
// 禁止修改原型对象,禁止传入自身对象: $.extend({aa: $})、$.fn.extend({aa: $.fn})
if (name === "__proto__" || target === copy) {
continue;
}
// 属性值存在时赋值
if (copy !== undefined) {
target[name] = copy;
}
}
}
}
// Return the modified object
return target;
};
可以看到最终的复制语句为 target[name] = copy
,只是将 target 赋值为 this
以实现给调用方法的对象赋值。
简易实现
核心思路:将属性绑定到 this
上,谁调用方法,就给谁绑定。
function jQuery() {
return new init();
}
function init() {}
init.prototype = jQuery.fn = jQuery.prototype = {};
jQuery.extend = jQuery.fn.extend = function (obj) {
for (let key in obj) {
this[key] = obj[key];
}
};
$ = jQuery;