原型的实际应用及原型的插件扩展机制
原型的实际应用
zepto 如何使用原型
HTML 部分代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<body>
<p>zepto test 1</p>
<p>zepto test 2</p>
<p>zepto test 3</p>
<div id="div1">
<p>zepto test in div</p>
</div>
<script type="text/javascript" src="./my-zepto.js"></script>
<script type="text/javascript">
var $p = $('p')
$p.css('font-size', '40px')
alert($p.html())
var $div1 = $('#div1')
$div1.css('color', 'blue')
alert($div1.html())
</script>
</body>
模拟zepto的实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38(function (window) {
var zepto = {}
function Z(dom, selector) {
var i, len = dom ? dom.length : 0
for (i = 0; i < len; i++) {
this[i] = dom[i]
}
this.length = len
this.selector = selector || ''
}
zepto.Z = function (dom, selector) {
return new Z(dom, selector)
}
zepto.init = function (selector) {
var slice = Array.prototype.slice
var dom = slice.call(document.querySelectorAll(selector))
return zepto.Z(dom, selector)
}
var $ = function (selector) {
return zepto.init(selector)
}
window.$ = $
$.fn = {
css: function (key, value) {
alert('css')
},
html: function (value) {
return '这是一个模拟的 html 函数'
}
}
Z.prototype = $.fn
})(window)
在上面的代码中定义一个自执行函数,防止全局污染,只通过 $
暴露给全局。
通过 $
变量的选择器函数,传入选择器,再到 zepto.init
进行对选择到 dom 元素的类数组使用 slicew
方法进行数组化,再到 zepto.Z
中调用 Z
构造函数,将 查询到的 dom 元素类数组结果集添加到实例的属性,并添加 length
属性和 selector
属性。将封装好的方法放入 $.fn
对象之中,并将 $.fn
对象赋值给 Z.prototype
,通过这样的方式,每一个选择器返回的实例都会有封装好的方法。
jQuery 如何使用原型
HTML 部分:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<body>
<p>jquery test 1</p>
<p>jquery test 2</p>
<p>jquery test 3</p>
<div id="div1">
<p>jquery test in div</p>
</div>
<script type="text/javascript" src="./my-jquery.js"></script>
<script type="text/javascript">
var $p = $('p')
$p.css('font-size', '40px')
alert($p.html())
var $div1 = $('#div1')
$div1.css('color', 'blue')
alert($div1.html())
</script>
</body>
1 | (function (window) { |
与 zepto 类似。
自执行函数,防止全局污染,只通过 $
暴露给全局。
通过构造函数jQuery.fn.init
实例化对象,再通过给 jQuery.fn
对象添加属性,再赋值给构造函数 init
的 prototype
的形式添加原型方法。
原型的插件扩展机制
zepto 和 jQuery 的扩展机制
在 zepto 和 jQuery 中,都有一样的插件扩展机制:将扩展的方法放在 $.fn
下,再赋值给构造函数的 prototype
难道不可以直接将 $.fn
对象里的内容赋值给构造函数的 prototype
吗?为什么要先放在放在 $.fn
下,再赋值给构造函数的 prototype
。这是不是有点多此一举?
其实并非多此一举。
为什么要把原型方法放在 $.fn
?
其他的 jQuery 插件是怎么添加方法的呢?
下面是一个简单的例子:
1 | $.fn.geuNodeName = function () { |
为什么扩展方法并不是直接添加到构造函数的 prototype
上,而是添加到 $.fn
上呢。
一开始插件就是自执行函数,是封闭的作用域,只对外暴露了 $
对象,所以只能通过 $
来添加方法。
这样做的好处就是:
- 只有 $ 会暴露在 windows 全局变量中
- 将插件扩展统一到 $.fn.xxx 这一接口,方便使用。