尝试用JS来实现jQuery中简单的API: addClass
注:为方便理解,变量名用了中文名
一、使用闭包实现
function jQuery(选择器) {
const 标签伪数组 = document.querySelectorAll(选择器)
const 标签数组 = Array.from(标签伪数组)
return {
addClass(className) {
标签数组.forEach((标签) => {
标签.classList.add(className)
})
return this
},
removeClass(className) {
标签数组.forEach((标签) => {
标签.classList.remove(className)
})
return this
}
}
}
const $ = jQuery
// 这样就能用jQuery的方式调用了,return this是为了可以链式调用
$('li').addClass('red').removeClass('green')
- querySelectorAll获取到的是一个伪数组,伪数组和真数组的区别在于,伪数组只有数组的自由属性,但没有数组的共有属性
- 用闭包实现的缺点:
- 当多次调用$ 时, 如调多次下面的代码,会在内存中重复创建addClass,造成内存冗余
$('li').addClass('red')
二、使用构造函数实现
function jQuery(选择器) {
// 为了不使用new调用
if (!(this instanceof jQuery)) {
return new jQuery(选择器)
}
const 标签伪数组 = document.querySelectorAll(选择器)
this.标签数组 = Array.from(标签伪数组)
}
jQuery.prototype = {
constructor: jQuery,
addClass(className) {
this.标签数组.forEach((标签) => {
标签.classList.add(className)
})
return this
},
removeClass(className) {
this.标签数组.forEach((标签) => {
标签.classList.remove(className)
})
return this
}
}
const $ = jQuery
$('li').addClass('red').removeClass('green')
三、使用class实现
class jQueryClass {
constructor(选择器) {
const 标签伪数组 = document.querySelectorAll(选择器)
this.标签数组 = Array.from(标签伪数组)
}
addClass(className) {
this.标签数组.forEach((标签) => {
标签.classList.add(className)
})
return this
}
removeClass(className) {
this.标签数组.forEach((标签) => {
标签.classList.remove(className)
})
return this
}
}
function jQuery(选择器) {
return new jQueryClass(选择器)
}
const $ = jQuery
$('li').addClass('red').removeClass('green')