欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript Object的extend是一個(gè)常用的功能

 更新時(shí)間:2009年12月02日 00:42:08   作者:  
對(duì)Object的extend是一個(gè)常用的功能。舉一個(gè)例子,由于javascript 沒(méi)有重載(overload),而且函數(shù)的參數(shù)類(lèi)型是沒(méi)有定義的,所以很多時(shí)候我們都傳入一個(gè)對(duì)象來(lái)作為參數(shù)已方便控制。
通常在函數(shù)里面給了參數(shù)對(duì)象的默認(rèn)值,這個(gè)時(shí)候就需要通過(guò)extend來(lái)把傳入的參數(shù)覆蓋進(jìn)默認(rèn)參數(shù),如:
代碼:
復(fù)制代碼 代碼如下:

giant.ui.imageshow = function(options) {
this.opts = $.extend({}, giant.ui.imageshow.defaults, options);
}
giant.ui.imageshow.defaults = {
id:"imageshow",
isAuto:true,
speed:3000
};

Jquery 的框架中給了一個(gè)extend工具:
jQuery.extend(target,obj1,[objN])
用一個(gè)或多個(gè)其他對(duì)象來(lái)擴(kuò)展一個(gè)對(duì)象,返回被擴(kuò)展的對(duì)象。
用于簡(jiǎn)化繼承。
Extend one object with one or more others, returning the original, modified, object.
This is a great utility for simple inheritance.
返回值--Object
參數(shù)
target (Object) : 待修改對(duì)象。
object1 (Object) : 待合并到第一個(gè)對(duì)象的對(duì)象。
objectN (Object) : (可選) 待合并到第一個(gè)對(duì)象的對(duì)象。
但框架中內(nèi)置的這個(gè)extend有明顯的缺陷,那就是不能繼承對(duì)象中的對(duì)象。還是舉一個(gè)例子來(lái)說(shuō)明:
代碼:
復(fù)制代碼 代碼如下:

var obj1 = {},
var obj2={name:"karry",email:"karry@a.com",tel:{homeTel:"158255",officeTel:"02112585"}}
obj1 = $.extend({},obj1 ,obj2 );

結(jié)果obj1 只有name 和email屬性,而有與tel本身就是一個(gè)對(duì)象,tel里面的homeTel和officeTel沒(méi)有繼承過(guò)去。
我的目標(biāo)就是實(shí)現(xiàn)這種對(duì)子對(duì)象的子屬性也一起復(fù)制(繼承)的功能,不管他嵌套有多深。
首先我們看看這個(gè)方法的參數(shù),有三個(gè)參數(shù),target 目標(biāo)對(duì)象,source 源對(duì)象,deep 是否復(fù)制(繼承)對(duì)象中的對(duì)象,如果deep為true則繼承所有,為false則和jquery的實(shí)現(xiàn)方式一樣,不會(huì)繼承子對(duì)象。
代碼:
復(fù)制代碼 代碼如下:

Object.extend = function(target, /*optional*/source, /*optional*/deep) {}

我只把第一個(gè)參數(shù)target設(shè)為必選參數(shù),而source 和deep都設(shè)為可選參數(shù)。這樣就會(huì)遇到一個(gè)問(wèn)題,如果使用的時(shí)候只傳如兩個(gè)參數(shù),怎么確認(rèn)第二個(gè)參數(shù)是 對(duì)應(yīng)的source還是deep?所以我需要判斷傳入的第二個(gè)參數(shù)的類(lèi)型。
代碼:
復(fù)制代碼 代碼如下:

target = target || {}; //target默認(rèn)為空
var sType = typeof source;
//如果第二個(gè)參數(shù)的類(lèi)型為未定義或者為布爾值
if( sType === 'undefined' || sType === 'boolean' ) {
deep = sType === 'boolean' ? source : false;
source = target; //把target賦值給source,
target = this; //這里的this指的是Object
}

有人可能對(duì)最后面的兩行代碼有疑問(wèn),我的處理方式是這樣的。如果target和source兩個(gè)參數(shù)都存在,且source不是布爾值,那么,就把source對(duì)象的內(nèi)容復(fù)制給target.否則,把target對(duì)象復(fù)制給Object對(duì)象。deep默認(rèn)為false.
為了安全起見(jiàn),我們還需要判斷一下,如果souce滿足了上面的條件,但它不是Object對(duì)象,或者它是一個(gè)Function對(duì)象(這涉及到一些其他的問(wèn)題),我們也沒(méi)辦法對(duì)其進(jìn)行復(fù)制的。這個(gè)時(shí)候我們把souce設(shè)為空的Object,也就是并不進(jìn)行復(fù)制操作。
代碼:
復(fù)制代碼 代碼如下:

if( typeof source !== 'object' && Object.prototype.toString.call(source) !== '[object Function]' )
source = {};

注:Function對(duì)象在執(zhí)行typeof 操作時(shí) 也會(huì)返回“object”,但我們沒(méi)辦法對(duì)其進(jìn)行正確的復(fù)制(至少在我這個(gè)方法里面不行),所以我必須剔除出來(lái)。
下面就是循環(huán)進(jìn)行復(fù)制了。這里利用了遞歸。
代碼:
復(fù)制代碼 代碼如下:

var i=1,option;
// 外層循環(huán)就是為了把依次修改options,先設(shè)為target,后設(shè)為source
while(i <= 2) {
options = i === 1 ? target : source;
if( options != null ) {
//內(nèi)層循環(huán)復(fù)制對(duì)應(yīng)的屬性
for( var name in options ) {
var src = target[name], copy = options[name];
if(target === copy)
continue;
//如果deep設(shè)為true,且該屬性是一個(gè)對(duì)象
if(deep && copy && typeof copy === 'object' && !copy.nodeType)
//遞歸
target[name] = this.extend(src ||(copy.length != null ? [] : {}), copy, deep);
else if(copy !== undefined)
target[name] = copy;
}
}
i++;
}

這里利用了遞歸的方式,依次復(fù)制對(duì)象里面的對(duì)象。這個(gè)功能就做完了。全部代碼如下:
代碼:
復(fù)制代碼 代碼如下:

/*
* @param {Object} target 目標(biāo)對(duì)象。
* @param {Object} source 源對(duì)象。
* @param {boolean} deep 是否復(fù)制(繼承)對(duì)象中的對(duì)象。
* @returns {Object} 返回繼承了source對(duì)象屬性的新對(duì)象。
*/
Object.extend = function(target, /*optional*/source, /*optional*/deep) {
target = target || {};
var sType = typeof source, i = 1, options;
if( sType === 'undefined' || sType === 'boolean' ) {
deep = sType === 'boolean' ? source : false;
source = target;
target = this;
}
if( typeof source !== 'object' && Object.prototype.toString.call(source) !== '[object Function]' )
source = {};
while(i <= 2) {
options = i === 1 ? target : source;
if( options != null ) {
for( var name in options ) {
var src = target[name], copy = options[name];
if(target === copy)
continue;
if(deep && copy && typeof copy === 'object' && !copy.nodeType)
target[name] = this.extend(src ||
(copy.length != null ? [] : {}), copy, deep);
else if(copy !== undefined)
target[name] = copy;
}
}
i++;
}
return target;
};

使用示例:
代碼:
復(fù)制代碼 代碼如下:

var source = {id:1, name:'Jack Source'}, target = {name:'Jack Target', gender:1,tel:{homeTel:"158255",officeTel:"02112585"}};
var newObj1 = Object.extend(target, source);

相關(guān)文章

最新評(píng)論