jQuery api 的本质

jQuery 本质是接受一个节点返回一个对象,一个对该节点各种操作方法组成的对象

如下:

let $div = $('div')    // 形参 dom 获得实例
$div.addClass('blue')  // 调用对形参 dom 的方法(= 对实参操作)

jQuery 示例代码

// 注:以下为简易版代码,未实现链式操作

let jQuery = function(nodesOrSelector) {
    let nodes = {}
    if(typeof nodesOrSelector === 'string') {
        nodes = document.querySelectorAll(nodesOrSelector)
    } else {
        nodes = nodesOrSelector
    }
    return {
        addClass: function (className) {
            for(let i=0; i<nodes.length; i++) {
                nodes[i].classList.add(className)
            }
        },
        text: function (textContent) {
            for(let i=0; i<nodes.length; i++) {
                nodes[i].innerText = textContent
            }
        }
    }
}
window.$ = jQuery

let $divs = $('div')
$divs.addClass('red')
$divs.text('hello')

封装常用操作的其他两种办法

使用命名空间

命名空间的优点是:代码可复制给别人使用

命名空间的缺点是:调用方式不太简洁

写入公用属性

写入公用属性的好处是:调用起来异常简洁

写入公用属性的坏处是:污染全局变量(你加我也加,最后这个 prototype 被大家毁了)

不难发现,以上两种办法的优缺点刚好是相反的。而 jQuery 的做法(把函数封装成对象)兼具双方的优点。既创建自己的命名空间又能直接调用。

总结

  1. jQuery 封装 dom 常用操作,是通过把函数封装成对象实现的
  2. 封装常用操作还有两种方式,使用命名空间写入公用属性

改进

可以链式调用的 jQuery

function jQuery(node) {
  ...
  return {
    ...
    addClass: function(className) {
      node.classList.add(className)
      return jQuery(node)
    }
  }
}