ホームページ  >  記事  >  ウェブフロントエンド  >  $.extend_jquery に関する小さな問題

$.extend_jquery に関する小さな問題

WBOY
WBOYオリジナル
2016-05-16 15:54:271115ブラウズ

私は最近モバイル端末に取り組んでおり、Zepto は jQuery と同じ API を提供しているため、開発フレームワークとして Zepto を選択しました。

これはモバイル開発であるため、forEach などのいくつかの新しい ES5 API も使用されます。次に、私が作成したコードの例をいくつか示します。

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

私は単純に、forEach は jQuery の each と同じように、戻り値が false である限りループを中断すると考えていました。そのため、このようなトラバーサル コードをたくさん書きました (本当に書くのが面倒でした)。各走査) 変数を宣言します)

しばらく書いていたら、forEach のコールバック関数ではループを中断できないことに気づき、Array.prototype に関数をぶら下げて、replaceAll すれば完璧でした。

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

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

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

ある日まで、私はクライアントが保存する必要がある JSON が大きすぎることを考慮して (最大 20M になる可能性があります)、stringify は時間がかかりすぎるため、最適化を実行したいと考えていました。 UI なので、Worker を使用して、特にこの JSON を文字列化するためにバックグラウンドでスレッドを開きます。次のようになります。

コードをコピーします コードは次のとおりです:

addEventListener("メッセージ", function(e) {
var data = e.data;
データ = JSON.stringify(data);
postMessage(データ);
}, false);

posメッセージ:

コードをコピーします コードは次のとおりです:

worker.postMessage(data)

しかし、コンソールには次のエラー メッセージが出力されました:

コードをコピーします コードは次のとおりです:

Uncaught DataCloneError: 'Worker' で 'postMessage' の実行に失敗しました: オブジェクトを複製できませんでした。

一体、なぜ JSON をコピーすることさえできないのでしょうか?そこで、その理由を探し始めたところ、JSON で次のことがわかりました。

なんと、これは一体何なのでしょう? エディターで $.extend(true, {}, obj) を見たとき、不思議に思わずにはいられませんでした。 、あなたが問題を起こしているはずはありません。そこで、$.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
 }

なんと、この男は本当に問題を引き起こしています。配列を走査するために for...in... を使用するのは問題ありませんが、それ以外の場合は if (source[key] !== unknown) target[key] = source を使用します。 [ key] ここでの条件はさらに深刻なものになる可能性がありますか? hasOwnProperty を追加してチェックすることで、多くの時間を無駄にすることはありません。涙が頬を伝いながら

Zepto に騙された後、私はすぐに jQuery に文句を言いに行き、それが私を慰めてくれることを期待しましたが、予想外に次のことが起こりました。

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;
};

この男も else if ( copy !== unknown ) {target[ name ] = copy;} 教えてください、親愛なるお母さん。

結局、自分で書くしかありませんでした。

要約: $.extend を使用する場合は、カスタム プロパティとメソッドを Array.prototype と Object.prototype に簡単に追加しないでください。そうしないと、将来バグを見つけなければならない可能性があります。

以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。