jQuery 中的设计模式

链式风格

也叫jQuery风格

window.jQuery()是我们提供的全局函数

特殊函数jQuery

jQuery(选择器)用于获取对应的元素,但它却不返回这些元素。

相反,它返回一个对象,称为jQuery构造出来的对象,这个对象可以操作相应的元素。

image-20210504152456575.png

image-20210504152512743.png

jQuery是构造函数吗?

因为jQuery函数确实构造出了一个对象

不是

因为不需要写new jQuery()就能构造一个对象

以前讲的构造函数都要结合new才行,比如var obj = new Object()

结论

jQuery是一个不需要加new的构造函数

jQuery不是常规意义上的构造函数

这是因为jQuery用了一些技巧

术语

jQuery对象

jQuery对象指代jQuery函数构造出来的对象,也就是那个api

jQuery对象不是说jQuery这个对象

举例

Object是个函数,Object对象表示Object构造出的对象

Array是个函数,Array对象/数组对象表示Array构造出来的对象

Function是个函数,Function对象/函数对象表示Function构造出来的对象

手写jQuery

源码

命名风格

下面代码令人误解

const div = $('div#test')

我们会误以为div是一个DOM,实际上div是jQuery构造的api对象

改成这样

const $div = $('div#test')

$div.appendChild不存在,因为它不是DOM对象

$div.find存在,因为它是jQuery对象

链式风格

$('<div><span>1</span></div>')

返回值并不是新增的元素,而是api对象

$('<div><span>1</span></div>').appendTo(document.body)

appendTo可以把新增的元素放到另一个元素里,类似上面这样操作

总结

感觉DOM是不可见的,不需要知道DOM的任何细节,只需要使用简洁的API即可

一个好的封装,能让使用者完全不知道内部细节,只是通过闭包实现的

如果想知道细节怎么办

举例1
const $div = $('div#test')
复制代码

$div并不是DOM对象,而是jQuery构造的api对象

如何从$div中得到div呢?

$div.get(0) 获取第0个元素 //div
$div.get(1) 获取第1个元素 //undefined
$div.get(2) 获取第2个元素 //undefined
$div.size() 得到元素的个数
$div.length 也可以得到元素的个数
$div.get() 获取所有元素组成的数组 //[div]
复制代码
举例2
const $div = $('.red') //假设有3个div.red
复制代码

$div不是DOM对象们,而不是jQuery构造的api对象

如何从$div中得到div呢?

一样的

$div.get(0) 获取第0个元素 //div
$div.get(1) 获取第1个元素 //div
$div.get(2) 获取第2个元素 //div
$div.size() 得到元素的个数
$div.length 也可以得到元素的个数
$div.get() 获取所有元素组成的数组 //[div,div,div]
复制代码

$div.get(0)太麻烦,使用更简单的$div[0]

重新开始写链式风格

$('#xxx') //返回值并不是元素,而是一个api对象
$('#xxx').find('.red') //查找#xxx里的.red元素
$('#xxx').parent() //获取新爸爸
$('#xxx').children() //获取儿子
$('#xxx').siblings() //获取兄弟
$('#xxx').index() //获取排行老几(从0开始)
$('#xxx').next() //获取弟弟
$('#xxx').prev() //获取哥哥
$('.red').each(fn) //遍历并对每个元素执行fn
复制代码
$('body') // 获取document.body
$('body').append($'<div>1</div>') //添加小儿子
$('body').append('<div>1</div>') //更方便
$('body').prepend(div或$div) //添加大儿子
$('#test').after(div或$div) //添个弟弟
$('#test').before(div或$div) //添个哥哥
复制代码
$div.remove()
$div.empty()
复制代码
$div.text(?) //读写文本内容
$div.html(?) //读写HTML内容
$div.attr('title',?) //读写属性
$div.css({color: 'red'}) //读写style //$div.style更好,但是jQuery是用的css
$div.addClass('blue')/removeClass/hasClass // 添加 / 移除 / 检查是否有
$div.on('click',fn)
$div.off('click',fn)
复制代码

注意:$div可能对应了多个div元素

后续

使用原型

把共有属性(函数)全都放到$.prototype

$.fn=$.prototype //名字太长

然后让api.__proto__指向$fn

设计模式

jQuery用到了哪些设计模式

不用new的构造函数,这个模式没有专门的名字

$(支持多种参数),这个模式叫做重载

用闭包隐藏细节,这个模式没有专门的名字

$div.text()既可读也可写,getter/setter

$.fn$.prototype的别名,这叫别名

jQuery针对不同浏览器使用不同代码,这叫适配器

设计模式是什么?

设计模式就是对通用代码取个名字

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享