Implementation of extend in jquery

Source: Internet
Author: User

Implementation of extend in jquery

Generally, when we use the extend of jquery, most of them are used to overwrite the default field. That is, if the value of a field is input, the input value is used; otherwise, the default value is used. The following code:

function getOpt(option){var _default = {name : 'wenzi',age : '25',sex : 'male'}$.extend(_default, option);return _default;}getOpt();  // {name: wenzi, age: 25, sex: male}getOpt({name:'bing'}); // {name: bing, age: 25, sex: male}getOpt({name:'bing', age:36, sex:'female'});  // {name: bing, age: 36, sex: female}

Now we need to know how this extend is implemented. Apart from implementing the above functions, are there other functions? That must be the case. Otherwise, I won't ask that sentence (⊙ ﹏ ⊙) B ). Let's first take a look at the main functions of extend, and then look at how these functions are implemented.

1. functions implemented by extend

In fact, from the meaning of extend, we can know what extend is. After extend is translated into Chinese, it is extended, extended, and promoted.

1.1 merge the content of two or more objects into the first object

Let's take a look.$.extend()Provided parameters:jQuery.extend( target [, object1 ] [, objectN ] ), The extend method requires at least one parameter. The first parameter is required, and all the following parameters are optional. If two or more parameters passed to extend are of the object type, the content of all subsequent objects will be merged to the target (first object.

Let's take a look at the above example:

function getOpt(option){var _default = {name : 'wenzi',age : '25',sex : 'male'}`$.extend(_default, option);`return _default;}

$.extend()If two parameters _ default and option are received, the value of the field on the option object is given to _ default when the extend method is executed. Therefore, the default value set on _ default will be overwritten by the value on option. Of course, if option does not have this field, it will not overwrite the value of the _ default field.

In the extend function above, only two parameters are passed in. What about more parameters:

function getOpt(target, obj1, obj2, obj3){    $.extend(target, obj1, obj2, obj3);    return target;}var _default = {    name : 'wenzi',    age : '25',    sex : 'male'}var obj1 = {    name : 'obj1'}var obj2 = {    name : 'obj2',    age : '36'}var obj3 = {    age : '67',    sex : {'error':'sorry, I dont't kown'}}getOpt(_default, obj1, obj2, obj3);  // {name: obj2, age: 67, sex: {error: sorry, I dont't kown}}

Here we pass in four parameters, and then getOpt () returns the value of the first parameter. From the running result, we can see that the attribute value is always the value of the last attribute.

Another important point is that,$.extend()Actually, there is a return value. The returned value is the value of the first parameter after modification. For example, we can modify the above function as follows:

Function getOpt (target, obj1, obj2, obj3) {var result = $. extend (target, obj1, obj2, obj3); return result; // result indicates the modified target value}

If the input parameter does not want to be modified, we can use an empty object as the first parameter and obtain$.extend()Return Value:

Function getOpt (target, obj1, obj2, obj3) {var result = $. extend ({}, target, obj1, obj2, obj3); return result; // result is the modified value}
1.2 JQUERY extension methods or attributes

What we mentioned in section 1.1$.extend()In this example, two or more parameters are passed, but only one parameter is required. What if I pass only one parameter.

If only one parameter is provided$.extend()This means that the target parameter is omitted. In this case, the jQuery object itself is the default target object. In this way, we can add new functions under the namespace of jQuery. This is useful for plug-in developers who want to add new functions to jQuery.

$.extend({_name : 'wenzi',_getName : function(){return this._name;}})$._name; // wenzi$._getName(); // wenzi

In this way, we have extended jQuery._nameAttributes and_getNameMethod.

1.3 deep copy and shortest copy

For what is deep copy and what is simple copy, let's look at a simple example.

Var obj = {name: 'wenzi', sex: 'male'}; var obj1 = obj; // value obj1.name = 'bin'; console. log (obj. name); // bing

We modified the name value in obj1, and the value in the result obj also changed. Why. In fact, this isSimple copy: This simply copies the reference address of the obj object to the variable obj1, instead of cloning the real object, therefore, obj and obj1 point to the same address. Obj is affected when you modify the obj1 attribute or add a new attribute to obj1.

However, if the value of a variable is not an object or an array, the modified variable will not affect the previous variable:

var s = 'hello';var t = s;t = 'world';console.log(s); // hello

In this case, the deep copy does not copy the reference address, but actually copies a new object to the new variable. Use$.extend()Is used for the shortest copy. Therefore, if the following parameter values are of the object or array type, modifying the value of _ default (target) will affect the values of the following parameters.

For example, we usegetOpt(_default, obj1, obj2, obj3);The value of _ default is {name: "obj2", age: "67", sex: {error: "sorry, I dont't kown"}. However, if:

_default.sex.error = 'hello world';

The obj3.sex. error will also be modified because obj3.sex is of the object type.

However$.extend()The deep COPY method is also provided: jQuery. extend ([deep], target, object1 [, objectN]). If the first parameter is of the boolean type and the value is true, the second parameter is merged as the target parameter.

var obj = {name:'wenzi', score:80};var obj1 = {score:{english:80, math:90}}$.extend(true, obj, obj1);obj.score.english = 10;console.log(obj.score.english);   // 10console.log(obj1.score.english);  // 80

After the execution, we found that no matter how we modify the values in obj. score, it will not affect the obj1.score.

2. extend implementation principle in jQuery

In fact, the general process of extend should also be understood without looking at the source code: loop the next parameter, and then give all the fields on the following parameter to the first field, if the first parameter has the same field, overwrite it. Otherwise, add a new field.

The following is the source code of extend in jQuery. I will comment on the source code and then summarize it later:

// Corresponds to the subscript of the source code. We call the first parameter '100 parameters', and so on jQuery. extend = jQuery. fn. extend = function () {var options, name, src, copy, copyIsArray, clone, target = arguments [0] | {}, // The default 0th parameters are the target parameter I = 1. // I indicates merging the target parameters from the first few parameters, such as case, by default, length = arguments is merged into the 1st parameters starting from the 0th parameters. length, deep = false; // The default value is copy in a shortest. // judge the type of The 0th parameters. If the 0th parameters are of the boolean type, returns true or false. // 1st parameters are used as the target parameter at the same time. I will use the next // Handle a deep copy situationif (typeof targ Et = boolean) {deep = target; // Skip the boolean and the targettarget = arguments [I] |{}; I ++ ;} // determine the type of the target parameter. If the target parameter is neither the object type nor the function type, assign a value to the target parameter // Handle case when target is a string or something (possible in deep copy) if (typeof target! = Object &&! JQuery. isFunction (target) {target ={};}// if no parameter is added to the target parameter, for example, $. extend ({_ name: 'wenzi'}), $. extend (true, {_ name: 'wenzi'}) // The target parameter is jQuery, the target parameter is no longer the target parameter // Extend jQuery itself if only one argument is passedif (I = length) {target = this; I --;} // start from the I parameter for (; I <length; I ++) {// obtain the I parameter, and this parameter is not null, // such as $. the first parameter null in extend (target, {}, null); is not involved in merging // Only deal with non-null/undefined value Sif (options = arguments [I])! = Null) {// USE ~ In to get all the fields of this parameter // Extend the base objectfor (name in options) {src = target [name]; // The value of the name field in the target parameter copy = options [name]; // The value of the name field in the current parameter // if the value of the field in the parameter is the target parameter, stop the assignment, assign a value to the next field // This is to prevent infinite loop nesting. We call this, the following describes in detail // Prevent never-ending loopif (target = copy) {continue;} // If deep is true, if the value of the name field in the current parameter exists and is of the object or Array type, perform an in-depth assignment // Recurse if we're re merging plain objects or arraysif (deep & copy && (JQuery. isPlainObject (copy) | (copyIsArray = jQuery. isArray (copy) {// if the value of the name field in the current parameter is of the Array type, // you can determine whether the value of the name field in the target parameter exists, if yes, use the original one. Otherwise, initialize if (copyIsArray) {copyIsArray = false; clone = src & jQuery. isArray (src )? Src: [];} else {// if the original object exists, use it directly instead of creating clone = src & jQuery. isPlainObject (src )? Src: {};}// recursive processing. Here it is 2.2 // Never move original objects, clone themtarget [name] = jQuery. extend (deep, clone, copy); // If deep is false, it indicates a copy of the shortest degree, which is directly assigned a value. // If copy is of a simple type and has a value, assign a value directly // Don't bring in undefined values} else if (copy! = Undefined) {// if the original object has the name attribute, it will be overwritten directly. If not, a new attribute target [name] = copy ;}}} will be created ;}}}} // Return the modified target parameter // Return the modified objectreturn target ;};

After analyzing the source code, let's take a look at the difficulties and key points in the source code.

2.1 if the value of a field in the parameter is the target parameter, stop the assignment.

The following judgment is made in the source code:

// Prevent never-ending loopif ( target === copy ) {continue;}

Why is there such a judgment? Let's look at a simple example. What if we don't have this judgment:

var _default = {name : 'wenzi'};var obj = {name : _default}$.extend(_default, obj);console.log(_default);

What is the output _ default:

_default = {name : _default}; 

_ Default is of the object type. There is a field name with the value of _ default, while _ default is of the object type. There is a field name with the value of _ default ......, An infinite loop goes on. Therefore, jQuery does not directly perform operations. Skip this field and perform operations on the next field.

2.2 recursive processing during deep copy

As we have explained in the previous section, when the value of a variable is of a simple type (such as number, string, or boolean), the value of the previous variable is not affected. Therefore, if the value of the current field isObjectOrArrayType, which must be split until the field value is of a simple type (such as number, string, boolean.

3. $. extend () and $. fn. extend ()

All of the above are $. extend (), which is not mentioned at all. $. fn. extend (). However, have you found a detail about how to write the first line of this Code:

jQuery.extend = jQuery.fn.extend = function(){}

That is to say, $. extend () and $. fn. extend () share the same function body. All operations are the same, but the two extends use different objects:$.extend()Operations are performed on jQuery ($ ).$.fn.extend()Is operated on the jQuery object, such as $ ('div '). extend ().

4. Summary

This is the implementation of extend in jQuery. If we need to use the above functions in the future, apart from using $. extend (), we can also write a simple extend () without introducing the jQuery framework to implement the above functions.

 

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.