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

JavaScript Object的extend是一個常用的功能

 更新時間:2009年12月02日 00:42:08   作者:  
對Object的extend是一個常用的功能。舉一個例子,由于javascript 沒有重載(overload),而且函數(shù)的參數(shù)類型是沒有定義的,所以很多時候我們都傳入一個對象來作為參數(shù)已方便控制。
通常在函數(shù)里面給了參數(shù)對象的默認值,這個時候就需要通過extend來把傳入的參數(shù)覆蓋進默認參數(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 的框架中給了一個extend工具:
jQuery.extend(target,obj1,[objN])
用一個或多個其他對象來擴展一個對象,返回被擴展的對象。
用于簡化繼承。
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) : 待修改對象。
object1 (Object) : 待合并到第一個對象的對象。
objectN (Object) : (可選) 待合并到第一個對象的對象。
但框架中內(nèi)置的這個extend有明顯的缺陷,那就是不能繼承對象中的對象。還是舉一個例子來說明:
代碼:
復(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本身就是一個對象,tel里面的homeTel和officeTel沒有繼承過去。
我的目標就是實現(xiàn)這種對子對象的子屬性也一起復(fù)制(繼承)的功能,不管他嵌套有多深。
首先我們看看這個方法的參數(shù),有三個參數(shù),target 目標對象,source 源對象,deep 是否復(fù)制(繼承)對象中的對象,如果deep為true則繼承所有,為false則和jquery的實現(xiàn)方式一樣,不會繼承子對象。
代碼:
復(fù)制代碼 代碼如下:

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

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

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

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

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

注:Function對象在執(zhí)行typeof 操作時 也會返回“object”,但我們沒辦法對其進行正確的復(fù)制(至少在我這個方法里面不行),所以我必須剔除出來。
下面就是循環(huá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ù)制對應(yīng)的屬性
for( var name in options ) {
var src = target[name], copy = options[name];
if(target === copy)
continue;
//如果deep設(shè)為true,且該屬性是一個對象
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ù)制對象里面的對象。這個功能就做完了。全部代碼如下:
代碼:
復(fù)制代碼 代碼如下:

/*
* @param {Object} target 目標對象。
* @param {Object} source 源對象。
* @param {boolean} deep 是否復(fù)制(繼承)對象中的對象。
* @returns {Object} 返回繼承了source對象屬性的新對象。
*/
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)文章

最新評論