The Extend () and Fn.extend () methods in jquery are detailed _jquery

Source: Internet
Author: User
Tags extend

The two methods use the same code, one for the jquery object or the common object merging properties and methods, one for the jquery object, and a few examples for the basic usage:

The HTML code is as follows:

code as follows:

<!doctype html>
<title></title>
<script src= ' jquery-1.7.1.js ' ></script>
<body>

</body> 

Below write JS inside usage:

Merge two Normal objects

code as follows:

Combine properties for two normal objects
var obj1={name: ' Tom ', age:22};
var obj2={name: ' Jack ', height:180};
Console.log ($.extend (OBJ1,OBJ2)); Object {name: "Jack", Age:22, height:180} 

Add attributes or methods to a jquery object

code as follows:

$.extend ({hehe:function () {alert (' hehe ');}});
$.hehe (); Alert (' hehe ')

This usage is very important, is the implementation method of adding instance properties and methods as well as prototype properties and methods inside jquery is also the method of writing jquery Plug-ins, the following is the method and attribute of jQuery1.7.1 using extend method to extend its own

code as follows:

Jquery.extend ({
Noconflict:function (deep) {
if (window.$ = = jQuery) {
window.$ = _$;
}
if (deep && window.jquery = = jQuery) {
Window.jquery = _jquery;
}
return jQuery;
},
Is the DOM ready to be used? Set to True once it occurs.
Isready:false,
A counter to track how many the items to the wait for before
The Ready event fires. #6781
Readywait:1,
.....

In this example, only one object parameter is passed in, so by default this is treated as an object to be merged

Add a property or method to a jquery object instance

code as follows:

Extending the merge for jquery instances
Console.log (' img '). Extend ({' title ': ' img '});//[img, Img#img.img, prevobject:jquery.fn.jquery.init[1], context: Document, selector: "img", Title: "img", constructor:function ...] 

Merge only and do not modify objects to be merged

code as follows:

var obj1={name: ' Tom ', age:22};
var obj2={name: ' Jack ', height:180};
Console.log ($.extend (OBJ1,OBJ2)); Object {name: "Jack", Age:22, height:180}
Console.log (OBJ1); Object {name: "Jack", Age:22, height:180}

By default, the objects to be merged are modified as if they were returned, and you can use this method if you just want a merged object and don't want to break any of the original objects.

code as follows:

var obj1={name: ' Tom ', age:22};
var obj2={name: ' Jack ', height:180};
var empty={};
Console.log ($.extend (EMPTY,OBJ1,OBJ2)); Object {name: "Jack", Age:22, height:180}
Console.log (OBJ1); Object {name: "Tom", age:22}

Use recursive merge or deep copy

code as follows:

var obj1={name: ' Tom ', Love:{drink: ' Milk ', eat: ' Bread '};
var obj2={name: ' Jack ', Love:{drink: ' Water ', sport: ' Football '};
Console.log (($.extend (FALSE,OBJ1,OBJ2)). Love); Object {drink: "Water", Sport: "Football"}
Console.log (($.extend (TRUE,OBJ1,OBJ2)). Love); Object {drink: "Water", Eat: "Bread", Sport: "Football"}

Detailed use of the method can be seen in the reference manual http://www.w3cschool.cc/manual/jquery/

Below to analyze how the following 1.7.1 source code is implemented:

code as follows:

Jquery.extend = JQuery.fn.extend = function () {
var options, name, SRC, copy, Copyisarray, clone,
target = Arguments[0] | | {},
i = 1,
Length = Arguments.length,
Deep = false;
...
}

The first is to define a set of variables, because the number of parameters is not sure, so we call the arguments object access directly to the arguments passed

Variable options: Point to a source object.

Variable Name: Represents a property name for a source object.
Variable src: The original value representing a property of the target object.
Variable copy: Represents the value of a property of a source object.
Variable Copyisarray: Indicates whether the variable copy is an array.
Variable clone: A fixup value that represents the original value of a deep copy.
Variable target: point to target object.
Variable I: Represents the starting subscript of the source object.
Variable length: Represents the number of parameters that are used to correct variable target.
Variable deep: Indicates whether deep replication is performed, false by default.

To better understand the implementation of the code here, take an example of the above as a demonstration to observe source code execution

code as follows:

var obj1={name: ' Tom ', Love:{drink: ' Milk ', eat: ' Bread '};
var obj2={name: ' Jack ', Love:{drink: ' Water ', sport: ' Football '};
$.extend (TRUE,OBJ1,OBJ2)

SOURCE Analysis

code as follows:
Handle a deep copy situation
if (typeof target = = "Boolean") {
Deep = target;
target = Arguments[1] | | {};
Skip the Boolean and the target
i = 2;

To determine if the first parameter is a Boolean value, then give the value of the first parameter to deep, and then the second argument as the target object, if the second argument does not exist, assign to an empty object, and then change the subscript of the source object to 2, in this example It's going to be here. Because the first argument is ture and then the deep is true, target is corrected to the second parameter, Obj1, and the source object starts with a subscript of 2, which starts with the third as the source object, which is the obj2 in this example.

code as follows:
Handle case as Target is a string or something (possible in deep copy)
if (typeof target!== "Object" &&!jquery.isfunction (target)) {
target = {};

The target is further processed here. Adding custom attributes is not valid for data types of objects and functions, such as strings can call self-contained methods and properties

code as follows:
Extend JQuery itself if only one argument is passed
if (length = = i) {
target = this;
I.;
}

If the Length property equals I value that means no target object exists, and normally length should be greater than I, then this is the target object to reduce the I value by one implementation length value greater than I (1)

This is the implementation of JQuery's method of extending attributes to itself, as long as it is not passed on to the target object.

Two possible scenarios: $.extend (obj) or $.extend (false/true,obj);

code as follows:

for (; i < length; i++) {
Only deal with non-null/undefined values
if (options = arguments[i])!= null) {
Extend the Base Object
for (name in options) {
src = target[name];
copy = options[name];
Prevent never-ending Loop
if (target = = copy) {
Continue
}
recurse if we ' re merging plain objects or arrays
if (deep && copy && jquery.isplainobject (copy) | | (Copyisarray = Jquery.isarray (copy)) ) {
if (Copyisarray) {
Copyisarray = false;
clone = src && jquery.isarray (src)? SRC: [];
} else {
clone = src && jquery.isplainobject (src)? src: {};
}
Never move original objects, clone them
target[name] = Jquery.extend (deep, clone, copy);
Don ' t bring in undefined values
else if (copy!== undefined) {
target[name] = copy;
}
}
}

This part is the core of this method, starting with the Arguements object's subscript value to start the loop operation to first filter out the source object is null or undefined can be seen in fact

The source object does not have to be a true image, or it can be another type of value such as a string, such as writing:

code as follows:

Console.log ($.extend ({' name ': ' Tom '}, ' AA ')); Object {0: "A", 1: "A", Name: "Tom"}

Does it feel weird? How did it actually happen? Next look

After filtering, start for loop SRC holds the value of a key of the target object, the value of a key of the source object saved by the Copy property, and the two keys are the same

code as follows:

Prevent never-ending Loop
if (target = = copy) {
Continue
}

If a property value of the source object is a target object that can cause a dead loop to cause the program to crash so here's a restriction to skip this loop for example:

code as follows:

var o = {};
O.N1 = O;
$.extend (True, O, {n2:o});
Throw an exception:
uncaught rangeerror:maximum Call stack size exceeded

But doing so would have wronged some normal situations, such as:

code as follows:

var obj1={a: ' A '}
var obj2={a:obj1};
Console.log ($.extend (OBJ1,OBJ2)); Object {A: "a"}

This situation is also satisfied with the source object value equals the target object, but the result found that Obj1 's attribute value has not been modified, is because the implementation of the continue, the following source code for this comment dropped in the implementation

code as follows:

Object {A:object}

This is a normal time to be modified. Personal feeling this place needs to be improved;

Then there is an if judgment is to distinguish whether the depth of replication is not to look at the depth of the first to copy the general

code as follows:

target[name] = copy;

Very simple is that as long as the copy has a value directly copied to the target object, some of the target object on the modification did not increase, so that the merger is achieved.

After the For loop returns the new target object, the target object is finally modified and the result is the same as the result returned.

code as follows:

Return the Modified Object
return target;
};


Let's talk about how to deal with the deep copy.

The first thing to do is to ensure that the deep is true,copy with a value and is an object or an array (if it is not an object and a depth copy of the objects) and then it is processed by fractional groups and objects, first to look at the array:

code as follows:

if (Copyisarray) {
Copyisarray = false;
clone = src && jquery.isarray (src)? SRC: [];

} else {

clone = src && jquery.isplainobject (src)? src: {};
}

If the value of the array Copyisarray is true and then go inside to change the value to False, for the current loop of the source object properties, the target object may or may not be, some of the words to determine whether the array is the original array is not change is not to let it become an array, Since the current property of the source object is the last target element of the array, it must also be an array. Not an array is an object that changes the current property of the target object to an object.

code as follows:

Never move original objects, clone them
target[name] = Jquery.extend (deep, clone, copy);

The current attribute value of the source object (the array or object) and the current properties of the target object that has been modified are then recursively merged with the new array or object assigned to the target object, and finally the deep copy is realized.

But there is also a strange phenomenon, such as the operation:

code as follows:

Console.log ($.extend ({a:1}, ' AA ')); Object {0: "A", 1: "A", a:1}

The original source object is not really an object E and actually can take apart the string with the target object merge, the original for...in loop is the operation of the string

code as follows:

var str= ' AA ';
for (var name in str) {
Console.log (name);
Console.log (Str[name])
}

This is also possible, the string will be opened by digital subscript read, but in the source code

code as follows:

if (deep && copy && jquery.isplainobject (copy) | | (Copyisarray = Jquery.isarray (copy)) ) 

There are arrays and object restrictions, then the depth of replication is not the effect of it?

After I test the depth of replication is also possible, because in the source code of the value of the copy has become an anonymous function function

Alert (jquery.isplainobject (copy)); True

As for why the function of the author has not been clear to be left to solve it later!

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.