Home > Web Front-end > JS Tutorial > body text

A small problem with $.extend_jquery

WBOY
Release: 2016-05-16 15:54:27
Original
1085 people have browsed it

I have been working on the mobile terminal recently. Since I am familiar with jQuery and Zepto provides the same API as jQuery, I chose Zepto as the development framework.

Since it is a mobile development, some new ES5 APIs are also used, such as forEach. Here are some examples of the code I wrote:

list.forEach(function(v) {
 return !!v;
})

Copy after login

I naively thought that forEach was just like jQuery’s each. As long as my return value was false, it would interrupt the loop. So, I wrote a lot of traversal code like this (I was really too lazy to write it for each traversal). Declare variables)

After writing for a while, I suddenly discovered that the callback function of forEach cannot interrupt the loop, so I hung a function on Array.prototype, and then replacedAll, perfect.

 Array.prototype.foreach = function(fn) {
  var i = 0, len = this.length;

  for (; i < len; ++i) {

    if (fn(this[i], i) === false) {
     break;
    }
   }
 };

Copy after login

Until one day, I wanted to do some optimization. Considering that the json that the client needs to save is too large (I kid you not, the maximum can be 20M), stringify is too time-consuming and will block the UI, so I Use Worker to open a thread in the background specifically to stringify this json, similar to this:

Copy code The code is as follows:

addEventListener("message", function(e) {
var data = e.data;
data = JSON.stringify(data);
postMessage(data);
}, false);

posMesage:

Copy code The code is as follows:

worker.postMessage(data)

But the console output the following error message:

Copy code The code is as follows:

Uncaught DataCloneError: Failed to execute 'postMessage' on 'Worker': An object could not be cloned.

What the hell, why can’t I even copy a json? So, I started looking for the reason, and I found this thing in my json:

Oh my god, what the hell is this? Why did this foreach come in? I looked at $.extend(true, {}, obj) in the editor and it was trembling there. I couldn’t help but wonder, it couldn’t be you. You must be causing trouble. So, I checked the source code of $.extend:

 function extend(target, source, deep) {
  for (key in source)
   if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
    if (isPlainObject(source[key]) && !isPlainObject(target[key]))
     target[key] = {}
    if (isArray(source[key]) && !isArray(target[key]))
     target[key] = []
    extend(target[key], source[key], deep)
   }
   else if (source[key] !== undefined) target[key] = source[key]
 }

 // Copy all but undefined properties from one or more
 // objects to the `target` object.
 $.extend = function(target){
  var deep, args = slice.call(arguments, 1)
  if (typeof target == 'boolean') {
   deep = target
   target = args.shift()
  }
  args.forEach(function(arg){ extend(target, arg, deep) })
  return target
 }

Copy after login

Oh my God, this guy is really causing trouble. It’s okay to use for...in... to traverse the array, but else if (source[key] !== undefined) target[key] = source[ key] Can the conditions here be more serious? Adding hasOwnProperty to check will not waste much time. With tears streaming down my face

After being cheated by Zepto, I immediately went to jQuery to complain, hoping it could comfort me, but unexpectedly:

jQuery.extend = jQuery.fn.extend = function() {
  var options, name, src, copy, copyIsArray, clone,
    target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false;

  // Handle a deep copy situation
  if ( typeof target === "boolean" ) {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // Handle case when target is a string or something (possible in deep copy)
  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
    target = {};
  }

  // extend jQuery itself if only one argument is passed
  if ( length === i ) {
    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) &#63; src : [];

          } else {
            clone = src && jQuery.isPlainObject(src) &#63; 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;
};

Copy after login

This guy is also else if ( copy !== undefined ) {target[ name ] = copy;} Just tell me, my dear mother.

In the end I had no choice but to write one myself.

Summary: When you want to use $.extend, don’t easily add your custom properties and methods to Array.prototype and Object.prototype, otherwise, you may have to find bugs in the future.

The above is the entire content of this article, I hope you all like it.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!