


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
var obj1={name:'Tom',age:22};
var obj2={name:'Jack',height:180};
console.log($.extend(obj1,obj2)); //Object {name: "Jack", age: 22, height: 180}
$.hehe(); //alert('hehe')
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 items to wait for before
// the ready event fires. See #6781
readyWait: 1,
.....
Add properties or methods to jQuery object 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…]
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 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
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}
If used, recursive merging or deep copy
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"}
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:
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
...
}
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
var obj1={name:'Tom',love:{drink:'milk',eat:'bread'}};
var obj2={name:'Jack',love:{drink:'water',sport:'football'}};
$.extend(true,obj1,obj2)
Source code analysis
// Handle a deep copy situation
If ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
}
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.// Handle case when 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 invalid for non-object and function data types. For example, strings can call their own methods and attributes
// extend jQuery itself if only one argument is passed
If ( length === i ) {
target = this;
—i;
}
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);
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;
}
}
}
}
这个部分就是此方法的核心了,从arguements对象的第i个下标值开始循环操作首先过滤掉源对象是null或者是undefined的情况可以看到其实
源对象不一定真的就是对像,也可以是其他类型的值比如字符串比如这样写:
console.log($.extend({'name':'tom'},'aa')); //Object {0: "a", 1: "a", name: "tom"}
是不是感觉很奇怪啊?究竟是怎么实现的呢?下面接着看
过滤完之后开始进行for循环 src保存的是目标对象的某个键的值,copy属性保存的源对象的某个键的值,这两个键都是一样的
// Prevent never-ending loop
If ( target === copy ) {
continue;
}
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:
var o = {};
o.n1 = o;
$.extend( true, o, { n2: o } );
// throw exception:
// Uncaught RangeError: Maximum call stack size exceeded
But doing so will also unfairly affect some normal situations such as:
var obj1={a:'a'}
var obj2={a:obj1};
console.log($.extend(obj1,obj2)); //Object {a: "a"}
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
Object {a: Object}
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
target[ name ] = copy;
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.
// Return the modified object
Return target;
};
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:
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, 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.
// Never move original objects, clone them
Target[ name ] = jQuery.extend( deep, clone, copy );
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:
console.log($.extend({a:1},'aa')); //Object {0: "a", 1: "a", a: 1}
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
var str='aa';
for(var name in str){
console.log(name);
console.log(str[name])
}
This is also possible, it will split the string and read it according to the numerical subscript, but in the source code
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) )
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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Detailed explanation of jQuery reference method: Quick start guide jQuery is a popular JavaScript library that is widely used in website development. It simplifies JavaScript programming and provides developers with rich functions and features. This article will introduce jQuery's reference method in detail and provide specific code examples to help readers get started quickly. Introducing jQuery First, we need to introduce the jQuery library into the HTML file. It can be introduced through a CDN link or downloaded

How to use PUT request method in jQuery? In jQuery, the method of sending a PUT request is similar to sending other types of requests, but you need to pay attention to some details and parameter settings. PUT requests are typically used to update resources, such as updating data in a database or updating files on the server. The following is a specific code example using the PUT request method in jQuery. First, make sure you include the jQuery library file, then you can send a PUT request via: $.ajax({u

How to remove the height attribute of an element with jQuery? In front-end development, we often encounter the need to manipulate the height attributes of elements. Sometimes, we may need to dynamically change the height of an element, and sometimes we need to remove the height attribute of an element. This article will introduce how to use jQuery to remove the height attribute of an element and provide specific code examples. Before using jQuery to operate the height attribute, we first need to understand the height attribute in CSS. The height attribute is used to set the height of an element

Title: jQuery Tips: Quickly modify the text of all a tags on the page In web development, we often need to modify and operate elements on the page. When using jQuery, sometimes you need to modify the text content of all a tags in the page at once, which can save time and energy. The following will introduce how to use jQuery to quickly modify the text of all a tags on the page, and give specific code examples. First, we need to introduce the jQuery library file and ensure that the following code is introduced into the page: <

Title: Use jQuery to modify the text content of all a tags. jQuery is a popular JavaScript library that is widely used to handle DOM operations. In web development, we often encounter the need to modify the text content of the link tag (a tag) on the page. This article will explain how to use jQuery to achieve this goal, and provide specific code examples. First, we need to introduce the jQuery library into the page. Add the following code in the HTML file:

jQuery is a fast, small, feature-rich JavaScript library widely used in front-end development. Since its release in 2006, jQuery has become one of the tools of choice for many developers, but in practical applications, it also has some advantages and disadvantages. This article will deeply analyze the advantages and disadvantages of jQuery and illustrate it with specific code examples. Advantages: 1. Concise syntax jQuery's syntax design is concise and clear, which can greatly improve the readability and writing efficiency of the code. for example,

jQuery is a popular JavaScript library that is widely used to handle DOM manipulation and event handling in web pages. In jQuery, the eq() method is used to select elements at a specified index position. The specific usage and application scenarios are as follows. In jQuery, the eq() method selects the element at a specified index position. Index positions start counting from 0, i.e. the index of the first element is 0, the index of the second element is 1, and so on. The syntax of the eq() method is as follows: $("s

How to tell if a jQuery element has a specific attribute? When using jQuery to operate DOM elements, you often encounter situations where you need to determine whether an element has a specific attribute. In this case, we can easily implement this function with the help of the methods provided by jQuery. The following will introduce two commonly used methods to determine whether a jQuery element has specific attributes, and attach specific code examples. Method 1: Use the attr() method and typeof operator // to determine whether the element has a specific attribute
