實(shí)現(xiàn)一個(gè)自制jQuery框架
理解jquery
jquery常用方法如下
$("body") //選擇對象返回對象
$("body").foo() //對選中每個(gè)對象使用方法
$.ajax() //調(diào)用特定模塊
那么要要實(shí)現(xiàn)jquery從什么入手呢荒辕?
分步實(shí)現(xiàn)類jquery庫nQuery
- 我們創(chuàng)建一個(gè)構(gòu)造函數(shù)
var nQuery = function (selector, context) {
console.log("我是nQuery")
}
nQuery() //我是nQuery
此時(shí)可以調(diào)用nQuery方法
- 下面要讓nQuery像jquery那樣使用$就能調(diào)用
var nQuery = function (selector, context) {
console.log("我是nQuery")
}
window.$ = window.nQuery = nQuery
$() //我是nQuery
ok現(xiàn)在我們已經(jīng)可以使用方便的方法來調(diào)用它了柬祠。
- 接下來我們要為nQuery增加功能
var nQuery = function (selector, context) {
return nQuery.prototype
}
nQuery.prototype = {
foo: function () {
console.log("我是方法一")
},
bad: function () {
console.log("我是方法二")
}
}
window.$ = window.nQuery = nQuery
$().foo() //我是方法一
$().bad() //我是方法二
此時(shí),運(yùn)行$()返回nQuery的原型捶闸,又在nQuery的原型上增加了方法拷沸,此時(shí)可以使用jquery的方法調(diào)用nQuery原型上的方法了
- 現(xiàn)在我們的nQuery已經(jīng)可以調(diào)用方法了延届,但是它所有的方法都寫在原型上椭符,每個(gè)實(shí)例都是調(diào)用的相同的方法,數(shù)據(jù)沒有私密性耻姥,下面來改進(jìn)以下
var nQuery = function (selector, context) {
return new nQuery.prototype.foo(selector, context)
}
nQuery.prototype = {
foo: function () {
//nothing
},
bad: function () {
console.log("我是方法二")
},
good: function () {
console.log("我是方法三")
}
}
//讓foo的原型等于nQuery的原型销钝,這樣每次new的對象都可以調(diào)用nQuery圓型的方法。切每次調(diào)用$()時(shí)候返回的對象既有自己私有的屬性琐簇,也可調(diào)用公共的方法
nQuery.prototype.foo.prototype = nQuery.prototype
window.$ = window.nQuery = nQuery
$().good() //我是方法三
$() //foo {} 此時(shí)返回的是一個(gè)新對象蒸健,這個(gè)對象指向nQuery原型中foo方法
- 上面的方法雖然?實(shí)現(xiàn)了,但是不夠漂亮婉商,接下來對上面的nQuery進(jìn)行優(yōu)化
var nQuery = function (selector, context) {
return new nQuery.prototype.init(selector, context)
}
nQuery.prototype = {
constructor: nQuery,
init: function (selector, context) {
this.selector = selector
this.context = context
}
}
nQuery.prototype.init.prototype = nQuery.prototype
//使用extent方法時(shí)似忧,把obj里邊的屬性放到this里邊,當(dāng)nQuery調(diào)用的時(shí)候丈秩,會把obj的this綁定到nQuery的this上盯捌,讓obj可以使用nQuery的原型
nQuery.extent = nQuery.prototype.extent = function (obj) {
for (var key in obj) {
this[key] = obj[key]
}
}
//這里是$.ajax()類調(diào)用方法
nQuery.extent({
isArray: Array.isArray,
ajax: function () {
console.log("ajax")
}
})
nQuery.prototype.extent({
addClass: function () {
console.log("addClass...")
},
sayHello: function () {
console.log("hello")
}
})
//這里是$().addClass()調(diào)用方法
//寫在這里方便對nQuery進(jìn)行拓展
// //學(xué)習(xí)jquery用$符和nQuery直接引用nQuery
window.nQuery = window.$ = nQuery
- 實(shí)現(xiàn)Jquery的鏈?zhǔn)秸{(diào)用
$(".div").addClass().attr()
jQuery支持以上方法,它是怎么實(shí)現(xiàn)的呢蘑秽?
其實(shí)每次調(diào)用?例如addClass()這樣的函數(shù)時(shí)饺著,它會在函數(shù)調(diào)用完時(shí)候返回一個(gè)this箫攀,如下代碼
nQuery.prototype.extent({
addClass: function () {
console.log("addClass...")
return this
},
sayHello: function () {
console.log("hello")
return this
}
})
這樣便可實(shí)現(xiàn)?jquery的鏈?zhǔn)秸{(diào)用了
好了以上我們實(shí)現(xiàn)了jquery的骨架了,后面需要什么方法就可以在這上面增加方法了