Analysis of jQuery. extend () method
The jQuery. extend method is a common method and a basic method in jQuery source code. It combines one or more "Source objects" into a "target object" and returns the target object. It has three forms: a and jQuery. extend (destination, source1, source2, soure3 ....) b. jQuery. extend (source) c, jQuery. extend (boolean, destination, source1, source2, soure3 ....) method a uses the first parameter as the "target object" and other parameters as the "source object ". Method B has only one parameter. Here this parameter is changed to "source object" and "target object" to jQuery. To put it bluntly, it is the property of the "source object", which is changed to the static method or attribute of the jQuery function. In method c, the first parameter is of the boolean type, the second parameter is the "target object", and the remaining parameter is the "source object ". When the value of the first parameter is true, it indicates that "Deep copy" is supported during object merging ". With the usage of the function, we must be curious about how jQuery is implemented. I want to see the jQuery source code. However, before looking at the jQuery source code, we may try to write the function of this method. Then, let's look back at the jQuery source code and feel more deeply. The more things we can see. First, we should not put pressure on ourselves. First, we should start with the simplest method. The method to be implemented has two parameters: the first parameter is "target object", and the second parameter is: "source object ". First, merge "source object" into "target object. The Code is as follows: copy the code var Test = function () {} Test. extend0 = function (destination, source) {for (var key in source) {destination [key] = source [key]} return destination} copy the code to implement the second step. Multiple parameters can be input. The first parameter is the target object, and other parameters are the source object. The Code is as follows: copy the code Test. extend1 = function () {var destination = arguments [0] var sourceArr = Array. prototype. slice. call (arguments, 1) for (var I = 0, len = sourceArr. length; I <len; I ++) {var source = sourceArr [I] for (var key in source) {destination [key] = source [key]} return destination} copy the code. When there is only one parameter in step 3, append the property of the parameter object to Test. The Code is as follows: copy the code Test. extend2 = function () {var argumentsLen = arguments. length if (argumentsLen = 1) {var source = arguments [0] for (var key in source) {Test [key] = source [key]} else {var destination = arguments [0] var sourceArr = Array. prototype. slice. call (arguments, 1) for (var I = 0, len = sourceArr. length; I <len; I ++) {var source = sourceArr [I] for (var key in source) {destination [key] = source [ke Y]} return destination} copy the code to implement "Deep copy" in Step 4. The first parameter is whether to make a Boolean check for deep copy, and the second parameter is the target object, other parameters are source objects. The Code is as follows: copy the code Test. extend3 = function () {var argumentsLen = arguments. length if (argumentsLen = 1) {var source = arguments [0] for (var key in source) {Test [key] = source [key]} else {var firstItem = arguments [0] var isBoolean = typeof firstItem = "boolean" var destination = isBoolean? Arguments [1]: firstItem var startNum = isBoolean? 2: 1 var sourceArr = Array. prototype. slice. call (arguments, startNum) for (var I = 0, len = sourceArr. length; I <len; I ++) {var source = sourceArr [I] if (isBoolean) {deepExtend (destination, source)} else {for (var key in source) {destination [key] = source [key] }}} return destination} function deepExtend (destination, source) {for (var key in source) {var value = source [key] if (value instanceof Array) {destination [key] = arguments. callee. call (destination [key] | [], value)} else if (value instanceof Object) {destination [key] = arguments. callee. call (destination [key] | |{}, value)} else {destination [key] = source [key] }} return destination} copy the code. follow our own ideas, you have roughly implemented your own extend method. Now let's take a look at jQuery's implementation of extend. The source code is as follows: copy the code jQuery. extend = jQuery. fn. extend = function () {var src, copyIsArray, copy, name, options, clone, target = arguments [0] |{}, I = 1, length = arguments. length, deep = false; // Handle a deep copy situation if (typeof target = "boolean") {deep = target; // skip the boolean and the target = arguments [I] |{}; I ++;} // Handle case when target is a string or something (possib Le in deep copy) if (typeof target! = "Object "&&! JQuery. isFunction (target) {target ={};}// extend jQuery itself if only one argument is passed if (I === length) {target = this; I --;} 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 ;}}// Return the modified object return target;} After copying the code, we find that: a. jQuery is more elegant in code organization and implementation. B. jQuery has considered some special cases. For example, if (target = copy) {continue;} is used to avoid infinite loops. the attribute of "source object" points to "target object". When merging objects, that is, copy "yourself" as "your own attributes ". This is not desirable. C. jQuery considers the Array (jQuery. isArray) and "Pure object" (jQuery. isPlainObject) more precisely. This learning method is quite good if you want to implement it by yourself and then compare it with others. A. Enhanced independent thinking capabilities. B. Discover new learning content. C. Expose your own shortcomings.