Home >Web Front-end >JS Tutorial >Detailed explanation of extend() and fn.extend() methods in jQuery_jquery
These two methods use the same code. One is used to merge properties and methods for jQuery objects or ordinary objects. The other is for instances of jQuery objects. Here are a few examples of basic usage:
The html code is as follows:
Merge two ordinary objects
Add properties or methods to jQuery object instances
By default, the object to be merged is modified like the returned result. If you just want to get a merged object but do not want to destroy any of the original objects, you can use this method
If used, recursive merging or deep copy
For detailed usage, please see the reference manual http://www.w3cschool.cc/manual/jquery/
Let’s analyze how it is implemented in the 1.7.1 source code:
First, a set of variables is defined. Since the number of parameters is uncertain, the arguments object is directly called to access the passed parameters
Variable options: points to a source object.
Variable name: represents an attribute name of a source object.
Variable src: Represents the original value of an attribute of the target object.
Variable copy: represents the value of an attribute of a source object.
Variable copyIsArray: Indicates whether the variable copy is an array.
Variable clone: represents the correction value of the original value during deep copying.
Variable target: points to the target object.
Variable i: represents the starting index of the source object.
Variable length: indicates the number of parameters and is used to modify the variable target.
Variable deep: indicates whether to perform deep copy, the default is false.
In order to better understand the code implementation, here is an example given above as a demonstration to observe the execution of the source code
Source code analysis
Determine whether it is a deep copy. If the first parameter is a Boolean value, then give the value of the first parameter to deep, and then use the second parameter as the target object. If the second parameter does not exist, assign it to one. Empty object, change the subscript of the source object to 2. In this example, it is done here because the first parameter is true and then deep is changed to true. The target is modified to the second parameter, which is obj1. The starting subscript of the source object is 2, which means starting from the third one as the source object, which is obj2
in this example.The target is further processed here. Adding custom attributes is invalid for non-object and function data types. For example, strings can call their own methods and attributes
If the length attribute is equal to the value of i, it means that there is no target object. Under normal circumstances, length should be greater than the value of i. Then use this as the target object at this time and reduce the i value by one to achieve the length value greater than the i value. (1 greater than i)
This is the implementation principle of jQuery’s method of extending attributes to itself, as long as the target object is not passed in
Two possible situations: $.extend(obj) or $.extend(false/true,obj);
这个部分就是此方法的核心了,从arguements对象的第i个下标值开始循环操作首先过滤掉源对象是null或者是undefined的情况可以看到其实
源对象不一定真的就是对像,也可以是其他类型的值比如字符串比如这样写:
是不是感觉很奇怪啊?究竟是怎么实现的呢?下面接着看
过滤完之后开始进行for循环 src保存的是目标对象的某个键的值,copy属性保存的源对象的某个键的值,这两个键都是一样的
If a certain attribute value of the source object is the target object, it may cause an infinite loop and cause the program to crash, so a restriction is made here to allow it to skip this loop. For example:
But doing so will also unfairly affect some normal situations such as:
This situation also satisfies that the source object value is equal to the target object, but it turns out that the attribute value of a of obj1 has not been modified, because continue is executed. Below, comment out this paragraph in the source code before executing
At this time, it has been modified normally. I personally feel that this area needs improvement;
Then there is an if judgment, which is to distinguish whether it is a deep copy. First, do not look at the deep copy and first look at the general
It is very simple. As long as the copy has a value, it is copied directly to the target object. If the target object has some modifications, it is added. In this way, the merge is achieved.
After the for loop, the new target object is returned, so the target object is finally modified, and the result is the same as the returned result.
Let’s talk about how to handle deep copy
First ensure that deep is true, copy has a value and is an object or array (if it is not an object or array, deep copying is out of the question) and then it is processed by arrays and objects. Let’s look at the array first:
} else {
clone = src && jQuery.isPlainObject(src) ? src: {};
}
If the value of the array copyIsArray is true, then go inside and change the value to false. For the source object attribute of the current loop, the target object may or may not have it. If it does, judge whether it is an array. If so, it is the original one. If the array is unchanged, let it become an array, because since the current attribute of the source object is the array, the last target element must also be an array. Either an array or an object. Change the current properties of the target object to an object.
Then recursively merge the current attribute value of the source object (which is an array or object) and the current attribute of the modified target object and assign the returned new array or object to the target object, ultimately achieving deep copying.
But there is a rather strange phenomenon here, such as this:
The original source object is not necessarily the object e, and the string can be split and merged with the target object. It turns out that the for...in loop operates on strings
This is also possible, it will split the string and read it according to the numerical subscript, but in the source code
is limited to arrays and objects, so will it have no effect during deep copying?
After my test, deep copying is also possible, because the copied value in the source code turned into an anonymous function
alert(jQuery.isPlainObject(copy)); //true
As for why it is a function, I haven’t figured it out yet and will leave it to be solved later!