前端知識 | 論jQuery如何編寫插件

一. jQuery的插件機制

爲了方便用戶創建插件,jquery提供了jQuery.extend()和jQuery.fn.extend()方法
jQuery.extend(object) ,一個參數的用於擴展jQuery類本身,也就是用來在jQuery類/命名空間上增加新函數,或者叫靜態方法,例如jQuery內置的 ajax方法都是用jQuery.ajax()這樣調用的,有點像 “類名.方法名” 靜態方法的調用方式。

jQuery.extend() 擴展
//擴展jQuery對象本身
jQuery.extend({
"minValue": function (a, b) {
return a < b ? a : b;
},
"maxValue": function (a, b) {
return a > b ? a : b;
}
});
var i = 100; j = 101;
var min_v = $.minValue(i, j);

jQuery.extend()方法重載
jQuery.extend([deep], target, object1, [objectN])

參數
deep: 可選。如果設爲true,則遞歸合併。
target: 待修改對象。
object1: 待合併到第一個對象的對象。
objectN: 可選。待合併到第一個對象的對象。

示例
合併 defaults 和 options, 不修改 defaults。
var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = jQuery.extend(empty, defaults, options)

結果
settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }

用一個或多個其他對象來擴展一個對象,返回被擴展的對象。
如果不指定target,則給jQuery命名空間本身進行擴展。這有助於插件作者爲jQuery增加新方法。
如果第一個參數設置爲true,則jQuery返回一個深層次的副本,遞歸地複製找到的任何對象。否則的話,副本會與原對象共享結構。
未定義的屬性將不會被複制,然而從對象的原型繼承的屬性將會被複制。
Query.fn.extend(object)擴展 jQuery 元素集來提供新的方法(常用來製作插件)。

首先我們來看fn 是什麼東西呢。查看jQuery代碼,就不難發現。
jQuery.fn = jQuery.prototype = {
   init: function( selector, context ) {.....};
};
原來 jQuery.fn = jQuery.prototype,也就是jQuery對象的原型。那jQuery.fn.extend()方法就是擴展jQuery對象的原型方法。我們知道擴展原型上的方法,就相當於爲對象添加“成員方法”,類的“成員方法”要類的對象才能調用,所以使用jQuery.fn.extend(object)擴展的方法,jQuery類的實例可以使用這個“成員函數”,比如$(‘p’).extend(obj)。
jQuery.fn.extend(object)和jQuery.extend(object)方法一定要區分開來。
二. 自執行的匿名函數/閉包

  1. 什麼是自執行的匿名函數?
    它是指形如這樣的函數: (function(){// code})();

  2. 疑問 爲什麼(function() {// code})();可以被執行, 而function() {// code}();卻會報錯?
    (1).首先,要清楚兩者的區別:(function(){// code})是表達式,function(){// code}是函數聲明.
    (2).其次, js"預編譯"的特點: js在"預編譯"階段, 會解釋函數聲明, 但卻會忽略表達式.
    (3).當js執行到function() {//code}();時, 由於function() {//code}在"預編譯"階段已經被解釋過, js會跳過function(){//code}, 試圖去執行();, 故會報錯;
    當js執行到(function(){// code})();時, 由於(function(){// code})是表達式, js會去對它求解得到返回值, 由於返回值是一 個函數, 故而遇到();時, 便會被執行.

匿名函數最大的用途是創建閉包(這是JavaScript語言的特性之一),並且還可以構建命名空間,以減少全局變量的使用。

例如:
var a=1;
(function(){
    var a=100;
  })();
alert(a); //彈出 1
三. 分步封裝JQuery插件

第一步定義一個閉包區域,防止插件“污染”。
(function($) {} )(window.jQuery);

第二步jQuery.fn.extend(object)擴展jquery方法制作插件
(function ($) {
$.fn.plugin=function(options){
//do something
};
})(window.jQuery);

第三步給插件默認參數,實現插件的功能
(function ($) {
$.fn.plugin=function (options) {
var defaults={
foreground: 'red',
background: 'yellow'
};
//options合併到defaults上,defaults繼承了options上的各種屬性和方法,將所有的賦值給endOptions
var endOptions=$.extend({},defaults,options);
this.each(function () {
var $this = $(this);
$this.css({
backgroundColor: endOptions.background,
color: endOptions.foreground
});
});
return this;
};
})(jQuery);

最後調用插件
$(function () {
$("p").plugin({ foreground: 'orange', background: '#ccc' });
//調用自定義 插件
});
注意

  1. 有一種東西叫腳本壓縮,前端頁面要減少腳本數量和腳本大小,所以要把一類的腳本壓縮在一起,爲了避免壓縮時前一個腳本沒有寫最後一個分號而導致壓縮後腳本不能使用,所以要在開始加一個分號。

  2. 函數全部放在閉包裏,外面的函數就調用不到裏面的參數了,比較安全。

  3. 之所以插件要return this,返回當前對象,是爲了遵循jQuery的鏈式寫法特點。

    總結
  4. jQuery.fn = jQuery.prototype,也就是jQuery對象的原型。jQuery.fn.extend()方法就是擴展jQuery對象的原型方法。爲對象添加“成員方法”,類的“成員方法”要類的對象才能調用,所以使用jQuery.fn.extend(object)擴展的方法,jQuery類的實例可以使用這個“成員函數”,比如$(‘p’).extend(obj)。

  5. 閉包可以構建命名空間,以減少全局變量的使用,避免全局污染。

  6. $.extend()多用來合併插件中的參數,也可以用來拓展全局函數,$.fn.extend()用來爲對象添加成員方法。

  7. return this返回該對象,便於jQuery方法的鏈式調用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章