Extend of JavaScriptObject is a common function _ javascript Technique

Source: Internet
Author: User
Extend for objects is a common function. For example, javascript does not overload the function, and the parameter type of the function is not defined. Therefore, it is convenient to input an object as a parameter. The default value of the parameter object is usually provided in the function. In this case, the extend is used to overwrite the input parameter to the default parameter, for example:
Code:

The Code is as follows:


Giant. ui. imageshow = function (options ){
This. opts = $. extend ({}, giant. ui. imageshow. defaults, options );
}
Giant. ui. imageshow. defaults = {
Id: "imageshow ",
IsAuto: true,
Speed: 3000
};


The Jquery framework provides an extend tool:
JQuery. extend (target, obj1, [objN])
Use one or more other objects to expand an object and return the extended object.
Used to simplify inheritance.
Extend one object with one or more others, returning the original, modified, object.
This is a great utility for simple inheritance.
Return Value -- Object
Parameters
Target (Object): the Object to be modified.
Object1 (Object): the Object to be merged into the first Object.
ObjectN (Object): (optional) Object to be merged to the first Object.
But the extend built in the framework has obvious defects, that is, it cannot inherit the objects in the object. Here is an example:
Code:

The Code is as follows:


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


As a result, obj1 only has the name and email attributes, while tel itself is an object. homeTel and officeTel in tel are not inherited.
My goal is to implement the function of copying (inheriting) Sub-attributes of this Sub-object, no matter how deep it is nested.
First, let's take a look at the parameters of this method. There are three parameters: target object, source object, and whether to copy (inherit) objects in deep. If deep is true, all objects are inherited, if it is set to false, it is implemented in the same way as jquery and does not inherit sub-objects.
Code:

The Code is as follows:


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


I only set the first target parameter as a required parameter, while both source and deep are set as optional parameters. In this case, a problem occurs. If we use only two parameters, how can we determine whether the second parameter is the corresponding source or deep? So I need to determine the type of the second input parameter.
Code:

The Code is as follows:


Target = target | {}; // The default value of target is null.
Var sType = typeof source;
// If the type of the second parameter is undefined or Boolean
If (sType = 'undefined' | sType = 'boolean '){
Deep = sType === 'boolean '? Source: false;
Source = target; // assign the target value to source,
Target = this; // here this refers to Object
}


Some people may have questions about the last two lines of code. My approach is as follows. If both target and source parameters exist and source is not a Boolean value, copy the content of the source Object to target. Otherwise, copy the target Object to the Object. The default value of deep is false.
For the sake of security, we also need to judge that if souce meets the above conditions, but it is not an Object, or it is a Function Object (this involves some other issues ), we cannot copy it. At this time, we set souce to an empty Object, that is, we do not perform the copy operation.
Code:

The Code is as follows:


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


Note: The Function object will return "object" when executing the typeof operation, but we cannot copy it correctly (at least not in my method ), so I have to remove it.
The following is a circular copy. Recursion is used here.
Code:

The Code is as follows:


Var I = 1, option;
// The outer loop is used to change the options in sequence, first set to target, and then set to source.
While (I <= 2 ){
Options = I = 1? Target: source;
If (options! = Null ){
// Attributes corresponding to the inner loop Replication
For (var name in options ){
Var src = target [name], copy = options [name];
If (target = copy)
Continue;
// If deep is set to true, and this attribute is an object
If (deep & copy & typeof copy = 'object '&&! Copy. nodeType)
// Recursion
Target [name] = this. extend (src | (copy. length! = Null? []: {}), Copy, deep );
Else if (copy! = Undefined)
Target [name] = copy;
}
}
I ++;
}


The recursive method is used to copy objects in sequence. This function is complete. The Code is as follows:
Code:

The Code is as follows:


/*
* @ Param {Object} target Object.
* @ Param {Object} source Object.
* @ Param {boolean} whether to copy (inherit) objects in deep.
* @ Returns {Object} returns a new Object that inherits the property of the source Object.
*/
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;
};


Example:
Code:

The Code is as follows:


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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.