jQuery.extend的用法

有網友提問,看不太懂jQuery.extend的用法,本想在留言裡回覆,但寫著寫著,發現要說到淺顯白話,還真得花些篇幅,索性另起一篇,解釋得更詳細點。

以jQuery.extend(objA, objB)為例,你可以想像成objA與objB各有一些屬性(方法也會比照處理,在此只提屬性),extend()會將objB有而objA沒有的屬性加到objA裡,如果objB裡的某個屬性,objA裡剛好也有同名的屬性,則會用objB的屬性值去覆寫objA原有的屬性。objA最後就是整合結果,或者也可以由var objC = jQuery.extend(objA, objB)取得整合結果(objA == objC)。

例如以下的程式碼,大家可以丟到Mini jQuery Lab跑一下,馬上就可以驗證jQuery.extend的效果:

var objA = { speed:"slow" };
var objB = { speed:"fast", power:"hard" };
var objC = jQuery.extend( objA, objB );
document.write("<dt>objA");
for (var p in objA) { document.write("<dd>" + p + "->" + objA[p]); }
document.write("<dt>objC");
for (var p in objC) { document.write("<dd>" + p + "->" + objC[p]); }

所得結果objA與objC的內容相同,都有兩個屬性speed:"fast"(被覆寫), power:"hard"(新加的)。

jQuery.extend可以支援多個物件屬性/方法的整併,並不限於兩個。例如: jQuery.extend(objA, objB, objC),objB, objC多出的屬性都會加到objA裡,如果有objA已有同名屬性,則會用objC/objB裡的屬性值覆寫之,若objB, objC都用同名屬性,則會排在後方的objC為準(後令壓前令)。

jQuery.extend的最常見的用途是用來處理Plugin或函數的傳入參數,比如函數會用到的參數有10個,但大部分情況呼叫時只需要指定其中一兩個,其餘的用預設值即可。於是我們可以在函數中宣告一個預設值物件objDefault,裡面已有10個屬性,呼叫函數時則傳入objOption,裡面只放入一兩個要變更的屬性值,經過var objSetting = jQuery.extend(objDefault, objOption)之後,我們得到10個"有指定用指定值,沒指定用預設值"的屬性供後續使用。舉個例子:

function addDiv(options) {
    var defaults = { 
        border: "solid 1px black",
        backgroundColor: "#cccccc",
        width: "200px", height: "50px",
    margin: "10px"
    };
    var settings = $.extend(defaults, options);
    $("<div></div>").css(settings).appendTo("body");
}
addDiv({ width: "400px" });
addDiv({ backgroundColor: "orange", height: "100px" });

希望這樣的說明夠清楚。

歡迎推文分享:
Published 01 March 2009 02:32 AM 由 Jeffrey
Filed under:
Views: 70,007



意見

# chicken said on 01 March, 2009 02:01 AM

覺的比較有趣的,不是 jQuery.extend 的用法,而是它的用途...

一般的程式語言都沒這樣的東西,即使是 .NET 內的 Dictionary 也沒有對等的... 因為用途不一樣啊。extend 看起來像是 javascript 沒有正規的 "類別繼承" 的衍生作法, extend(objA, objB) 感覺就像 objA 去繼承 objB 一樣,只不過一般講的繼承是對 class, 這裡是對 object, 而且繼承的時間點從 coding time 延後到 run time ...

不過朝這角度想,extend 的用途就清楚多了...

# Will 保哥 said on 01 March, 2009 03:17 AM

我 run 的結果跟你寫的不同耶,所得結果objA與objC的內容不一樣, objC 沒有 power 屬性:

objA

  speed->fast

  power->hard

objC

  speed->fast

# KINK said on 01 March, 2009 04:53 AM

版大...

感謝您!

看來要多用幾次來熟悉這方便的語法了^^~

# Jeffrey said on 01 March, 2009 08:16 AM

to chicken, 這陣子Javascript寫多了,開始覺得可以不用宣告,就在Runtime"惡搞"起物件也有其獨到的方便之處。而C# 4.0裡的Dynamic Programming我個人覺得就有點向JS這種"不嚴謹"的精神傾斜... 程式語言的發展真是奇妙。

to 保哥,好像在Chrome裡<dd>因為沒有結尾</dd>所以最後一列不會馬上印出來,最後再加一個document.write("<hr />")應該可以改善。

# metavige said on 02 March, 2009 06:15 PM

javascript 本來就沒有類似 OOP 那種 extends 的觀念

他有 prototype 的方式可以做到類似繼承的東西

只是,因為 javascript 是弱型別,沒辦法像是 C# or Java 這樣

所以,只要名稱相同,就會被覆蓋掉

jQuery 只是提供了一個易懂的方式去讓 "繼承" 這件事情變得更貼近語意

如果寫 prototype 大概很少人會懂吧

因為這種作法,其實並不是現在才出現的

很早以前(我記得沒錯應該是七八年前了)就已經有這樣的作法了~

# kink said on 10 March, 2009 09:24 AM

Jeffrey大...

冒昧又來求問了:p關於以下的語法,小弟不理解其中的

var bb = this這段的涵義@@!

為什麼不能用$(this).dequeue();這樣呢?

$.fn.wait = function(time, type) {

       time = time || 1000;

       type = type || "fx";

       return this.queue(type, function() {

           var bb = this;

             //alert($(bb).attr("nodeName"));

           setTimeout(function() {

               $(bb).dequeue();

           }, time);

       });

   };

# Jeffrey said on 10 March, 2009 06:08 PM

to kink, PO了一篇文回答你的問題,Check it out.

blog2.darkthread.net/.../js-this-and-closure.aspx

# joeshow said on 21 March, 2010 09:32 PM

不错。。谢谢

# Raphael said on 03 June, 2010 07:54 AM

見到此篇真是豁然開朗, 太感謝了.

# A-chung said on 09 May, 2011 10:57 PM

寫得真的不錯~簡單明瞭~感謝分享!!

# Jill said on 18 January, 2012 09:56 PM

非常感謝您~!

# jessie said on 27 April, 2012 09:38 PM

你好:我可以請教有關以下這個函數的用途嘛?

$.fn.ntAccordion = function(options) {

   var _defaultSettings = {

};

   var _opts = $.extend(_defaultSettings, options);

var _init = function(container){

var height=26*7;

$(container).find('.menu.level01').next().each(function(){

height=$(this).height()>height?$(this).height():height;

}).css({height:height});

$('.menu.level02[s=none]').hover(

function(){

$(this).find('tr:first td:last').children().show();

},

function(){

$(this).find('tr:first td:last').children().hide();

}

).each(function(){

var url=Base64.decode($(this).attr('url'));

$(this).unbind('click').click(function(){

location.href=url;

});

});

};

   var _handler = function() {

var container=this;

_init(container);

$(container).find('.menu.level01').click(function(){

$(this).siblings('.menu.level02:visible').hide('fast');

$(this).next(':hidden').slideDown('fast');

});

   };

   return this.each(_handler);

};

# Jeffrey said on 28 April, 2012 09:59 AM

to jessie,看起來是用來製作收合式選單的Plugin(滑鼠滑過時展開),但要配合適當的class設定才能順利運作。

# anyyou said on 05 October, 2012 04:38 AM

看完就解惑了~謝謝大大

# Hardy said on 23 October, 2015 02:25 AM

改成這樣子,就能馬上了解他們之間的曖昧關係了

var objA = { speed:"fast" };

var objB = { speed:"slow", power:"hard" };

document.write("<dt>objB");

for (var p in objB) { document.write("<dd>" + p + "->" + objB[p]); }

var objC = jQuery.extend( objB, objA );

document.write("<dt>objC");

for (var p in objC) { document.write("<dd>" + p + "->" + objC[p]); }

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<March 2009>
SunMonTueWedThuFriSat
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication