Underscore.js 1.3.3 Arahan terjemahan anotasi bahasa Cina_Pengetahuan asas

WBOY
Lepaskan: 2016-05-16 15:52:54
asal
1342 orang telah melayarinya
// Underscore.js 1.3.3

// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.

// Underscore boleh diedarkan secara bebas di bawah lesen MIT.

// Bahagian Garis Bawah diilhamkan atau dipinjam daripada Prototaip,

// Oliver Steele's Functional, dan John Resig's Micro-Templating.

// Untuk semua butiran dan dokumentasi:

// http://documentcloud.github.com/underscore

(fungsi() {

 

  // Cipta objek global, diwakili sebagai objek tetingkap dalam penyemak imbas dan objek global dalam Node.js

  var root = ini;

 

  //Simpan nilai sebelum "_" (pembolehubah garis bawah) ditimpa

  // Jika terdapat konflik penamaan atau mempertimbangkan spesifikasi, kaedah _.noConflict() boleh digunakan untuk memulihkan nilai "_" sebelum ia diduduki oleh Underscore dan mengembalikan objek Underscore untuk menamakan semula

  var previousUnderscore = root._;

 

  //Buat pemalar objek kosong untuk perkongsian dan penggunaan dalaman

  pemutus var = {};

 

  //Cache rantai prototaip objek terbina dalam dalam pembolehubah tempatan untuk memudahkan panggilan pantas

  var ArrayProto = Array.prototype, //

  ObjProto = Object.prototype, //

  FuncProto = Function.prototype;

 

  //Cache kaedah biasa dalam prototaip objek terbina dalam dalam pembolehubah tempatan untuk panggilan pantas

  var slice = ArrayProto.slice, //

  unshift = ArrayProto.unshift, //

  toString = ObjProto.toString, //

  hasOwnProperty = ObjProto.hasOwnProperty;

 

  // Ini mentakrifkan beberapa kaedah baharu yang disediakan oleh JavaScript 1.6

  // Jika persekitaran hos menyokong kaedah ini, kaedah ini akan dipanggil terlebih dahulu Jika persekitaran hos tidak menyediakannya, ia akan dilaksanakan oleh Underscore.

  var nativeForEach = ArrayProto.forEach, //

  nativeMap = ArrayProto.map, //

  nativeReduce = ArrayProto.reduce, //

  nativeReduceRight = ArrayProto.reduceRight, //

  nativeFilter = ArrayProto.filter, //

  nativeEvery = ArrayProto.every, //

  nativeSome = ArrayProto.some, //

  nativeIndexOf = ArrayProto.indexOf, //

  nativeLastIndexOf = ArrayProto.lastIndexOf, //

  nativeIsArray = Array.isArray, //

  nativeKeys = Object.keys, //

  nativeBind = FuncProto.bind;

 

  // Cipta kaedah panggilan gaya objek, yang akan mengembalikan pembungkus Underscore Prototaip objek pembalut mengandungi semua kaedah Underscore (serupa dengan membungkus objek DOM ke dalam objek jQuery).

  var _ = function(obj) {

    // Semua objek Underscore dibina secara dalaman melalui objek pembalut

    kembalikan pembalut baharu(obj);

  };

  // Untuk persekitaran hos yang berbeza, simpan pembolehubah bernama Undersocre dalam objek berbeza.

  if( typeof exports !== 'undefined') {// Persekitaran Node.js

    if( typeof module !== 'undefined' && module.exports) {

      eksport = modul.eksport = _;

    }

    eksport._ = _;

  } else {//Pembolehubah Underscore yang dinamakan dalam persekitaran penyemak imbas digantung dalam objek tetingkap

    akar ['_'] = _;

  }

 

  // pernyataan versi

  _.VERSION = '1.3.3';

 

  // Kaedah berkaitan koleksi (kaedah pemprosesan am untuk data dan objek)

  //----------------------------------

 

  // Ulang pemproses dan laksanakan kaedah pemproses pada setiap elemen dalam koleksi

  var each = _.each = _.forEach = function(obj, iterator, context) {

    //Jangan kendalikan nilai nol

    if(obj == null)

      kembali;

    if(nativeForEach && obj.forEach === nativeForEach) {

      // Jika persekitaran hos menyokongnya, kaedah forEach yang disediakan oleh JavaScript 1.6 akan dipanggil dahulu.

      obj.forEach(iterator, konteks);

    } else if(obj.length === obj.length) {

      //Laksanakan kaedah pemproses untuk setiap elemen dalam <array>

      untuk(var i = 0, l = obj.panjang; i < l; i ) {

        if( i dalam obj && iterator.call(konteks, obj[i], i, obj) === pemutus)

          kembali;

      }

    } lain {

      // Laksanakan kaedah pemproses untuk setiap elemen dalam <objek>

      untuk(kunci var dalam obj) {

        if(_.has(obj, key)) {

          if(iterator.call(context, obj[key], key, obj) === pemutus)

            kembali;

        }

      }

    }

  };

  // Pemproses lelaran, perbezaan daripada setiap kaedah ialah peta akan menyimpan nilai pulangan setiap lelaran dan mengembalikannya sebagai tatasusunan baharu

  _.map = _.collect = fungsi(obj, iterator, konteks) {

    //Array digunakan untuk menyimpan nilai pulangan

    var keputusan = [];

    if(obj == null)

      pulangan hasil;

    // Utamakan memanggil kaedah peta yang disediakan oleh persekitaran hos

    if(NativeMap && obj.map === nativeMap)

      kembalikan obj.map(iterator, konteks);

    // Lelaran melalui elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      // Simpan nilai pulangan setiap lelaran ke dalam tatasusunan hasil

      keputusan[results.length] = iterator.call(konteks, nilai, indeks, senarai);

    });

    //Kembalikan hasil pemprosesan

    if(obj.length === obj.length)

      hasil.panjang = obj.panjang;

    pulangan hasil;

  };

  // Letakkan setiap elemen dalam koleksi ke dalam pemproses lelaran, dan hantar nilai pulangan lelaran ini sebagai "memo" kepada lelaran seterusnya, biasanya digunakan untuk mengumpul hasil atau menyambung data

  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {

    // Semak sama ada terdapat nilai awal dengan bilangan parameter

    var initial = arguments.length >

    if(obj == null)

      obj = [];

    // Utamakan memanggil kaedah pengurangan yang disediakan oleh persekitaran hos

    if(nativeReduce && obj.reduce === nativeReduce && false) {

      jika(konteks)

        iterator = _.bind(iterator, context);

      kembalikan awal ? obj.reduce(iterator, memo): obj.reduce(iterator);

    }

    // Lelaran melalui elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      if(!initial) {

        // Jika tiada nilai awal, elemen pertama digunakan sebagai nilai awal jika koleksi objek diproses, nilai lalai ialah nilai atribut pertama

        memo = nilai;

        awal = benar;

      } lain {

        // Rekodkan hasil pemprosesan dan hantar hasilnya ke lelaran seterusnya

        memo = iterator.call(konteks, memo, nilai, indeks, senarai);

      }

    });

    jika(!awal)

      buang TypeError baru('Kurangkan tatasusunan kosong tanpa nilai awal');

    pulangkan memo;

  };

  // Sama seperti mengurangkan, ia akan mengulangi elemen dalam koleksi dalam arah terbalik (iaitu, bermula dari elemen terakhir hingga elemen pertama)

  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {

    var initial = arguments.length >

    if(obj == null)

      obj = [];

    // Utamakan memanggil kaedah reduceRight yang disediakan oleh persekitaran hos

    if(nativeReduceRight && obj.reduceRight === nativeReduceRight) {

      jika(konteks)

        iterator = _.bind(iterator, context);

      kembalikan awal ? obj.reduceRight(iterator, memo): obj.reduceRight(iterator);

    }

    //Terbalikkan susunan unsur dalam koleksi

    var terbalik = _.toArray(obj).reverse();

    if(konteks && !initial)

      iterator = _.bind(iterator, context);

    //Proses data melalui kaedah pengurangan

    kembalikan awal ? _.reduce(terbalikkan, iterator, memo, konteks): _.reduce(terbalikkan, iterator);

  };

  // Lintas elemen dalam koleksi dan kembalikan elemen pertama yang boleh lulus pengesahan pemproses

  _.cari = _.detect = fungsi(obj, iterator, konteks) {

    // result menyimpan elemen pertama yang boleh lulus pengesahan

    hasil var;

    // Lintas data melalui sebarang kaedah dan rekod elemen yang lulus pengesahan

    // (Jika anda menyemak status pengembalian pemproses semasa lelaran, adalah lebih sesuai untuk menggunakan setiap kaedah di sini)

    sebarang(obj, fungsi(nilai, indeks, senarai) {

      // Jika hasil yang dikembalikan oleh pemproses ditukar kepada jenis Boolean dan nilainya adalah benar, maka elemen semasa direkodkan dan dikembalikan

      if(iterator.call(konteks, nilai, indeks, senarai)) {

        hasil = nilai;

        kembali benar;

      }

    });

    pulangan hasil;

  };

  // Sama seperti kaedah cari, tetapi kaedah penapis akan merekodkan semua elemen yang disahkan dalam koleksi

  _.filter = _.select = function(obj, iterator, context) {

    // Digunakan untuk menyimpan tatasusunan elemen yang lulus pengesahan

    var keputusan = [];

    if(obj == null)

      pulangan hasil;

    // Beri keutamaan untuk memanggil kaedah penapis yang disediakan oleh persekitaran hos

    if(nativeFilter && obj.filter === nativeFilter)

      kembalikan obj.filter(iterator, konteks);

    // Ulangi elemen dalam koleksi dan letakkan elemen yang disahkan oleh pemproses ke dalam tatasusunan dan kembalikan

    setiap (obj, fungsi (nilai, indeks, senarai) {

      if(iterator.call(konteks, nilai, indeks, senarai))

        keputusan[hasil.panjang] = nilai;

    });

    pulangan hasil;

  };

  // Kesan bertentangan kaedah penapis, iaitu, mengembalikan senarai elemen yang belum lulus pengesahan pemproses

  _.reject = fungsi(obj, iterator, konteks) {

    var keputusan = [];

    if(obj == null)

      pulangan hasil;

    setiap (obj, fungsi (nilai, indeks, senarai) {

      if(!iterator.call(konteks, nilai, indeks, senarai))

        keputusan[hasil.panjang] = nilai;

    });

    pulangan hasil;

  };

  //Jika semua elemen dalam koleksi boleh lulus pengesahan pemproses, kembalikan benar

  _.every = _.all = fungsi(obj, iterator, konteks) {

    var keputusan = benar;

    if(obj == null)

      pulangan hasil;

    // Berikan keutamaan untuk memanggil setiap kaedah yang disediakan oleh persekitaran hos

    if(nativeEvery && obj.every === nativeEvery)

      kembalikan obj.every(iterator, konteks);

    //Lelaran pada elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      // Ini difahami sebagai hasil = (hasil && iterator.call(konteks, nilai, indeks, senarai))

      // Sahkan sama ada hasil pemproses adalah nilai sebenar selepas ditukar kepada jenis Boolean

      if(!( result = result && iterator.call(konteks, nilai, indeks, senarai)))

        pemutus pulangan;

    });

    pulangan !!hasil;

  };

  // Semak sama ada mana-mana elemen dalam koleksi mempunyai nilai sebenar apabila ia ditukar kepada jenis Boolean Atau sama ada ia mempunyai nilai sebenar selepas diproses oleh pemproses?

  var any = _.some = _.any = function(obj, iterator, context) {

    // Jika tiada parameter pemproses dinyatakan, fungsi pemproses lalai akan mengembalikan elemen itu sendiri dan menentukan sama ada ia adalah nilai sebenar dengan menukar elemen kepada jenis Boolean semasa lelaran

    iterator ||. ( iterator = _.identity);

    var keputusan = palsu;

    if(obj == null)

      pulangan hasil;

    // Berikan keutamaan untuk memanggil beberapa kaedah yang disediakan oleh persekitaran hos

    if(nativeSome && obj.some === nativeSome)

      kembalikan obj.some(iterator, konteks);

    //Lelaran pada elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      jika(hasil || ( hasil = iterator.panggilan(konteks, nilai, indeks, senarai)))

        pemutus pulangan;

    });

    pulangan !!hasil;

  };

  // Semak sama ada terdapat nilai dalam koleksi yang betul-betul sepadan dengan parameter sasaran (jenis data juga akan dipadankan)

  _.include = _.contains = function(obj, target) {

    var dijumpai = palsu;

    if(obj == null)

      pulangan ditemui;

    // Utamakan memanggil kaedah Array.prototype.indexOf yang disediakan oleh persekitaran hos

    if(nativeIndexOf && obj.indexOf === nativeIndexOf)

      kembalikan obj.indexOf(sasaran) != -1;

    // Ulangi elemen dalam koleksi melalui sebarang kaedah dan sahkan sama ada nilai dan jenis elemen sepadan sepenuhnya dengan sasaran.

    dijumpai = sebarang(obj, fungsi(nilai) {

      nilai pulangan === sasaran;

    });

    pulangan ditemui;

  };

  // Panggil kaedah yang dinamakan sama untuk semua elemen dalam koleksi dalam urutan, bermula dari parameter ketiga, yang akan dihantar ke kaedah panggilan elemen.

  // Kembalikan tatasusunan yang menyimpan hasil pemprosesan semua kaedah

  _.invoke = fungsi(obj, kaedah) {

    // Parameter diluluskan apabila memanggil kaedah dengan nama yang sama (bermula dari parameter ke-3)

    var args = slice.call(argumen, 2);

    // Panggil kaedah setiap elemen secara bergilir-gilir dan letakkan hasilnya ke dalam tatasusunan dan kembalikannya

    return _.map(obj, function(value) {

      return (_.isFunction(kaedah) ? kaedah || nilai : nilai[kaedah]).apply(nilai, args);

    });

  };

  // Melintasi tatasusunan yang terdiri daripada senarai objek dan kembalikan senarai nilai untuk atribut yang ditentukan dalam setiap objek

  _.pluck = function(obj, key) {

    // Jika harta itu tidak wujud dalam objek, kembalikan tidak ditentukan

    return _.map(obj, function(value) {

      nilai pulangan[kunci];

    });

  };

  //Kembalikan nilai maksimum dalam koleksi, jika tiada nilai setanding, kembalikan tidak ditentukan

  _.maks = fungsi(obj, iterator, konteks) {

    // Jika koleksi ialah tatasusunan dan tiada pemproses digunakan, gunakan Math.max untuk mendapatkan nilai maksimum

    // Secara amnya, satu siri data jenis Nombor disimpan dalam tatasusunan.

    if(!iterator && _.isArray(obj) && obj[0] === obj[0])

      kembalikan Math.max.apply(Math, obj);

    // Untuk nilai nol, kembalikan infiniti negatif secara langsung

    if(!iterator && _.isEmpty(obj))

      kembali -Infiniti;

    // Objek sementara, dikira digunakan untuk menyimpan nilai maksimum semasa proses perbandingan (sementara)

    hasil var = {

      dikira: -Infiniti

    };

    //Lelaran pada elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      // Jika parameter pemproses ditentukan, data yang dibandingkan ialah nilai yang dikembalikan oleh pemproses, jika tidak nilai lalai semasa setiap traversal digunakan secara langsung.

      var dikira = iterator ? iterator.call(konteks, nilai, indeks, senarai): nilai;

      // Jika nilai perbandingan lebih besar daripada nilai sebelumnya, masukkan nilai semasa ke dalam result.value

      dikira >= hasil.dikira && ( hasil = {

        nilai: nilai,

        dikira : dikira

      });

    });

    // Kembalikan nilai maksimum

    pulangan hasil.nilai;

  };

  //Kembalikan nilai minimum dalam set, proses pemprosesan adalah konsisten dengan kaedah maks

  _.min = fungsi(obj, iterator, konteks) {

    if(!iterator && _.isArray(obj) && obj[0] === obj[0])

      kembalikan Math.min.apply(Math, obj);

    if(!iterator && _.isEmpty(obj))

      kembali Infiniti;

    hasil var = {

      dikira: Infiniti

    };

    setiap (obj, fungsi (nilai, indeks, senarai) {

      var dikira = iterator ? iterator.call(konteks, nilai, indeks, senarai): nilai;

      dikira < hasil.dikira && ( hasil = {

        nilai: nilai,

        dikira : dikira

      });

    });

    pulangan hasil.nilai;

  };

  // Gunakan nombor rawak supaya tatasusunan tidak perlu disusun

  _.shuffle = function(obj) {

    // pembolehubah yang dikocok menyimpan proses pemprosesan dan data hasil akhir

    var dikocok = [], rand;

    //Lelaran pada elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks, senarai) {

      // Hasilkan nombor rawak, nombor rawak adalah antara <0-nombor yang sedang diproses>

      rand = Math.floor(Math.random() * (indeks 1));

      // Letakkan elemen yang diperoleh secara rawak di hujung tatasusunan yang dikocok

      dikocok[indeks] = dikocok[rand];

      //Masukkan nilai terkini pada kedudukan nombor rawak yang diperoleh sebelum ini

      dikocok[rand] = nilai;

    });

    // Kembalikan tatasusunan yang menyimpan elemen koleksi yang dikocok secara rawak.

    kembali dikocok;

  };

  // Susun elemen dalam koleksi mengikut medan atau nilai tertentu

  // Berbanding dengan kaedah Array.prototype.sort, kaedah sortBy menyokong pengisihan objek.

  _.sortBy = fungsi(obj, val, konteks) {

    // val harus menjadi sifat objek, atau fungsi pemproses Jika ia adalah pemproses, ia harus mengembalikan data yang perlu dibandingkan.

    var iterator = _.isFunction(val) val : function(obj) {

      kembalikan obj[val];

    };

    // Urutan panggilan: _.pluck(_.map().sort());

    // Panggil kaedah _.map() untuk merentasi koleksi, letakkan elemen dalam koleksi ke dalam nod nilai, dan letakkan data yang perlu dibandingkan dalam elemen ke dalam atribut kriteria

    //Panggil kaedah sort() untuk mengisih elemen dalam koleksi mengikut data dalam atribut kriteria.

    // Panggil pluck untuk mendapatkan koleksi objek yang diisih dan mengembalikannya

    return _.pluck(_.map(obj, function(value, index, list) {

      kembali {

        nilai: nilai,

        kriteria: iterator.call(konteks, nilai, indeks, senarai)

      };

    }).sort(function(kiri, kanan) {

      var a = kiri.kriteria, b = kanan.kriteria;

      jika(a ===

        batal 0)

        pulangan 1;

      jika(b ===

        batal 0)

        pulangan -1;

      kembalikan a < b ?

    }), 'nilai');

  };

  // Bahagikan elemen dalam koleksi kepada berbilang tatasusunan mengikut kekunci yang dikembalikan oleh pemproses

  _.groupBy = function(obj, val) {

    hasil var = {};

    // val akan ditukar kepada fungsi pemproses untuk pengumpulan Jika val bukan data jenis Fungsi, ia akan digunakan sebagai nilai kunci semasa menapis elemen.

    var iterator = _.isFunction(val) val : function(obj) {

      kembalikan obj[val];

    };

    //Lelaran pada elemen dalam koleksi

    setiap (obj, fungsi (nilai, indeks) {

      // Gunakan nilai pulangan pemproses sebagai kunci, dan letakkan elemen kunci yang sama ke dalam tatasusunan baharu

      kunci var = iterator(nilai, indeks);

      (hasil[kunci] || (hasil[kunci] = [])).tolak(nilai);

    });

    // Kembalikan data terkumpul

    pulangan hasil;

  };

  _.sortedIndex = function(array, obj, iterator) {

    iterator ||. ( iterator = _.identity);

    var rendah = 0, tinggi = tatasusunan.panjang;

    manakala(rendah < tinggi) {

      var pertengahan = (rendah tinggi) >>

      iterator(array[mid]) < iterator(obj) ?

    }

    kembali rendah;

  };

  //Tukar koleksi kepada tatasusunan dan kembalikan

  // Biasanya digunakan untuk menukar argumen kepada tatasusunan, atau menukar koleksi objek yang tidak tertib kepada koleksi tersusun dalam bentuk data

  _.toArray = function(obj) {

    jika(!obj)

      kembali [];

    if(_.isArray(obj))

      return slice.call(obj);

    //Tukar argumen kepada tatasusunan

    if(_.isArguments(obj))

      return slice.call(obj);

    if(obj.toArray && _.isFunction(obj.toArray))

      kembalikan obj.toArray();

    //Tukar objek kepada tatasusunan, yang mengandungi senarai nilai semua sifat dalam objek (tidak termasuk sifat dalam rantai prototaip objek)

    return _.values(obj);

  };

  // Kira bilangan elemen dalam koleksi

  _.saiz = fungsi(obj) {

    // Jika koleksi ialah tatasusunan, kira bilangan elemen tatasusunan

    // Jika koleksi ialah objek, kira bilangan sifat dalam objek (tidak termasuk sifat dalam rantai prototaip objek)

    return _.isArray(obj) ? obj.length : _.keys(obj).length;

  };

  // Kaedah berkaitan tatasusunan

  // ---------------

 

  // Kembalikan elemen pertama atau n bagi tatasusunan yang ditentukan mengikut susunan

  _.first = _.head = _.take = function(array, n, guard) {

    // Jika parameter n tidak dinyatakan, kembalikan elemen pertama

    // Jika n ditentukan, kembalikan tatasusunan baharu yang mengandungi bilangan n elemen yang ditentukan dalam urutan

    //Parameter guard digunakan untuk menentukan bahawa hanya elemen pertama dikembalikan Apabila guard adalah benar, nombor n yang ditentukan adalah tidak sah.

    return (n != null) && !guard ? slice.call(array, 0, n): array[0];

  };

  //Kembalikan tatasusunan baharu, yang mengandungi elemen lain kecuali elemen pertama, atau tidak termasuk n elemen yang ditentukan ke hadapan bermula daripada elemen terakhir

  // Perbezaan daripada kaedah pertama ialah yang pertama menentukan kedudukan elemen yang diperlukan sebelum tatasusunan, dan permulaan menentukan kedudukan elemen yang dikecualikan pada penghujung tatasusunan.

  _.initial = function(array, n, guard) {

    // Jika parameter n tidak diluluskan, elemen lain kecuali elemen terakhir akan dikembalikan secara lalai

    // Jika parameter n diluluskan, elemen lain kecuali n elemen ke hadapan bermula dari elemen terakhir dikembalikan.

    // guard digunakan untuk memastikan bahawa hanya satu elemen dikembalikan Apabila guard adalah benar, nombor n yang dinyatakan adalah tidak sah.

    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));

  };

  //Kembalikan n elemen terakhir tatasusunan atau n elemen yang ditentukan dalam susunan terbalik

  _.last = function(array, n, guard) {

    if((n != null) && !guard) {

      // Kira dan nyatakan kedudukan elemen yang diperoleh n, sehingga penghujung tatasusunan, dan kembalikannya sebagai tatasusunan baharu

      return slice.call(array, Math.max(array.length - n, 0));

    } lain {

      // Jika nombor tidak dinyatakan, atau guard adalah benar, hanya elemen terakhir dikembalikan

      kembali tatasusunan[array.length - 1];

    }

  };

  // Dapatkan elemen lain kecuali elemen pertama atau n elemen pertama yang ditentukan

  _.rest = _.tail = function(array, index, guard) {

    // Kira parameter kedudukan kedua bagi kepingan sehingga penghujung tatasusunan

    // Jika indeks tidak dinyatakan, atau nilai pengawal adalah benar, kembalikan elemen lain kecuali elemen pertama.

    // Apabila nilai (index == null) adalah benar, parameter yang dihantar ke fungsi slice akan ditukar secara automatik kepada 1

    return slice.call(array, (index == null) || guard ? 1 : index);

  };

  // Kembalikan semua elemen dalam tatasusunan yang nilainya boleh ditukar kepada benar, dan kembalikan tatasusunan baharu

  // Nilai yang tidak boleh ditukar termasuk palsu, 0, '', null, undefined, NaN, nilai ini akan ditukar kepada palsu

  _.compact = function(array) {

    return _.filter(array, function(value) {

      pulangan !!nilai;

    });

  };

  // Gabungkan nombor berbilang dimensi ke dalam tatasusunan satu dimensi, menyokong penggabungan dalam

  // Parameter cetek digunakan untuk mengawal kedalaman penggabungan Apabila cetek adalah benar, hanya lapisan pertama digabungkan, dan penggabungan dalam dilakukan secara lalai.

  _.ratakan = fungsi(susunan, cetek) {

    // Lelaran ke atas setiap elemen dalam tatasusunan dan hantar nilai pulangan sebagai demo kepada lelaran seterusnya

    return _.reduce(array, function(memo, value) {

      // Jika elemen masih dalam tatasusunan, buat pertimbangan berikut:

      // - Jika penggabungan dalam tidak dilakukan, gunakan Array.prototype.concat untuk menyambung tatasusunan semasa dan data sebelumnya.

      // - Jika penggabungan dalam disokong, kaedah ratakan dipanggil secara berulang sehingga elemen asas bukan lagi jenis tatasusunan

      if(_.isArray(value))

        return memo.concat( shallow ? value : _.flatten(value));

      // Data (nilai) sudah berada di bahagian bawah dan bukan lagi jenis tatasusunan, kemudian gabungkan data ke dalam memo dan kembalikan

      memo[memo.length] = nilai;

      pulangkan memo;

    }, []);

  };

  // Tapis dan kembalikan data perbezaan dalam tatasusunan semasa yang tidak sama dengan data yang ditentukan (sila rujuk ulasan kaedah perbezaan)

  _.tanpa = function(array) {

    return _.difference(array, slice.call(arguments, 1));

  };

  // Nyahduplikasi data dalam tatasusunan (gunakan === untuk perbandingan)

  // Apabila parameter isSorted tidak palsu, kaedah sertakan akan dipanggil pada elemen dalam tatasusunan dalam urutan untuk memeriksa sama ada elemen yang sama telah ditambahkan pada nilai pulangan (tatasusunan)

  // Jika anda memastikan data dalam tatasusunan disusun mengikut urutan sebelum memanggil, anda boleh menetapkan isSorted kepada benar Ia akan mengecualikan nilai yang sama dengan membandingkannya dengan elemen terakhir Menggunakan isSorted akan menjadi lebih cekap daripada kaedah termasuk lalai .

  // Kaedah uniq akan membandingkan data dalam tatasusunan secara lalai Jika pemproses iterator diisytiharkan, tatasusunan perbandingan akan dibuat berdasarkan pemproses Data dalam tatasusunan akan digunakan semasa perbandingan, tetapi satu-satunya data yang dikembalikan dalam end masih array asal

  _.uniq = _.unique = function(array, isSorted, iterator) {

    // Jika pemproses iterator digunakan, data dalam tatasusunan semasa akan diproses oleh iterator terlebih dahulu dan tatasusunan baru yang diproses akan dikembalikan.

    // Tatasusunan baru digunakan sebagai asas untuk perbandingan

    var initial = iterator ? _.map(array, iterator): tatasusunan;

    // Tatasusunan sementara digunakan untuk merekodkan hasil pemprosesan

    var keputusan = [];

    // Jika terdapat hanya 2 nilai dalam tatasusunan, tidak perlu menggunakan kaedah sertakan untuk perbandingan.

    if(array.length < 3)

      isSorted = benar;

    // Gunakan kaedah pengurangan untuk mengulang dan mengumpul hasil pemprosesan

    //Pembolehubah awal ialah data asas yang perlu dibandingkan. Ia mungkin tatasusunan asal atau set hasil pemproses (jika iterator ditetapkan)

    _.kurangkan(awal, fungsi(memo, nilai, indeks) {

      // Jika parameter isSorted adalah benar, gunakan terus === untuk membandingkan data terakhir dalam rekod

      // Jika parameter isSorted adalah palsu, gunakan kaedah sertakan untuk membandingkan dengan setiap data dalam koleksi

      if( isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {

        //memo merekodkan data bukan pendua yang telah dibandingkan

        // Bergantung pada status parameter iterator, data yang direkodkan dalam memo mungkin data asal atau data yang diproses oleh pemproses

        memo.push(nilai);

        // Data yang disimpan dalam tatasusunan hasil pemprosesan sentiasa data dalam tatasusunan asal

        results.push(array[index]);

      }

      pulangkan memo;

    }, []);

    //Kembalikan hasil pemprosesan, yang hanya mengandungi data bukan pendua dalam tatasusunan

    pulangan hasil;

  };

  // Kaedah kesatuan mempunyai kesan yang sama seperti kaedah uniq Perbezaannya ialah kesatuan membenarkan berbilang tatasusunan dihantar sebagai parameter.

  _.union = function() {

    // kesatuan menggabungkan berbilang tatasusunan dalam parameter ke dalam objek tatasusunan dan menyerahkannya kepada kaedah uniq untuk diproses

    return _.uniq(_.flatten(arguments, true));

  };

  // Dapatkan elemen persilangan tatasusunan semasa dan satu atau lebih tatasusunan lain

  //Bermula dari parameter kedua ialah satu atau lebih tatasusunan yang perlu dibandingkan

  _.simpang = _.simpang = fungsi(susun) {

    // Pembolehubah selebihnya merekodkan objek tatasusunan lain yang perlu dibandingkan.

    var rest = slice.call(argumen, 1);

    // Gunakan kaedah uniq untuk mengalih keluar data pendua dalam tatasusunan semasa untuk mengelakkan pengiraan berulang

    // Tapis data tatasusunan semasa melalui pemproses dan kembalikan data yang memenuhi syarat (membandingkan elemen yang sama)

    return _.filter(_.uniq(array), function(item) {

      // Gunakan setiap kaedah untuk mengesahkan bahawa setiap tatasusunan mengandungi data yang perlu dibandingkan.

      // Jika semua tatasusunan mengandungi data perbandingan, maka semua kembali benar, jika mana-mana tatasusunan tidak mengandungi elemen, maka kembalikan palsu

      pulangkan _.setiap(rehat, fungsi(lain) {

        // Parameter lain menyimpan setiap tatasusunan yang perlu dibandingkan

        // item menyimpan data yang perlu dibandingkan dalam tatasusunan semasa

        // Gunakan kaedah indexOf untuk mencari sama ada elemen itu wujud dalam tatasusunan (sila rujuk ulasan kaedah indexOf)

        return _.indexOf(other, item) >= 0;

      });

    });

  };

  // Tapis dan kembalikan data perbezaan dalam tatasusunan semasa yang tidak sama dengan data yang ditentukan

  // Fungsi ini biasanya digunakan untuk memadam data yang ditentukan dalam tatasusunan dan mendapatkan tatasusunan baharu selepas pemadaman

  // Fungsi kaedah ini bersamaan dengan tanpa Parameter kaedah tanpa tidak membenarkan data dimasukkan dalam tatasusunan, manakala parameter kaedah perbezaan disyorkan untuk menjadi tatasusunan (anda juga boleh menggunakan parameter yang sama seperti tanpa).

  _.perbezaan = fungsi(tatasusunan) {

    // Gabungkan semua parameter bermula dari parameter kedua sebagai tatasusunan (hanya gabungkan tahap pertama, bukan cantum dalam)

    // Pembolehubah selebihnya menyimpan data pengesahan, yang digunakan dalam kaedah ini untuk membandingkan dengan data asal.

    var rest = _.flatten(slice.call(arguments, 1), true);

    // Tapis data tatasusunan yang digabungkan Syarat penapis ialah tatasusunan semasa tidak mengandungi data pengesahan yang ditentukan oleh parameter.

    // Gabungkan data yang memenuhi syarat penapis ke dalam tatasusunan baharu dan kembalikannya

    return _.filter(array, function(value) {

      return !_.include(rehat, nilai);

    });

  };

  //Kembalikan data pada kedudukan yang sama bagi setiap tatasusunan sebagai tatasusunan dua dimensi yang baru Panjang tatasusunan yang dikembalikan adalah berdasarkan panjang tatasusunan maksimum dalam parameter yang dilalui.

  // Kaedah zip hendaklah mengandungi berbilang parameter, dan setiap parameter hendaklah berupa tatasusunan

  _.zip = function() {

    //Tukar parameter kepada tatasusunan, pada masa ini args ialah tatasusunan dua dimensi

    var args = slice.call(argumen);

    // Kira panjang setiap tatasusunan dan kembalikan nilai panjang maksimum

    var length = _.max(_.pluck(args, 'length'));

    //Buat tatasusunan kosong baharu mengikut nilai panjang maksimum, yang digunakan untuk menyimpan hasil pemprosesan

    var keputusan = new Array(panjang);

    //Panjang maksimum gelung, dalam setiap gelung kaedah pluck akan dipanggil untuk mendapatkan data pada kedudukan yang sama dalam setiap tatasusunan (dari 0 hingga kedudukan terakhir dalam urutan)

    // Simpan data yang diperoleh dalam tatasusunan baharu, masukkan ke dalam hasil dan kembalikan

    untuk(var i = 0; i < panjang; i )

    keputusan[i] = _.pluck(args, "" i);

    //Hasil yang dikembalikan ialah tatasusunan dua dimensi

    pulangan hasil;

  };

  // Cari kejadian pertama elemen dalam tatasusunan, dan kembalikan -1 jika elemen itu tidak wujud

  // Gunakan === untuk memadankan elemen semasa mencari

  _.indexOf = function(array, item, isSorted) {

    if(array == null)

      pulangan -1;

    var i, l;

    if(isSorted) {

      i = _.sortedIndex(array, item);

      kembalikan tatasusunan[i] === item i : -1;

    }

    // Utamakan memanggil kaedah indexOf yang disediakan oleh persekitaran hos

    if(nativeIndexOf && array.indexOf === nativeIndexOf)

      kembalikan array.indexOf(item);

    // Gelung dan kembalikan kejadian pertama elemen

    untuk( i = 0, l = array.length; i < l; i )

    if( i dalam array && array[i] === item)

      kembali i;

    // Tiada elemen ditemui, mengembalikan -1

    pulangan -1;

  };

  //Mengembalikan kedudukan kejadian terakhir elemen dalam tatasusunan, atau -1 jika elemen itu tidak wujud

  // Gunakan === untuk memadankan elemen semasa mencari

  _.lastIndexOf = function(array, item) {

    if(array == null)

      pulangan -1;

    // Utamakan memanggil kaedah lastIndexOf yang disediakan oleh persekitaran hos

    if(nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf)

      kembalikan array.lastIndexOf(item);

    var i = array.length;

    // Gelung dan kembalikan kejadian terakhir elemen

    manakala (i--)

    if( i dalam array && array[i] === item)

      kembali i;

    // Tiada elemen ditemui, mengembalikan -1

    pulangan -1;

  };

  // Berdasarkan selang dan saiz langkah, hasilkan satu siri integer dan kembalikannya sebagai tatasusunan

  // Parameter permulaan mewakili nombor minimum

  // Parameter berhenti menunjukkan bilangan maksimum

  //Parameter langkah mewakili nilai langkah antara penjanaan berbilang nilai.

  _.julat = fungsi(mula, berhenti, langkah) {

    // Kawalan parameter

    if(arguments.length <= 1) {

      // Jika tiada parameter, mula = 0, berhenti = 0, tiada data akan dijana dalam gelung, dan tatasusunan kosong akan dikembalikan.

      // Jika terdapat 1 parameter, parameter ditetapkan untuk berhenti, mula = 0

      berhenti = mula ||.

      mula = 0;

    }// Hasilkan nilai langkah bagi integer, lalai ialah 1

    langkah = hujah[2] ||.

 

    // Kira nilai maksimum yang akan dijana berdasarkan selang dan saiz langkah

    var len = Math.max(Math.ceil((berhenti - mula) / langkah), 0);

    varidx = 0;

    julat var = Array(len);

 

    // Hasilkan senarai integer dan simpannya dalam tatasusunan julat

    while(idx < len) {

      julat[idx] = mula;

      mula = langkah;

    }

 

    //Kembalikan hasil senarai

    julat pulangan;

  };

  //Kaedah berkaitan fungsi

  // -------------------

 

  //Buat objek fungsi awam untuk menetapkan prototaip

  var ctor = function() {

  };

  //Ikat konteks pelaksanaan untuk fungsi Setiap kali fungsi dipanggil, ini dalam fungsi menunjuk ke objek konteks.

  // Apabila mengikat fungsi, anda boleh menghantar parameter panggilan ke fungsi pada masa yang sama

  _.bind = function bind(func, context) {

    var terikat, args;

    // Utamakan memanggil kaedah bind yang disediakan oleh persekitaran hos

    if(func.bind === nativeBind && nativeBind)

      kembalikan nativeBind.apply(func, slice.call(arguments, 1));

    // Parameter func mestilah jenis fungsi

    jika(!_.isFunction(func))

      buang TypeError baharu;

    // Pembolehubah args menyimpan senarai parameter ketiga bermula dari kaedah bind, yang akan dihantar ke fungsi func setiap kali ia dipanggil.

    args = slice.call(argumen, 2);

    kembali terikat = function() {

      jika(!(contoh ini terikat))

        kembalikan func.apply(konteks, sargs.concat(slice.call(argumen)));

      ctor.prototype = func.prototype;

      var diri = ctor baharu;

      var result = func.apply(self, args.concat(slice.call(arguments)));

      jika(Objek(hasil) === hasil)

        pulangan hasil;

      pulangkan diri;

    };

  };

  // Ikat fungsi yang ditentukan, atau semua fungsi objek itu sendiri, kepada objek itu sendiri Apabila fungsi terikat dipanggil, objek konteks sentiasa menunjuk ke objek itu sendiri.

  // Kaedah ini biasanya digunakan semasa mengendalikan peristiwa objek, contohnya:

  // _(obj).bindAll(); // atau _(obj).bindAll('handlerClick');

  // document.addEventListener('klik', obj.handlerClick);

  // Dalam kaedah handlerClick, konteks masih menjadi objek obj

  _.bindAll = function(obj) {

    //Parameter kedua mula menunjukkan nama fungsi yang perlu diikat

    var funcs = slice.call(argumen, 1);

    // Jika tiada nama fungsi tertentu dinyatakan, semua sifat jenis Fungsi terikat pada objek itu sendiri secara lalai.

    if(fungsi. panjang == 0)

      funcs = _.functions(obj);

    // Gelung dan tetapkan semua konteks fungsi kepada objek obj itu sendiri

    //Setiap kaedah itu sendiri tidak merentasi kaedah dalam rantai prototaip objek, tetapi senarai fungsi di sini diperoleh melalui kaedah _.functions, yang sudah mengandungi kaedah dalam rantai prototaip

    setiap(fungsi, fungsi(f) {

      obj[f] = _.bind(obj[f], obj);

    });

    kembali obj;

  };

  // Kaedah memoize akan mengembalikan fungsi, yang menyepadukan fungsi caching, menyimpan nilai yang dikira ke dalam pembolehubah tempatan dan mengembalikannya terus apabila ia dipanggil seterusnya.

  // Jika hasil pengiraan adalah objek atau data yang besar, penggunaan memori harus dipertimbangkan semasa menggunakannya.

  _.memoize = function(func, hasher) {

    //memo objek yang digunakan untuk menyimpan hasil cache

    var memo = {};

    // Parameter penggodam mestilah fungsi, yang digunakan untuk mengembalikan kunci, yang digunakan sebagai pengecam untuk membaca cache

    // Jika kunci tidak dinyatakan, parameter pertama fungsi digunakan sebagai kunci secara lalai Jika parameter pertama fungsi adalah jenis data komposit, kunci yang serupa dengan [objek objek] boleh dikembalikan boleh menyebabkan ralat pengiraan seterusnya Data tidak betul

    pencincang ||. ( pencincang = _.identiti);

    // Kembalikan fungsi yang mula-mula menyemak cache dan kemudian memanggil data yang belum dicache

    kembalikan fungsi() {

      var key = hasher.apply(this, arguments);

      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));

    };

  };

  // Menangguhkan pelaksanaan fungsi

  // Unit tunggu ialah ms, dan parameter ketiga akan dihantar ke fungsi pelaksanaan mengikut turutan.

  _.delay = function(func, wait) {

    var args = slice.call(argumen, 2);

    kembalikan setTimeout(function() {

      kembalikan func.apply(null, args);

    }, tunggu);

  };

  // Tangguhkan fungsi pelaksanaan

  // setTimeout dalam JavaScript akan dilaksanakan dalam tindanan fungsi yang berasingan Masa pelaksanaan adalah selepas semua fungsi yang dipanggil dalam tindanan semasa telah dilaksanakan.

  // defer menetapkan fungsi yang akan dilaksanakan selepas 1ms Tujuannya adalah untuk meletakkan fungsi func ke dalam tindanan berasingan dan menunggu fungsi semasa selesai sebelum melaksanakannya.

  // Kaedah penangguhan biasanya digunakan untuk mengendalikan keutamaan operasi DOM untuk mencapai aliran logik yang betul dan pengalaman interaktif yang lebih lancar.

  _.defer = function(func) {

    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));

  };

  // Kaedah pendikit fungsi Kaedah pendikit digunakan terutamanya untuk mengawal kekerapan pelaksanaan fungsi Dalam selang masa terkawal, fungsi yang sering dipanggil tidak akan dilaksanakan beberapa kali.

  // Jika fungsi dipanggil beberapa kali dalam selang masa, ia akan dipanggil secara automatik sekali apabila selang masa tamat. Tidak perlu menunggu sehingga masa tamat sebelum memanggilnya secara manual (tidak akan ada nilai pulangan apabila dipanggil secara automatik. )

  // Fungsi pendikit biasanya digunakan untuk mengendalikan fungsi yang kompleks dan sering dipanggil Ia mengawal kekerapan panggilan fungsi dengan mendikit dan menjimatkan sumber pemprosesan.

  // Contohnya, fungsi acara terikat kepada window.onresize atau fungsi acara terikat kepada element.onmousemove boleh dibungkus dengan pendikit.

  //Kaedah pendikit mengembalikan fungsi, yang secara automatik memanggil func dan melaksanakan kawalan pendikit

  _.throttle = fungsi(func, wait) {

    var context, args, timeout, throttling, more, result;

    // Pembolehubah whenDone memanggil kaedah nyahlantun, jadi apabila fungsi dipanggil beberapa kali, panggilan terakhir akan menimpa pemasa yang dipanggil sebelum ini, dan fungsi status yang jelas hanya akan dilaksanakan sekali

    //Fungsi whenDone dipanggil apabila selang masa pelaksanaan fungsi terakhir tamat, mengosongkan pendikit dan beberapa keadaan yang direkodkan semasa proses panggilan

    var apabilaSelesai = _.debounce(function() {

      lebih = pendikit = palsu;

    }, tunggu);

    // Kembalikan fungsi dan lakukan kawalan pendikit dalam fungsi

    kembalikan fungsi() {

      //Simpan konteks pelaksanaan dan parameter fungsi

      konteks = ini;

      args = hujah;

      //Fungsi kemudian dilaksanakan apabila selang masa panggilan fungsi terakhir tamat

      var kemudian = function() {

        // Kosongkan pemegang tamat masa untuk memudahkan panggilan fungsi seterusnya

        tamat masa = null;

        // lebih banyak rekod sama ada fungsi dipanggil berulang kali antara panggilan terakhir dan tamat tempoh selang masa

        // Jika fungsi dipanggil berulang kali, fungsi akan dipanggil semula secara automatik apabila selang masa tamat.

        jika (lebih)

          func.apply(context, args);

        // Panggil apabila Selesai, digunakan untuk mengosongkan keadaan pendikit selepas selang masa

        apabilaSelesai();

      };

      // tamat masa merekodkan pemegang selang masa bagi pelaksanaan fungsi terakhir

      // Panggil fungsi kemudian apabila selang masa tamat masa tamat akan dikosongkan kemudian dan semak sama ada fungsi itu perlu dipanggil semula.

      jika(! tamat masa)

        tamat masa = setMasa tamat(nanti, tunggu);

      // Pembolehubah pendikit merekodkan sama ada selang masa panggilan terakhir telah tamat, iaitu, sama ada dalam proses pendikit

      // pendikit ditetapkan kepada benar setiap kali fungsi dipanggil, menunjukkan keperluan untuk pendikit, dan ditetapkan kepada palsu apabila selang masa tamat (dilaksanakan dalam fungsi whenDone)

      if(throttling) {

        // Berbilang panggilan dibuat semasa proses pendikit, dan status direkodkan dalam lebih banyak lagi, menunjukkan bahawa fungsi itu perlu dipanggil semula secara automatik apabila selang masa tamat.

        lebih = benar;

      } lain {

        // Ia tidak dalam proses pendikit Ini mungkin kali pertama untuk memanggil fungsi, atau selang panggilan terakhir telah melebihi Anda boleh memanggil fungsi secara langsung.

        result = func.apply(context, args);

      }

      // Panggil apabila Selesai, digunakan untuk mengosongkan keadaan pendikit selepas selang masa

      apabilaSelesai();

      // Pembolehubah pendikit merekodkan status pendikit apabila fungsi dipanggil.

      pendikit = benar;

      //Kembalikan hasil panggilan

      pulangan hasil;

    };

  };

  // Kaedah nyahlantun adalah serupa dengan kaedah pendikit, digunakan untuk pendikitan fungsi Perbezaan antaranya ialah:

  // -- throttle memfokuskan pada kekerapan pelaksanaan fungsi Fungsi hanya akan dilaksanakan sekali dalam frekuensi yang ditetapkan;

  // -- Fungsi nyahlantun memberi lebih perhatian kepada selang antara pelaksanaan fungsi, iaitu, masa antara dua panggilan fungsi tidak boleh kurang daripada masa yang ditentukan;

  // Jika selang pelaksanaan antara dua fungsi kurang daripada menunggu, pemasa akan dikosongkan dan dicipta semula, yang bermaksud bahawa jika fungsi dipanggil secara berterusan dan kerap, fungsi itu tidak akan dilaksanakan sehingga masa antara panggilan tertentu dan panggilan sebelumnya tidak kurang daripada menunggu

  // Fungsi nyahlantun biasanya digunakan untuk mengawal operasi yang mengambil tempoh masa untuk dilaksanakan Contohnya, untuk menggesa pengguna 200ms selepas pengguna melengkapkan input, anda boleh menggunakan nyahlantun untuk membungkus fungsi dan mengikatnya pada acara onkeyup. .

  //------------------------------------------------ ----------------

  // @param {Function} func mewakili fungsi yang dilaksanakan

  // @param {Number} tunggu mewakili selang masa yang dibenarkan Panggilan berulang dalam julat masa ini akan ditangguhkan semula oleh milisaat menunggu.

  // @param {Boolean}serta-merta menunjukkan sama ada fungsi akan dilaksanakan serta-merta selepas ia dipanggil, benar bermakna ia akan dipanggil serta-merta, palsu bermakna ia akan dipanggil apabila masa tamat.

  // Kaedah nyahlantun mengembalikan fungsi, yang secara automatik memanggil func dan melaksanakan kawalan pendikit

  _.debounce = function(func, wait, immediate) {

    // tamat masa digunakan untuk merekod status pelaksanaan panggilan fungsi terakhir (pemegang pemasa)

    // Apabila tamat masa adalah batal, ini bermakna panggilan terakhir telah ditamatkan

    tamat masa var;

    // Kembalikan fungsi dan lakukan kawalan pendikit dalam fungsi

    kembalikan fungsi() {

      // Simpan objek konteks dan parameter fungsi

      konteks var = ini, args = hujah;

      var kemudian = function() {

        //Tetapkan tamat masa kepada null

        // Fungsi kemudian akan dipanggil apabila masa yang dibenarkan tamat

        // Apabila memanggil fungsi ini, ia menunjukkan bahawa masa pelaksanaan fungsi terakhir telah melebihi selang masa yang dipersetujui, dan panggilan berikutnya selepas masa ini dibenarkan.

        tamat masa = null;

        jika(!segera)

          func.apply(context, args);

      };

      // Jika fungsi ditetapkan untuk melaksanakan serta-merta dan selang masa panggilan terakhir telah berlalu, panggil fungsi dengan segera

      jika(segera && !tamat masa)

        func.apply(context, args);

      //Buat pemasa untuk menyemak dan menetapkan status panggilan fungsi

      // Sebelum mencipta pemasa, kosongkan pemegang setTimeout terakhir, tidak kira sama ada fungsi terikat terakhir telah dilaksanakan.

      // Jika apabila fungsi ini dipanggil, pelaksanaan fungsi sebelumnya belum bermula (biasanya apabila segera ditetapkan kepada palsu), masa pelaksanaan fungsi akan ditangguhkan, jadi pemegang tamat masa akan dicipta semula

      clearTimeout(masa tamat);

      // Panggil fungsi kemudian apabila masa yang dibenarkan tamat

      tamat masa = setMasa tamat(nanti, tunggu);

    };

  };

  // Cipta fungsi yang hanya akan dilaksanakan sekali Jika fungsi dipanggil berulang kali, hasil pelaksanaan pertama akan dikembalikan.

  // Fungsi ini digunakan untuk mendapatkan dan mengira logik data tetap, seperti mendapatkan jenis pelayar yang digunakan oleh pengguna

  _.sekali = function(func) {

    // menjalankan rekod sama ada fungsi telah dilaksanakan

    //memo merekodkan hasil pelaksanaan terakhir fungsi

    var ran = palsu, memo;

    kembalikan fungsi() {

      // Jika fungsi telah dilaksanakan sebelum ini, kembalikan terus hasil pelaksanaan pertama

      jika(berlari)

        pulangkan memo;

      berlari = benar;

      kembalikan memo = func.apply(this, arguments);

    };

  };

  // Mengembalikan fungsi yang menghantar fungsi semasa sebagai parameter kepada fungsi pembalut

  // Dalam fungsi yang dibalut, anda boleh memanggil fungsi semasa melalui parameter pertama dan mengembalikan hasilnya

  // Biasanya digunakan untuk panggilan gabungan gandingan rendah bagi pelbagai fungsi pemprosesan proses

  _.wrap = function(func, wrapper) {

    kembalikan fungsi() {

      // Lulus fungsi semasa sebagai parameter pertama kepada fungsi pembalut

      var args = [func].concat(slice.call(arguments, 0));

      // Kembalikan hasil pemprosesan fungsi pembalut

      return wrapper.apply(this, args);

    };

  };

  // Gabungkan berbilang fungsi bersama-sama Mengikut susunan lulus parameter, nilai pulangan fungsi terakhir akan dihantar sebagai parameter kepada fungsi sebelumnya sebagai parameter untuk meneruskan pemprosesan.

  // _.compose(A, B, C adalah bersamaan dengan A(B(C()));

  // Kelemahan kaedah ini ialah bilangan parameter yang diproses oleh fungsi yang berkaitan hanya boleh menjadi satu Jika berbilang parameter perlu diluluskan, ia boleh dipasang melalui jenis data komposit Array atau Objek.

  _.karang = function() {

    // Dapatkan senarai fungsi, semua parameter mestilah jenis Fungsi

    var funcs = hujah;

    //Kembalikan pemegang fungsi untuk memanggil

    kembalikan fungsi() {

      // Laksanakan fungsi dalam urutan dari belakang ke hadapan, dan hantar nilai pulangan yang direkodkan sebagai parameter kepada fungsi sebelumnya untuk meneruskan pemprosesan.

      var args = hujah;

      for(var i = funcs.length - 1; i >= 0; i--) {

        args = [funcs[i].apply(this, args)];

      }

      //Kembalikan nilai pulangan bagi panggilan fungsi terakhir

      kembalikan args[0];

    };

  };

  // Kembalikan fungsi yang berfungsi sebagai pembilang panggilan Apabila fungsi dipanggil kali masa (atau melebihi masa kali), fungsi fungsi akan dilaksanakan.

  // Kaedah selepas biasanya digunakan sebagai pembilang tak segerak Contohnya, jika anda perlu melaksanakan fungsi selepas berbilang permintaan AJAX selesai, anda boleh menggunakan selepas untuk memanggilnya selepas setiap permintaan AJAX selesai.

  _.after = function(times, func) {

    // Jika tiada atau masa tidak sah dinyatakan, func dipanggil terus

    jika(kali <= 0)

      kembalikan fungsi();

    // Kembalikan fungsi pembilang

    kembalikan fungsi() {

      // Setiap kali masa fungsi pembilang dipanggil, kurangkan ia sebanyak 1. Selepas masa masa panggilan, laksanakan fungsi fungsi dan kembalikan nilai pulangan fungsi fungsi.

      jika(--kali < 1) {

        kembalikan func.apply(this, arguments);

      }

    };

  };

  // Kaedah berkaitan objek

  //----------------

 

  // Dapatkan senarai nama atribut objek (tidak termasuk atribut dalam rantai prototaip)

  _.keys = nativeKeys ||

  fungsi(obj) {

    if(obj !== Objek(obj))

      buang TypeError baru('Objek tidak sah');

    kekunci var = [];

    //Rekod dan kembalikan semua nama harta objek

    untuk(kunci var dalam obj)

    if(_.has(obj, key))

      kekunci[keys.length] = kunci;

    kembali kunci;

  };

 

  // Kembalikan senarai nilai semua sifat dalam objek (tidak termasuk sifat dalam rantai prototaip)

  _.values ​​= function(obj) {

    return _.map(obj, _.identity);

  };

  // Dapatkan senarai kunci semua nilai harta dalam objek yang jenis Fungsi, dan isikannya mengikut nama kunci (termasuk sifat dalam rantai prototaip)

  _.fungsi = _.kaedah = fungsi(obj) {

    nama var = [];

    untuk(kunci var dalam obj) {

      if(_.isFunction(obj[key]))

        names.push(key);

    }

    kembalikan nama.sort();

  };

  // Salin sifat satu atau lebih objek (termasuk sifat dalam rantai prototaip) ke objek obj, dan tulis ganti jika terdapat sifat dengan nama yang sama.

  _.extend = fungsi(obj) {

    // Satu atau lebih objek dalam setiap parameter gelung

    setiap (slice.call(argumen, 1), fungsi(sumber) {

      //Salin atau tulis ganti semua sifat dalam objek ke objek obj

      for(var prop dalam sumber) {

        obj[prop] = sumber[prop];

      }

    });

    kembali obj;

  };

  // Kembalikan objek baharu dan salin sifat yang ditentukan dari obj ke objek baharu

  //Parameter kedua bermula dengan nama atribut yang ditentukan yang perlu disalin (menyokong berbilang parameter dan tatasusunan dalam)

  _.pick = function(obj) {

    //Buat objek untuk menyimpan atribut yang ditentukan yang disalin

    hasil var = {};

    // Bermula dari parameter kedua, gabungkannya ke dalam tatasusunan untuk menyimpan senarai nama atribut.

    each(_.flatten(slice.call(arguments, 1)), function(key) {

      // Gelung senarai nama atribut Jika atribut wujud dalam obj, salin ke objek hasil.

      jika (masukkan obj)

        result[key] = obj[key];

    });

    //Kembalikan hasil yang disalin

    pulangan hasil;

  };

  // Salin atribut yang tidak wujud dalam obj atau mempunyai nilai false selepas penukaran kepada jenis Boolean daripada satu atau lebih objek yang dinyatakan dalam parameter kepada obj

  // Biasanya digunakan untuk menetapkan nilai lalai kepada objek

  _.defaults = function(obj) {

    // Pelbagai objek boleh ditentukan bermula dari parameter kedua, dan sifat dalam objek ini akan disalin ke objek obj secara bergilir-gilir (jika harta itu tidak wujud dalam objek obj)

    setiap (slice.call(argumen, 1), fungsi(sumber) {

      // Lelaran melalui semua sifat dalam setiap objek

      for(var prop dalam sumber) {

        // Jika ia tidak wujud dalam obj atau nilai atribut adalah palsu selepas ditukar kepada jenis Boolean, salin atribut ke obj

        if(obj[prop] == null)

          obj[prop] = sumber[prop];

      }

    });

    kembali obj;

  };

  //Buat salinan obj dan kembalikan objek baharu yang mengandungi status semua sifat dan nilai dalam obj

  // Fungsi klon tidak menyokong penyalinan dalam Contohnya, jika harta dalam obj menyimpan objek, objek tidak akan disalin.

  // Jika obj ialah tatasusunan, objek tatasusunan yang sama akan dibuat

  _.klon = fungsi(obj) {

    //Tidak menyokong data bukan tatasusunan dan jenis objek

    jika(!_.isObject(obj))

      kembali obj;

    //Salin dan kembalikan tatasusunan atau objek

    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);

  };

  // Laksanakan fungsi dan hantar obj sebagai parameter kepada fungsi Selepas fungsi dilaksanakan, objek obj akhirnya dikembalikan.

  // Secara amnya, kaedah ketik digunakan semasa membuat rantai kaedah, contohnya:

  // _(obj).chain().tap(click).tap(mouseover).tap(mouseout);

  _.tap = fungsi(obj, pemintas) {

    pemintas(obj);

    kembali obj;

  };

  // Fungsi eq hanya dipanggil dalam kaedah isEqual dan digunakan untuk membandingkan sama ada nilai dua data adalah sama.

  //Perbezaan daripada === ialah eq memberi lebih perhatian kepada nilai data

  // Jika perbandingan adalah antara dua jenis data komposit, ia bukan sahaja akan membandingkan sama ada ia datang dari rujukan yang sama, tetapi juga melakukan perbandingan yang mendalam (membandingkan struktur dan data kedua-dua objek)

  fungsi eq(a, b, tindanan) {

    // Semak sama ada nilai dua jenis data mudah adalah sama

    // Untuk jenis data komposit, ia dianggap sama jika ia datang daripada rujukan yang sama

    // Jika nilai yang dibandingkan mengandungi 0, semak sama ada nilai lain ialah -0, kerana 0 === -0 adalah benar

    // Dan 1 / 0 == 1 / -0 tidak benar (nilai 1 / 0 ialah Infiniti, nilai 1 / -0 ialah -Infiniti dan Infiniti tidak sama dengan -Infiniti)

    jika(a === b)

      kembalikan a !== 0 || 1 / a == 1 / b;

    // Selepas menukar data kepada jenis Boolean, jika nilainya palsu, ia akan dinilai sama ada jenis data kedua-dua nilai adalah sama (kerana null adalah sama dengan undefined, false, 0, dan rentetan kosong di bawah bukan -perbandingan yang ketat)

    if(a == null || b == null)

      kembalikan a === b;

    // Jika data yang dibandingkan ialah objek Underscore encapsulated (objek dengan atribut _chain dianggap objek Underscore)

    // Kemudian buka bungkus objek dan dapatkan datanya sendiri (diakses melalui _wrapped), dan kemudian bandingkan datanya sendiri.

    // Hubungan mereka serupa dengan objek DOM yang dikapsulkan oleh jQuery, dan objek DOM yang dicipta oleh pelayar itu sendiri

    jika(a._rantai)

      a = a._berbalut;

    jika(b._rantai)

      b = b._berbalut;

    // Jika objek menyediakan kaedah isEqual tersuai (kaedah isEqual di sini bukan kaedah isEqual untuk objek Undersocre, kerana objek Undersocre telah dinyahsekat dalam langkah sebelumnya)

    // Kemudian gunakan kaedah isEqual tersuai objek untuk membandingkan dengan objek lain

    if(a.isEqual && _.isFunction(a.isEqual))

      kembalikan a.isEqual(b);

    if(b.isEqual && _.isFunction(b.isEqual))

      kembali b.isEqual(a);

    //Sahkan jenis data kedua-dua data

    // Dapatkan jenis data objek a (melalui kaedah Object.prototype.toString)

    var className = toString.call(a);

    // Jika jenis data objek a tidak sepadan dengan objek b, kedua-dua nilai data dianggap juga tidak sepadan.

    if(className != toString.call(b))

      kembali palsu;

    // Selepas melaksanakan di sini, anda boleh memastikan bahawa dua data yang perlu dibandingkan adalah jenis data komposit dan jenis data adalah sama.

    // Semak jenis data data melalui suis dan lakukan perbandingan berbeza untuk jenis data yang berbeza.

    // (Tatasusunan dan jenis objek tidak disertakan di sini, kerana ia mungkin mengandungi data yang lebih mendalam, yang akan dibandingkan kemudian)

    tukar (Nama kelas) {

      kes '[Rentetan objek]':

        // Jika yang dibandingkan ialah jenis rentetan (di mana a ialah rentetan yang dicipta melalui String() baharu)

        // Kemudian tukar B menjadi objek String dan kemudian padankan (padanan di sini tidak melakukan pemeriksaan jenis data yang ketat, kerana ia bukan rujukan daripada objek yang sama)

        // Apabila memanggil == sebagai perbandingan, kaedah toString() objek akan dipanggil secara automatik, mengembalikan dua rentetan jenis data ringkas

        kembalikan a == String(b);

      kes '[Nombor objek]':

        // Tukarkan a kepada Nombor melalui a Jika a tidak sama sebelum dan selepas penukaran, ia dianggap sebagai jenis NaN.

        // Oleh kerana NaN dan NaN tidak sama, apabila nilai a ialah NaN, anda tidak boleh hanya menggunakan == b untuk memadankan, tetapi gunakan kaedah yang sama untuk menyemak sama ada b ialah NaN (iaitu b != b)

        // Apabila nilai a ialah data bukan NaN, semak sama ada a ialah 0, kerana apabila b ialah -0, 0 === -0 ditubuhkan (sebenarnya, ia secara logiknya tergolong dalam dua data berbeza )

        kembalikan a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);

      kes '[Tarikh objek]':

      // Tiada pengembalian atau pemisah digunakan untuk jenis tarikh, jadi pelaksanaan akan diteruskan ke langkah seterusnya (tidak kira sama ada jenis data adalah jenis Boolean, kerana jenis Boolean akan disemak dalam langkah seterusnya)

      kes '[objek Boolean]':

        //Tukar tarikh atau jenis boolean kepada nombor

        // Jenis tarikh akan ditukar kepada cap waktu angka (format tarikh tidak sah akan ditukar kepada NaN)

        // Dalam jenis Boolean, benar ditukar kepada 1, palsu ditukar kepada 0

        // Bandingkan dua tarikh atau jenis Boolean untuk melihat sama ada ia adalah sama selepas ditukar kepada nombor.

        kembalikan a == b;

      kes '[objek RegExp]':

        // Jenis ungkapan biasa, akses bentuk rentetan ungkapan melalui sumber

        // Semak sama ada bentuk rentetan bagi dua ungkapan adalah sama

        // Semak sama ada sifat global kedua-dua ungkapan adalah sama (termasuk g, i, m)

        // Jika ia benar-benar sama, kedua-dua data dianggap sama

        kembalikan a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase;

    }// Apabila dilaksanakan ke tahap ini, kedua-dua data ab hendaklah daripada jenis objek atau jenis tatasusunan yang sama

    jika( jenis a != 'objek' || jenis b != 'objek')

      kembali palsu;

    // stack (heap) ialah tatasusunan kosong yang diluluskan secara dalaman apabila isEqual memanggil fungsi eq Ia juga akan diluluskan apabila kaedah eq dipanggil dalam lelaran dalaman membandingkan objek dan data kemudian.

    //panjang merekodkan panjang timbunan

    panjang var = timbunan.panjang;

    while(panjang--) {

      // Jika objek dalam timbunan sepadan dengan data a, ia dianggap sama

      if(timbunan[panjang] == a)

        kembali benar;

    }

    //Tambah data a pada timbunan

    stack.push(a);

    //Tentukan beberapa pembolehubah tempatan

    saiz var = 0, keputusan = benar;

    // Perbandingan mendalam objek dan tatasusunan melalui rekursi

    if(className == '[Array objek]') {

      //Data yang dibandingkan adalah daripada jenis tatasusunan

      // saiz merekodkan panjang tatasusunan

      // result membandingkan panjang dua tatasusunan untuk melihat sama ada ia konsisten Jika panjangnya tidak konsisten, keputusan (iaitu palsu) akan dikembalikan pada penghujung kaedah.

      saiz = a.panjang;

      hasil = saiz == b.panjang;

      // Jika panjang dua tatasusunan adalah sama

      jika(hasil) {

        //Panggil kaedah eq untuk membandingkan secara berulang elemen dalam tatasusunan (jika tatasusunan mengandungi tatasusunan atau objek dua dimensi, kaedah eq akan melakukan perbandingan yang mendalam)

        manakala(saiz--) {

          // Apabila memastikan kedua-dua tatasusunan mengandungi elemen pada indeks semasa, panggil kaedah eq untuk perbandingan mendalam (luluskan data timbunan kepada kaedah eq)

          // Simpan hasil perbandingan dalam pembolehubah hasil Jika keputusan palsu (iaitu, data elemen tertentu yang diperoleh semasa perbandingan tidak konsisten), hentikan lelaran

          if(!( hasil = saiz dalam == saiz dalam b && eq(a[saiz], b[saiz], tindanan)))

            pecah;

        }

      }

    } lain {

      //Data yang dibandingkan adalah jenis objek

      // Jika kedua-dua objek bukan contoh kelas yang sama (berbanding melalui sifat pembina), kedua-dua objek dianggap tidak sama.

      if('pembina' dalam a != 'pembina' dalam b || a.pembina != b.pembina)

        kembali palsu;

      // Bandingkan data dalam dua objek dengan mendalam

      untuk(kunci var dalam a) {

        jika(_.mempunyai(a, kunci)) {

          // saiz digunakan untuk merekodkan bilangan atribut yang dibandingkan, kerana apa yang dilalui di sini ialah atribut objek a, dan membandingkan data atribut dalam objek b

          // Apabila bilangan atribut dalam objek b melebihi objek a, logik di sini berlaku, tetapi kedua-dua objek tidak sama.

          saiz ;

          // Panggil kaedah eq secara berulang untuk membandingkan secara mendalam nilai atribut dalam dua objek

          // Rekod hasil perbandingan kepada pembolehubah hasil, dan hentikan lelaran apabila data tidak sama dibandingkan.

          if(!( result = _.has(b, key) && eq(a[key], b[key], stack)))

            pecah;

        }

      }

      // Perbandingan mendalam selesai Ia boleh dipastikan bahawa semua data dalam objek a dan data yang sama dalam objek b juga wujud.

      // Semak sama ada bilangan atribut dalam objek b adalah sama dengan objek a berdasarkan saiz (panjang atribut objek)

      jika(hasil) {

        // Melintasi semua sifat dalam objek b

        untuk(masukkan b) {

          // Apabila saiz telah mencapai 0 (iaitu, bilangan atribut dalam objek a telah dilalui), dan masih terdapat atribut dalam objek b, maka objek b mempunyai lebih banyak atribut daripada objek a.

          jika(_.mempunyai(b, kunci) && !(saiz--))

            pecah;

        }

        // Apabila objek b mempunyai lebih banyak atribut daripada objek a, kedua-dua objek dianggap tidak sama.

        hasil = !saiz;

      }

    }

    // Apabila fungsi menyelesaikan pelaksanaan, keluarkan data pertama daripada timbunan (apabila membandingkan objek atau tatasusunan, kaedah eq akan diulang dan mungkin terdapat berbilang data dalam timbunan)

    stack.pop();

    //Hasil yang dikembalikan merekodkan hasil perbandingan akhir

    pulangan hasil;

  }

 

  // Bandingkan nilai dua data (menyokong jenis data komposit), kaedah luaran fungsi dalaman eq

  _.isEqual = fungsi(a, b) {

    pulangkan eq(a, b, []);

  };

  // Semak sama ada data kosong, termasuk '', false, 0, null, undefined, NaN, tatasusunan kosong (panjang tatasusunan ialah 0) dan objek kosong (objek itu sendiri tidak mempunyai sifat)

  _.isEmpty = function(obj) {

    // obj ditukar kepada jenis Boolean dan nilainya adalah palsu

    if(obj == null)

      kembali benar;

    // Semak sama ada objek atau panjang rentetan ialah 0

    if(_.isArray(obj) || _.isString(obj))

      kembali obj.length === 0;

    // Semak objek (apabila menggunakan untuk dalam gelung, sifat objek itu sendiri akan digelungkan terlebih dahulu, diikuti dengan sifat dalam rantai prototaip), jadi jika harta pertama kepunyaan objek itu sendiri, maka objek itu bukan objek kosong

    untuk(kunci var dalam obj)

    if(_.has(obj, key))

      kembali palsu;

    // Semua jenis data belum lulus pengesahan dan merupakan data kosong

    kembali benar;

  };

  // Sahkan sama ada objek itu objek DOM

  _.isElement = function(obj) {

    kembali !!(obj && obj.nodeType == 1);

  };

  // Sahkan sama ada objek ialah jenis tatasusunan, mula-mula panggil kaedah isArray yang disediakan oleh persekitaran hos

  _.isArray = nativeIsArray ||

  fungsi(obj) {

    kembali keString.call(obj) == '[Array objek]';

  };

 

  // Sahkan sama ada objek ialah objek jenis data komposit (iaitu String jenis data bukan asas, Boolean, Nombor, nol, tidak ditentukan)

  // Jika jenis data asas dicipta melalui baru, ia juga tergolong dalam jenis objek

  _.isObject = function(obj) {

    return obj === Objek(obj);

  };

  // Überprüfen Sie, ob ein Datum ein Argumentparameterobjekt ist

  _.isArguments = function(obj) {

    return toString.call(obj) == '[Objektargumente]';

  };

  // Überprüfen Sie die Funktion isArguments. Wenn die laufende Umgebung die Argumenttypdaten nicht normal überprüfen kann, definieren Sie die Methode isArguments neu.

  if(!_.isArguments(arguments)) {

    // Wenn die Umgebung den Argumenttyp nicht über toString überprüfen kann, überprüfen Sie ihn, indem Sie die eindeutige Callee-Methode der Argumente aufrufen.

    _.isArguments = function(obj) {

      // callee ist ein Attribut von arguments, das auf einen Verweis auf die Funktion selbst verweist, zu der arguments gehört.

      return !!(obj && _.has(obj, 'callee'));

    };

  }

 

  // Überprüfen Sie, ob das Objekt ein Funktionstyp ist

  _.isFunction = function(obj) {

    return toString.call(obj) == '[object Function]';

  };

  // Überprüfen Sie, ob das Objekt ein String-Typ ist

  _.isString = function(obj) {

    return toString.call(obj) == '[object String]';

  };

  // Überprüfen Sie, ob das Objekt ein numerischer Typ ist

  _.isNumber = function(obj) {

    return toString.call(obj) == '[Objektnummer]';

  };

  // Prüfen, ob eine Zahl eine gültige Zahl ist und einen gültigen Bereich hat (Zahlentyp, Wert zwischen negativer Unendlichkeit und positiver Unendlichkeit)

  _.isFinite = function(obj) {

    return _.isNumber(obj) && isFinite(obj);

  };

  // Überprüfen Sie, ob die Daten vom Typ NaN sind (nur NaN und NaN sind nicht für alle Daten gleich)

  _.isNaN = function(obj) {

    return obj !== obj;

  };

  // Prüfen Sie, ob die Daten vom Typ Boolean sind

  _.isBoolean = function(obj) {

    //Unterstützt boolesche Daten in Literal- und Objektform

    return obj === true ||. obj === false ||. toString.call(obj) == '[object Boolean]';

  };

  // Überprüfen Sie, ob die Daten vom Typ „Datum“ sind

  _.isDate = function(obj) {

    return toString.call(obj) == '[Objektdatum]';

  };

  // Überprüfen Sie, ob die Daten ein regulärer Ausdruckstyp sind

  _.isRegExp = function(obj) {

    return toString.call(obj) == '[object RegExp]';

  };

  // Überprüfen Sie, ob die Daten ein Nullwert sind

  _.isNull = function(obj) {

    return obj === null;

  };

  // Prüfen Sie, ob die Daten ein undefinierter Wert sind

  _.isUndefiniert = function(obj) {

    return obj ===

    ungültig 0;

  };

  // Prüfen, ob eine Eigenschaft zum Objekt selbst gehört, nicht zur Prototypenkette

  _.has = function(obj, key) {

    return hasOwnProperty.call(obj, key);

  };

  // Utility-Funktion

  // -------------------

 

  // Das mit _ (Unterstrich) benannte Underscore-Objekt verwerfen und das Underscore-Objekt zurückgeben, das im Allgemeinen verwendet wird, um Namenskonflikte zu vermeiden oder Benennungsmethoden zu standardisieren.

  // Zum Beispiel:

  // var us = _.noConflict(); // Brechen Sie die _ (Unterstrich)-Benennung ab und speichern Sie das Underscore-Objekt in der us-Variablen

  // console.log(_); // _ (underscore) kann nicht mehr auf das Underscore-Objekt zugreifen und kehrt zum Wert vor der Definition von Underscore zurück.

  _.noConflict = function() {

    // Die Variable previousUnderscore zeichnet den Wert von _ (Unterstrich) auf, bevor Underscore definiert wird.

    root._ = previousUnderscore;

    gib dies zurück;

  };

  // Den gleichen Wert wie der Parameter zurückgeben, der im Allgemeinen zum Konvertieren einer Datenerfassungsmethode in eine Funktionserfassungsmethode verwendet wird (wird intern als Standardprozessorfunktion beim Erstellen von Methoden verwendet).

  _.identity = Funktion(Wert) {

    Rückgabewert;

  };

  // Die angegebene Funktion n-mal iterativ ausführen lassen (keine Parameter)

  _.times = function(n, iterator, context) {

    for(var i = 0; i < n; i )

    iterator.call(context, i);

  };

  // Sonderzeichen in HTML-Strings in HTML-Entitäten konvertieren, einschließlich & < >

  _.escape = function(string) {

    return ('' string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/ "/g, '"').replace(/'/g, ''').replace(///g, '/');

  };

  //Geben Sie das Attribut eines Objekts an und geben Sie den dem Attribut entsprechenden Wert zurück. Wenn das Attribut einer Funktion entspricht, wird die Funktion ausgeführt und das Ergebnis zurückgegeben.

  _.result = function(object, property) {

    if(object == null)

      null zurückgeben;

    // Den Wert des Objekts abrufen

    var value = object[property];

    // Wenn der Wert eine Funktion ist, führen Sie ihn aus und geben Sie ihn zurück, andernfalls wird er direkt zurückgegeben

    return _.isFunction(value) ? value.call(object) : value;

  };

  //Fügen Sie dem Underscore-Objekt eine Reihe benutzerdefinierter Methoden hinzu, um das Underscore-Plug-In zu erweitern

  _.mixin = function(obj) {

    //obj ist ein Objekt, das eine Reihe benutzerdefinierter Methoden sammelt. Die Methode zum Durchlaufen des Objekts erfolgt hier jeweils

    every(_.functions(obj), function(name) {

      //Fügen Sie benutzerdefinierte Methoden zu Objekten hinzu, die von Underscore über die Funktion addToWrapper erstellt wurden, um objektbasierte Aufrufe zu unterstützen

      // Fügen Sie außerdem Methoden zu _ selbst hinzu, um Funktionsaufrufe zu unterstützen

      addToWrapper(name, _[name] = obj[name]);

    });

  };

  // Einen global eindeutigen Bezeichner erhalten, der Bezeichner beginnt bei 0 und wird akkumuliert

  var idCounter = 0;

  // Präfix stellt das Präfix des Bezeichners dar. Wenn kein Präfix angegeben ist, wird der Bezeichner im Allgemeinen zum Erstellen einer eindeutigen ID für ein Objekt oder DOM zurückgegeben.

  _.uniqueId = function(prefix) {

    var id = idCounter;

    Präfix zurückgeben? Präfix-ID: id;

  };

  // Definieren Sie das Begrenzungssymbol der Vorlage, das in der Vorlagenmethode verwendet wird

  _.templateSettings = {

    //Trennzeichen des ausführbaren JavaScript-Codes

    auswerten: /<%([sS] ?)%>/g,

    // Das Trennzeichen der Variablen direkt ausgeben

    interpolieren: /<%=([sS] ?)%>/g,

    //Trennzeichen erforderlich, um HTML als String auszugeben (spezielle Symbole in String-Form umwandeln)

    Escape: /<%-([sS] ?)%>/g

  };

 

  var noMatch = /.^/;

 

  // Das Escape-Objekt zeichnet die Entsprechung zwischen Sonderzeichen und Zeichenfolgenformen auf, die ineinander konvertiert werden müssen, und wird als Index verwendet, wenn die beiden ineinander konvertiert werden.

  // Definieren Sie zunächst Sonderzeichen entsprechend der Zeichenfolgenform

  var escapes = {

    '\' : '\',

    "'" : "'",

    'r': 'r',

    'n': 'n',

    't': 't',

    'u2028': 'u2028',

    'u2029': 'u2029'

  };

  // Alle Sonderzeichenketten durchlaufen und die Zeichenfolgenform mit Sonderzeichen als Schlüssel aufzeichnen

  for(var p in Escapezeichen)

  entkommt[escapes[p]] = p;

  // Definieren Sie die Sonderzeichen, die in der Vorlage ersetzt werden müssen, einschließlich Backslash, einfaches Anführungszeichen, Wagenrücklauf, Zeilenvorschub, Tabulator, Zeilentrennzeichen, Absatztrennzeichen

  // Wird beim Konvertieren spezieller Symbole in einer Zeichenfolge in eine Zeichenfolgenform verwendet

  var escaper = /\|'|r|n|t|u2028|u2029/g;

  // Wird beim Umkehren (Ersetzen) von Sonderzeichen in Stringform verwendet

  var unescaper = /\(\|'|r|n|t|u2028|u2029)/g;

 

  //Spezielle Symbole im String umkehren

  // Der JavaScript-Quellcode, der in der Vorlage ausgeführt werden muss, muss mit speziellen Symbolen umgekehrt werden. Andernfalls wird ein Syntaxfehler ausgegeben, wenn er in Form von HTML-Entitäten oder Zeichenfolgen angezeigt wird

  var unescape = function(code) {

    Rückgabecode.replace(unescaper, function(match, escape) {

      return escapes[escape];

    });

  };

  // Analysemethode für Unterstrichvorlagen, die zum Füllen von Daten in eine Vorlagenzeichenfolge verwendet wird

  // Template-Parsing-Prozess:

  // 1. Konvertieren Sie spezielle Symbole in der Vorlage in Zeichenfolgen

  // 2. Analysieren Sie das Escape-Formular-Tag und analysieren Sie den Inhalt in HTML-Entitäten

  // 3. Analysieren Sie interpolierte Formular-Tags und Ausgabevariablen

  // 4. Analysieren Sie das Evalue-Formular-Tag und erstellen Sie ausführbaren JavaScript-Code

  // 5. Generieren Sie eine Verarbeitungsfunktion, die die Vorlage nach dem Abrufen der Daten direkt ausfüllen und die ausgefüllte Zeichenfolge zurückgeben kann

  // 6. Den gefüllten String oder das Handle der Verarbeitungsfunktion gemäß den Parametern zurückgeben

  //------------------

  // Im Vorlagenkörper können zwei Parameter über Argumente abgerufen werden, nämlich die Fülldaten (benannt obj) und das Underscore-Objekt (benannt _).

  _.template = Funktion(Text, Daten, Einstellungen) {

    // Vorlagenkonfiguration, wenn kein Konfigurationselement angegeben ist, wird das in templateSettings angegebene Konfigurationselement verwendet.

    Settings = _.defaults(settings || {}, _.templateSettings);

 

    // Beginnen Sie mit dem Parsen der Vorlage in ausführbaren Quellcode

    var source = "__p ='" text.replace(escaper, function(match) {

      //Konvertieren Sie spezielle Symbole in String-Form

      return '\' escapes[match];

    }).replace(settings.escape || noMatch, function(match, code) {

      // Analysieren Sie das Escape-Formular-Tag <%- %> und konvertieren Sie den in der Variablen enthaltenen HTML-Code über die Funktion _.escape in eine HTML-Entität

      return "' n_.escape(" unescape(code) ") n'";

    }).replace(settings.interpolate || noMatch, function(match, code) {

      // Analysieren Sie das interpolierte Formular-Tag <%= %>, verbinden Sie den Vorlageninhalt als Variable mit anderen Zeichenfolgen und er wird als Variable ausgegeben

      return "' n(" unescape(code) ") n'";

    }).replace(settings.evaluate || noMatch, function(match, code) {

      // Analysieren Sie das Evaluierungsformular-Tag <% %>. Der auszuführende JavaScript-Code wird im Evaluierungs-Tag gespeichert. Das aktuelle String-Splicing endet hier und wird als JavaScript-Syntax in einer neuen Zeile und dem folgenden Inhalt ausgeführt wird wieder als Zeichen verwendet, damit der JavaScript-Code im Evaluierungs-Tag normal ausgeführt werden kann.

      return "';n" unescape(code) "n;__p ='";

    }) "';N";

    if(!settings.variable)

      source = 'with(obj||{}){n' source '}n';

    source = "var __p='';" "var print=function(){__p =Array.prototype.join.call(arguments, '')};n" source "return __p;n";

 

    // Erstellen Sie eine Funktion, verwenden Sie den Quellcode als Funktionsausführungskörper und übergeben Sie obj und Underscore als Parameter an die Funktion

    var render = new Function(settings.variable || 'obj', '_', source);

    // Wenn die Fülldaten der Vorlage angegeben sind, ersetzen Sie den Vorlageninhalt und geben Sie das ersetzte Ergebnis zurück

    if(Daten)

      return render(data, _);

    // Wenn keine Fülldaten angegeben sind, wird eine Funktion zurückgegeben, die die empfangenen Daten in der Vorlage ersetzt

    // Wenn dieselbe Vorlage im Programm mehrmals ausgefüllt wird, wird empfohlen, die Fülldaten nicht beim ersten Aufruf anzugeben. Nachdem Sie die Referenz der Verarbeitungsfunktion erhalten haben, verbessert ein direkter Aufruf die Betriebseffizienz.

    var template = function(data) {

      return render.call(this, data, _);

    };

    // Fügen Sie die erstellte Quellcodezeichenfolge zum Funktionsobjekt hinzu, das im Allgemeinen zum Debuggen und Testen verwendet wird

    template.source = 'function(' (settings.variable || 'obj') '){n' source '}';

    //Wenn keine Fülldaten angegeben sind, wird das Handle der Verarbeitungsfunktion zurückgegeben

    Rücksendevorlage;

  };

  // Unterstützt den Methodenkettenbetrieb des Underscore-Objekts, siehe wrapper.prototype.chain

  _.chain = function(obj) {

    return _(obj).chain();

  };

  // Unterstrich-Objekt kapselt verwandte Methoden

  // ---------------

 

  //Erstelle einen Wrapper, um einige Rohdaten zu verpacken

  // Alle Undersocre-Objekte werden intern durch die Wrapper-Funktion erstellt und gekapselt

  //Die interne Beziehung zwischen Underscore und Wrapper:

  // - Definieren Sie die Variable _ intern und fügen Sie Unterstrich-bezogene Methoden zu _ hinzu, damit Funktionsaufrufe unterstützt werden können, z. B. _.bind()

  // - Definieren Sie die Wrapper-Klasse intern und verweisen Sie das Prototypobjekt von _ auf den Prototyp der Wrapper-Klasse

  // -Fügen Sie Underscore-bezogene Methoden zum Wrapper-Prototyp hinzu, und das erstellte _-Objekt verfügt über Underscore-Methoden

  // – Array.prototype-bezogene Methoden zum Wrapper-Prototyp hinzufügen, und das erstellte _-Objekt verfügt über die Methoden in Array.prototype

  // -new _() erstellt tatsächlich ein Wrapper()-Objekt und gibt es zurück, speichert das ursprüngliche Array in der Variablen _wrapped und ruft die entsprechende Methode mit dem Originalwert als erstem Parameter auf.

  var wrapper = function(obj) {

    //Die Originaldaten werden im _wrapped-Attribut des umschlossenen Objekts gespeichert

    this._wrapped = obj;

  };

  // Das Prototypobjekt von Underscore auf den Prototyp des Wrappers verweisen, sodass durch das Hinzufügen von Methoden wie dem Wrapper-Prototyp auch das Underscore-Objekt über dieselbe Methode verfügt.

  _.prototype = wrapper.prototype;

 

  //Ein Objekt zurückgeben. Wenn der aktuelle Underscore die Methode chain() aufruft (d. h. das _chain-Attribut ist wahr), wird ein umschlossenes Underscore-Objekt zurückgegeben, andernfalls wird das Objekt selbst zurückgegeben.

  // Ergebnisfunktion
Salin selepas log masuk
Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan