用 JS 封装一个库的基本思路

165 阅读1分钟

今天我尝试用JS来实现jQuery中最简单的API:addClass,一共有三种写法,以供参考。

假设html中有5个class为red的div

    <div class="red">1</div>
    <div class="red">2</div>
    <div class="red">3</div>
    <div class="red">4</div>
    <div class="red">5</div>

第一种:使用闭包

        function jQuery(选择器){
            const 所有标签 = document.querySelectorAll(选择器)
            const 标签数组 = Array.from(所有标签)
            return {addClass(className){
                标签数组.forEach(标签 => 标签.classList.add(className))
            },
            removeClass(){
                标签数组.forEach(标签 => 标签.classList.remove(className))
            }
        }}
        const $ = jQuery
        $('.red').addClass('green') //调用

多次调用 $ 时造成内存冗余,但是不需要用到new

第二种:使用构造函数(原型写法)

        function jQuery(选择器){
            const 所有标签 = document.querySelectorAll(选择器)
            this.标签数组 = Array.from(所有标签)
        }
        jQuery.prototype = {
            constructor: jQuery,
            addClass(className){this.标签数组.forEach(标签 => 标签.classList.add(className))},
            removeClass(className){this.标签数组.forEach(标签 => 标签.classList.remove(className))}
        }
        const $ = jQuery
        new $('.red').addClass('green')

第三种:使用 class

class jQuery{
            constructor(选择器){
                const 所有标签 = document.querySelectorAll(选择器)
                this.标签数组 = Array.from(所有标签)
            }
            addClass(className){this.标签数组.forEach(标签 =>标签.classList.add(className))}
            removeClass(className){this.标签数组.forEach(标签 => 标签.classList.remove(className))}
        }
        const $ = jQuery
        new $('.red').addClass('black')

总结

以上三种方式都可以用来封装库,除了使用的语法略有不同之外,其基本思路都是相似的:将我们封装好的代码放入一个作用域中,并将其作为一个可以被外部访问和使用的对象返回。这样,我们就可以像使用其他第三方库一样,使用我们自己封装的库了。