`
mengdejun
  • 浏览: 408777 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

javascript 给Object扩展extend方法

    博客分类:
  • JS
阅读更多

对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])

用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
用于简化继承。

返回值--Object

参数

target (Object) : 待修改对象。

object1 (Object) : 待合并到第一个对象的对象。

objectN (Object) : (可选) 待合并到第一个对象的对象。

但框架中内置的这个extend有明显的缺陷,那就是不能继承对象中的对象。还是举一个例子来说明:

var obj1 = {},
var obj2={name:"karry",email:"karry@a.com",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=Object.inherit = 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).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;
};

 

Object.extend = function(destination, source) { // 一个静态方法表示继承, 目标对象将拥有源对象的所有属性和方法for (var property in source) {
    destination[property] = source[property];   // 利用动态语言的特性, 通过赋值动态添加属性与方法
}
return destination;   // 返回扩展后的对象
}

Object.extend(Object, { 
inspect: function(object) {   // 一个静态方法, 传入一个对象, 返回对象的字符串表示
    try {
      if (object == undefined) return 'undefined'; // 处理undefined情况
      if (object == null) return 'null';     // 处理null情况
      // 如果对象定义了inspect方法, 则调用该方法返回, 否则返回对象的toString()值
      return object.inspect ? object.inspect() : object.toString(); 
    } catch (e) {
      if (e instanceof RangeError) return '...'; // 处理异常情况
      throw e;
    }
},
keys: function(object) {     // 一个静态方法, 传入一个对象, 返回该对象中所有的属性, 构成数组返回
    var keys = [];
    for (var property in object)
      keys.push(property);     // 将每个属性压入到一个数组中
    return keys;
},
values: function(object) {   // 一个静态方法, 传入一个对象, 返回该对象中所有属性所对应的值, 构成数组返回
    var values = [];
    for (var property in object) values.push(object[property]); // 将每个属性的值压入到一个数组中
    return values;
},
clone: function(object) {    // 一个静态方法, 传入一个对象, 克隆一个新对象并返回
    return Object.extend({}, object);
}
});

 

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

 

分享到:
评论

相关推荐

    Javascript Object.extend

    `Object.extend`方法在JavaScript的面向对象编程中起到了核心作用,它允许对象之间进行属性和方法的继承。在提供的代码中,`Object.extend`接受两个参数——目标对象(destination)和源对象(source),并将源对象...

    前端开源库-object-extend

    `object-extend`就是一个针对这种需求的开源库,它提供了深度扩展(或合并)JavaScript对象的功能。这个库经过了充分的测试,确保在各种情况下都能稳定工作。 `object-extend`的基本用法是将源对象(或多个源对象)...

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

    JavaScript中对象的extend操作是指将一个或多个对象的内容复制到另一个对象中,通常用以合并属性和方法。这项功能在JavaScript编程中非常实用,因为它可以方便地实现对象之间的属性继承和扩展。由于JavaScript不支持...

    Js-$.extend扩展方法使方法参数更灵活.docx

    在JavaScript开发中,jQuery库提供了一个...通过熟练掌握`$.extend()`方法,开发者可以更好地组织和管理代码,使其更具可读性和可扩展性。在实际项目中,合理利用`$.extend()`能有效提升代码质量,减少出错的可能性。

    Js-$.extend扩展方法使方法参数更灵活

    在JavaScript开发中,$.extend方法是jQuery库提供的一个扩展功能,它能够将一个或多个对象的内容合并到目标对象中,从而实现对象属性的扩展。这个方法在处理参数时提供了一种非常灵活的方式来设置默认值,并且能够...

    Extend

    JavaScript提供了多种方法来实现对象扩展,包括原型链、Object.create()、ES6的类继承以及Object.assign()等。此外,许多工具库也有自己的extend方法,为开发人员提供了更便捷的接口。而“arweb1.js”可能是一个包含...

    jQuery中的deferred对象和extend方法详解

    而`extend方法`则用于合并对象属性,增强了对象的可扩展性。 ### Deferred对象 `deferred对象`的核心在于它代表了一个未来可能完成的操作,它的状态可以从“未解决”(pending)变为“已完成”(resolved)或“已...

    010课-复习extend方法、事件封装及正则表达式1.rar

    在JavaScript中,"extend"通常用于对象的继承,它能够将一个对象的属性和方法扩展到另一个对象上。这在面向对象编程中非常常见,特别是在处理类库或框架如jQuery时。例如,jQuery的`.extend()`方法允许我们将多个...

    object-extend-missing-deep:对象仅扩展新键

    在JavaScript中,有两种主要的对象扩展方法:浅扩展(shallow extend)和深扩展(deep extend)。 浅扩展,如`Object.assign()`方法,会将源对象的所有可枚举属性复制到目标对象中。但当源对象和目标对象有相同的...

    前端开源库-class-extend

    子类可以通过调用`extend`方法从基类派生,这与JavaScript中的`Object.create`或`prototype`机制相似,但提供了更友好的API。 2. **方法重写与继承**:子类可以重写基类的方法,同时仍然保留对基类方法的访问。这种...

    jQuery.extend

    jQuery.extend方法的基本语法如下: ```javascript jQuery.extend(target, object1, [objectN]); ``` - `target`:目标对象,将接收其他对象的属性。 - `object1, objectN`:源对象,它们的属性将被合并到目标对象...

    浅谈jQuery中的$.extend方法来扩展JSON对象

    在JavaScript的世界里,jQuery库为开发者提供了许多便捷的API,其中`$.extend`是一个非常实用的方法,用于合并或扩展对象的属性。这篇文章将深入探讨`$.extend`在jQuery中的使用,以及它如何帮助我们处理JSON对象。 ...

    Jquery实现$.fn.extend和$.extend函数_.docx

    在JavaScript中,jQuery库提供了两种扩展对象的方法,即`$.fn.extend`和`$.extend`。它们都用于增加或修改现有对象的功能,但应用场景不同。本文将深入解析这两种方法的实现原理和用途。 首先,`$.fn.extend`是用于...

    JavaScript框架高级编程(第一章扩展和增强DOM元素 )

    ### JavaScript框架高级编程——扩展和增强DOM元素 ...此外,通过使用 `$()`、`$$()` 和 `Element.extend()` 这些核心方法,开发者可以快速高效地扩展和操作DOM元素,提高Web应用的性能和用户体验。

    Object.js:为 Object 类提供扩展能力。 OOP 现在更方便了!

    Object获得一个静态方法调用extend ,允许扩展这个超类。 实际上所有未来的类都会有这些方法和属性。创建一个班级用 : var MyClass = ParentClass . extend ( prototype ) ; prototype显然是MyClass的prototype ...

Global site tag (gtag.js) - Google Analytics