当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JavaScript Object的extend是一个常用的功能

Javascript
js 判断 enter 事件
谷歌浏览器 insertCell与appendChild的区别
从JavaScript 到 JQuery (1)学习小结
JavaScript实现动态增加文件域表单
JavaScript DOM 添加事件
Javascript 跨域访问解决方案
检测是否已安装 .NET Framework 3.5的js脚本
JavaScript 获得选中文本内容的方法
Javascript 获取链接(url)参数的方法
javascript Ext JS 状态默认存储时间
动态为事件添加js代码示例
JSON扫盲帖 JSON.as类教程
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
js实现权限树的更新权限时的全选全消功能
javascript Table 中2个列(TD)的交换实现代码
js表数据排序 sort table data
javascript css在IE和Firefox中区别分析
JAVASCRIPT IE 与 FF中兼容问题小结
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
csdn 批量接受好友邀请

Javascript 中的 JavaScript Object的extend是一个常用的功能


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-10   浏览: 357 ::
收藏到网摘: n/a

对Object的extend是一个常用的功能。举一个例子,由于javascript 没有重载(overload),而且函数的参数类型是没有定义的,所以很多时候我们都传入一个对象来作为参数已方便控制。 通常在函数里面给了参数对象的默认值,这个时候就需要通过extend来把传入的参数覆盖进默认参数,如:
代码:
复制代码 代码如下:

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
参数
target (Object) : 待修改对象。
object1 (Object) : 待合并到第一个对象的对象。
objectN (Object) : (可选) 待合并到第一个对象的对象。
但框架中内置的这个extend有明显的缺陷,那就是不能继承对象中的对象。还是举一个例子来说明:
代码:
复制代码 代码如下:

var obj1 = {},
var obj2={name:"karry",email:"[email protected]",tel:{homeTel:"158255",officeTel:"02112585"}}
obj1 = $.extend({},obj1 ,obj2 );

结果obj1 只有name 和email属性,而有与tel本身就是一个对象,tel里面的homeTel和officeTel没有继承过去。
我的目标就是实现这种对子对象的子属性也一起复制(继承)的功能,不管他嵌套有多深。
首先我们看看这个方法的参数,有三个参数,target 目标对象,source 源对象,deep 是否复制(继承)对象中的对象,如果deep为true则继承所有,为false则和jquery的实现方式一样,不会继承子对象。
代码:
复制代码 代码如下:

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

我只把第一个参数target设为必选参数,而source 和deep都设为可选参数。这样就会遇到一个问题,如果使用的时候只传如两个参数,怎么确认第二个参数是 对应的source还是deep?所以我需要判断传入的第二个参数的类型。
代码:
复制代码 代码如下:

target = target || {}; //target默认为空
var sType = typeof source;
//如果第二个参数的类型为未定义或者为布尔值
if( sType === 'undefined' || sType === 'boolean' ) {
deep = sType === 'boolean' ? source : false;
source = target; //把target赋值给source,
target = this; //这里的this指的是Object
}

有人可能对最后面的两行代码有疑问,我的处理方式是这样的。如果target和source两个参数都存在,且source不是布尔值,那么,就把source对象的内容复制给target.否则,把target对象复制给Object对象。deep默认为false.
为了安全起见,我们还需要判断一下,如果souce满足了上面的条件,但它不是Object对象,或者它是一个Function对象(这涉及到一些其他的问题),我们也没办法对其进行复制的。这个时候我们把souce设为空的Object,也就是并不进行复制操作。
代码:
复制代码 代码如下:

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

注:Function对象在执行typeof 操作时 也会返回“object”,但我们没办法对其进行正确的复制(至少在我这个方法里面不行),所以我必须剔除出来。
下面就是循环进行复制了。这里利用了递归。
代码:
复制代码 代码如下:

var i=1,option;
// 外层循环就是为了把依次修改options,先设为target,后设为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;
//如果deep设为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++;
}

这里利用了递归的方式,依次复制对象里面的对象。这个功能就做完了。全部代码如下:
代码:
复制代码 代码如下:

/*
* @param {Object} target 目标对象。
* @param {Object} source 源对象。
* @param {boolean} deep 是否复制(继承)对象中的对象。
* @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;
};

使用示例:
代码:
复制代码 代码如下:

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