為什么要有面向對象的思維,因為如果不這樣,你可能需要一個方法的時候就去定義一個function,當需要另外一個方法的時候,再去隨便定義一個function,同樣,需要一個變量的時候,毫無規則地定義一些散落在代碼各處的變量。
還是老問題,不方便維護,也不夠清晰。當然,這些問題在代碼規模較小時是體現不出來的。
如果將需要的重要變量定義到對象的屬性上,函數變成對象的方法,當我們需要的時候通過對象來獲取,一來方便管理,二來不會影響外部命名空間,因為所有這些變量名還有方法名都是在對象內部。
//構造函數
var Beautifier = function(ele, opt) {
//構造函數的屬性
//這里在插件內部會傳進 this==當前選中的元素
this.$element = ele,
//用戶不傳參時 會設置的屬性
this.defaults = {
'color': 'red',
'fontSize': '16px',
'textDecoration': 'none'
},
//extend工具 使得 有無參數均可設置相應的屬性
this.options = $.extend({}, this.defaults, opt)
}
//構造函數原型的方法
Beautifier.prototype = {
//插件其實用到的就是原型里的beatutify方法
beautify: function() {
//設置當前選中元素的樣式
//至于為什么用return? 把對象return出去
return this.$element.css({
'color': this.options.color,
'fontSize': this.options.fontSize,
'textDecoration': this.options.textDecoration
});
}
}
//自制插件
$.fn.myPlugin = function(obj) {
//每次調用插件 都會創建一個新實例
var beautifier = new Beautifier(this, obj);
//通過實例方法 設置相應樣式
return beautifier.beautify();
//return 保證鏈式語法
}
通過上面這樣一改造,我們的代碼變得更面向對象了,也更好維護和理解,以后要加新功能新方法,只需向對象添加新變量及方法即可,然后在插件里實例化后即可調用新添加的東西。
插件的調用還是一樣的,我們對代碼的改動并不影響插件其他地方,只是將代碼的組織結構改動了而以
$(function(){
$('p').myPlugin({
"color":"red",
"fontSize":"30px",
"textDecoration": "underline"
})
})
命名空間的問題
不僅僅是jQuery插件的開發,我們在寫任何JS代碼時都應該注意的一點是不要污染全局命名空間。因為隨著你代碼的增多,如果有意無意在全局范圍內定義一些變量的話,最后很難維護,也容易跟別人寫的代碼有沖突。
一個好的做法是始終用自調用匿名函數包裹你的代碼
我們知道JavaScript中無法用花括號方便地創建作用域,但函數卻可以形成一個作用域,域內的代碼是無法被外界訪問的。如果我們將自己的代碼放入一個函數中,那么就不會污染全局命名空間,同時不會和別的代碼沖突。
如上面我們定義了一個Beautifier全局變量,它會被附到全局的window對象上,為了防止這種事情發生,你或許會說,把所有代碼放到jQuery的插件定義代碼里面去啊,也就是放到$.fn.myPlugin里面。這樣做倒也是種選擇。但會讓我們實際跟插件定義有關的代碼變得臃腫,而在$.fn.myPlugin里面我們其實應該更專注于插件的調用,以及如何與jQuery互動。
所以保持原來的代碼不變,我們將所有代碼用自調用匿名函數包裹。
var foo = function() {
//為了測試如果 不加分號會出現的問題
}
;
(function($) {
var Beautifer = function(ele, opt) {
//保存jQ對象用$
this.$element = ele,
this.defaults = {
'color': 'red',
'fontSize': '16px',
},
this.setting = $.extend({}, this.defaults, opt)
}
Beautifer.prototype = {
beautify: function() {
//此處的return是把我們獲取的 元素返還出去
return this.$element.css({
'color': this.setting.color,
'fontSize': this.setting.fontSize
});
}
}
$.fn.myPlugin = function(options) {
var beautifer = new Beautifer(this, options);
return beautifer.beautify();
//return 依然是為了鏈式調用
}
})(jQuery);
//我發現 在自調用里傳進實參 jQuery 里面可以用任何變量名接收
//比如:把 $換為z 下面調用時 就是z.fn.myPlugin .前提是實參一定是!!jQuery!!jquery就不行
//這樣 把插件 封裝進一個匿名函數里 并 通過 自調用的方式 立即執行 的 好處是
// 1、JavaScript中無法用花括號方便地創建作用域,但函數卻可以形成一個作用域,域內的代碼
//是無法被外界訪問的。如果我們將自己的代碼放入一個函數中,那么就不會污染全局命名空間,
//同時不會和別的代碼沖突。
//2、自調用匿名函數里面的代碼會在第一時間執行,頁面準備好過后,
//上面的代碼就將插件準備好了,以方便在后面的代碼中使用插件。
//為了防止們用來充當自調用匿名函數的第一對括號與上面別人定義的函數相連,
//中間沒有分號嘛,代碼無法正常解析;
//一個好習慣是我們在代碼開頭加一個分號