Underscore.js



underscore

Underscore.js

وظائف التجميع (المصفوفات أو الكائنات)

كل _.each(list, iteratee, [context]) الاسم المستعار: forEach
يتكرر فوق قائمة من العناصر ، مما يعطي كل دور بدوره إلى وظيفة متكررة . يتم ربط iteratee إلى كائن السياق ، إذا تم تمرير أحد. يتم استدعاء كل استدعاء من iteratee مع ثلاث وسائط: (عنصر ، فهرس ، قائمة) . إذا كانت القائمة عبارة عن كائن JavaScript ، فستكون وسيطات iteratee (قيمة ، مفتاح ، قائمة) . إرجاع القائمة للتسلسل.

_.each([1, 2, 3], alert);
=> alerts each number in turn...
_.each({one: 1, two: 2, three: 3}, alert);
=> alerts each number value in turn...

ملاحظة: تعمل دالات التجميع على المصفوفات والكائنات وعناصر شبيهة بالصفوف مثل الوسائط و NodeList وما شابهها. ولكنه يعمل عن طريق كتابة البط ، لذا تجنب تمرير الكائنات ذات خاصية طولية . من الجيد أيضًا ملاحظة أن كل حلقة لا يمكن كسرها - للكسر ، استخدم _.find بدلاً من ذلك.

map _.map(list, iteratee, [context]) Alias: collect
ينتج مصفوفة جديدة من القيم عن طريق تعيين كل قيمة في القائمة من خلال وظيفة التحويل ( iteratee ). يتم تمرير iteratee ثلاث وسائط: القيمة ، ثم فهرس (أو مفتاح ) التكرار ، وأخيراً مرجع إلى القائمة بأكملها.

_.map([1, 2, 3], function(num){ return num * 3; });
=> [3, 6, 9]
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]
_.map([[1, 2], [3, 4]], _.first);
=> [1, 3]

تقليل _.reduce(list, iteratee, [memo], [context]) Aliases: inject ، foldl
يُعرف أيضًا باسم inject and foldl ، ويقلل الدمج أسفل قائمة القيم في قيمة واحدة. المذكرة هي الحالة الأولية للتخفيض ، ويجب إعادة كل خطوة متتالية منه بواسطة iteratee . يتم تمرير iteratee أربع وسائط: المذكرة ، ثم القيمة والفهرس (أو مفتاح) للتكرار ، وأخيراً مرجع إلى القائمة بأكملها.

إذا لم يتم تمرير أي مذكرة إلى الاستدعاء الأولي للتقليل ، لا يتم استدعاء iteratee على العنصر الأول من القائمة. يتم بدلاً من ذلك تمرير العنصر الأول كمذكرة في استدعاء iteratee على العنصر التالي في القائمة.

var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
=> 6

reduRight _.reduceRight(list, iteratee, [memo], [context]) الاسم المستعار: foldr
النسخة الصحيحة-اقتران من الحد . Foldr ليست مفيدة في جافا سكريبت كما سيكون في لغة مع تقييم كسول.

var list = [[0, 1], [2, 3], [4, 5]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
=> [4, 5, 2, 3, 0, 1]

find _.find(list, predicate, [context]) Alias: detect
يبحث من خلال كل قيمة في القائمة ، ويعيد أول قيمة يمر بها اختبار الحقيقة ( المسند ) ، أو غير معرف إذا لم تختر أي قيمة الاختبار. ترجع الدالة بمجرد العثور على عنصر مقبول ، ولا تعبر القائمة بأكملها. يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2

filter _.filter(list, predicate, [context]) Alias: select
ينظر من خلال كل قيمة في القائمة ، ويعيد مجموعة من جميع القيم التي تمر باختبار الحقيقة ( المسند ). يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]

findWhere _.findWhere(list, properties)
يبحث من خلال القائمة ويعرض القيمة الأولى التي تطابق جميع أزواج القيم الرئيسية المدرجة في الخصائص .

إذا لم يتم العثور على أي تطابق ، أو إذا كانت القائمة فارغة ، فسيتم إرجاع غير معروف .

_.where(listOfPlays, {author: "Shakespeare", year: 1611});
=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
    {title: "The Tempest", author: "Shakespeare", year: 1611}]

حيث _.where(list, properties)
يبحث في كل قيمة في القائمة ، ويعيد مصفوفة من جميع القيم التي تتطابق مع أزواج القيم الرئيسية المدرجة في الخصائص .

_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times",
  reason: "For its public service in publishing in full so many official reports,
  documents and speeches by European statesmen relating to the progress and
  conduct of the war."}

رفض _.reject(list, predicate, [context])
إرجاع القيم في القائمة دون العناصر التي يمر عليها اختبار الحقيقة ( المسند ). عكس مرشح . يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [1, 3, 5]

كل _.every(list, [predicate], [context]) الاسم المستعار: الكل
إرجاع true إذا مرت جميع القيم في القائمة اختبار الحقيقة المسند . الدوائر القصيرة والتوقفات تعبر القائمة إذا تم العثور على عنصر زائف. يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

_.every([2, 4, 5], function(num) { return num % 2 == 0; });
=> false

بعض _.some(list, [predicate], [context]) الاسم المستعار: أي
إرجاع true إذا مرت أي من القيم في القائمة اختبار الحقيقة المسند . الدوائر القصيرة والتوقفات تعبر القائمة إذا تم العثور على عنصر حقيقي. يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

_.some([null, 0, 'yes', false]);
=> true

يحتوي على _.contains(list, value, [fromIndex]) أسماء مستعارة: تتضمن ، تتضمن
إرجاع true إذا كانت القيمة موجودة في القائمة . يستخدم indexOf داخليًا ، إذا كانت القائمة هي صفيف. استخدم fromIndex لبدء البحث في فهرس معين.

_.contains([1, 2, 3], 3);
=> true

استدعاء _.invoke(list, methodName, *arguments)
يستدعي الأسلوب المسمى من قبل methodName على كل قيمة في القائمة . سيتم إعادة توجيه أية وسائط إضافية تم تمريرها للاستدعاء إلى استدعاء الأسلوب.

_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
=> [[1, 5, 7], [1, 2, 3]]

نتف _.pluck(list, propertyName)
إصدار ملائم لما قد يكون أكثر حالات الاستخدام استخدامًا للخريطة : استخراج قائمة قيم العقارات.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.pluck(stooges, 'name');
=> ["moe", "larry", "curly"]

max _.max(list, [iteratee], [context])
لعرض القيمة القصوى في القائمة . إذا تم توفير دالة iteratee ، فسيتم استخدامها على كل قيمة لإنشاء المعيار الذي يتم من خلاله ترتيب القيمة. - يتم إرجاع إنفينيتي إذا كانت القائمة فارغة ، لذلك قد يكون هناك حاجة لحرس isEmpty . سيتم تجاهل القيم غير الرقمية في القائمة .

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.max(stooges, function(stooge){ return stooge.age; });
=> {name: 'curly', age: 60};

min _.min(list, [iteratee], [context])
لعرض القيمة الدنيا في القائمة . إذا تم توفير دالة iteratee ، فسيتم استخدامها على كل قيمة لإنشاء المعيار الذي يتم من خلاله ترتيب القيمة. يتم إرجاع إنفينيتي إذا كانت القائمة فارغة ، لذلك قد تكون هناك حاجة لحرس isEmpty . سيتم تجاهل القيم غير الرقمية في القائمة .

var numbers = [10, 5, 100, 2, 1000];
_.min(numbers);
=> 2

sortBy _.sortBy(list, iteratee, [context])
لعرض نسخة مرتبة (ثابتة) من القائمة ، مرتبة ترتيبًا تصاعديًا حسب نتائج تشغيل كل قيمة من خلال iteratee . قد يكون iteratee أيضًا اسم سلسلة الخاصية للفرز حسب (على سبيل المثال ، الطول ).

_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
=> [5, 4, 6, 3, 1, 2]

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.sortBy(stooges, 'name');
=> [{name: 'curly', age: 60}, {name: 'larry', age: 50}, {name: 'moe', age: 40}];

groupBy _.groupBy(list, iteratee, [context])
تقسيم مجموعة إلى مجموعات ، مجمعة حسب نتيجة تشغيل كل قيمة خلال iteratee . إذا كان iteratee عبارة عن سلسلة بدلاً من دالة ، فإن المجموعات بواسطة الخاصية المسماة بواسطة iteratee على كل من القيم.

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
=> {1: [1.3], 2: [2.1, 2.4]}

_.groupBy(['one', 'two', 'three'], 'length');
=> {3: ["one", "two"], 5: ["three"]}

indexBy _.indexBy(list, iteratee, [context])
وبالنظر إلى قائمة ، وتقوم دالة iteratee التي ترجع مفتاحًا لكل عنصر في القائمة (أو اسم الخاصية) ، بإرجاع كائن به فهرس لكل عنصر. تمامًا مثل groupBy ، ولكن عندما تعرف أن مفاتيحك فريدة.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.indexBy(stooges, 'age');
=> {
  "40": {name: 'moe', age: 40},
  "50": {name: 'larry', age: 50},
  "60": {name: 'curly', age: 60}
}

countBy _.countBy(list, iteratee, [context])
لفرز قائمة في مجموعات وإرجاع عدد لعدد الكائنات في كل مجموعة. على غرار groupBy ، ولكن بدلاً من إرجاع قائمة القيم ، تُرجع حسابًا لعدد القيم في هذه المجموعة.

_.countBy([1, 2, 3, 4, 5], function(num) {
  return num % 2 == 0 ? 'even': 'odd';
});
=> {odd: 3, even: 2}

خلط ورق اللعب _.shuffle(list)
لعرض نسخة عشوائية من القائمة ، باستخدام نسخة من لعبة Fisher-Yates shuffle .

_.shuffle([1, 2, 3, 4, 5, 6]);
=> [4, 1, 6, 3, 5, 2]

sample _.sample(list, [n])
أنتج عينة عشوائية من القائمة . تمرير رقم لإرجاع عناصر n عشوائي من القائمة. وإلا سيتم إرجاع عنصر عشوائي واحد.

_.sample([1, 2, 3, 4, 5, 6]);
=> 4

_.sample([1, 2, 3, 4, 5, 6], 3);
=> [1, 6, 2]

toArray _.toArray(list)
يخلق صفيف حقيقي من القائمة (أي شيء يمكن تكراره). مفيد في نقل كائن الحجج .

(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
=> [2, 3, 4]

حجم _.size(list)
إرجاع عدد القيم في القائمة .

_.size({one: 1, two: 2, three: 3});
=> 3

partition _.partition(list, predicate)
تقسيم القائمة إلى صفيفين: عنصر واحد كل عناصر إرضاء والآخر كل العناصر لا تفي المسند . يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

_.partition([0, 1, 2, 3, 4, 5], isOdd);
=> [[1, 3, 5], [0, 2, 4]]

compact _.compact(list)
لعرض نسخة من القائمة مع إزالة جميع قيم الفالسة. في جافا سكريبت ، كاذبة ، خالية ، 0 ، "" ، غير محددة و NaN كلها كاذبة.

_.first([5, 4, 3, 2, 1]);
=> 5

وظائف صفيف

ملاحظة: ستعمل جميع وظائف الصفيف أيضًا على كائن الوسيطات . ومع ذلك ، لا يتم تصميم دالات Underscore للعمل على صفائف "sparse".

first _.first(array, [n]) Aliases: head ، take
إرجاع العنصر الأول من صفيف . سيؤدي التمرير n إلى إرجاع عناصر n الأولى من المصفوفة.

_.initial([5, 4, 3, 2, 1]);
=> [5, 4, 3, 2]

initial _.initial(array, [n])
إرجاع كل شيء ما عدا الإدخال الأخير للمصفوفة. مفيدة بشكل خاص على وجوه الحجج. قم بالمرور n لاستبعاد عناصر n الأخيرة من النتيجة.

_.last([5, 4, 3, 2, 1]);
=> 1

last _.last(array, [n])
إرجاع العنصر الأخير من صفيف . سيؤدي التمرير n إلى إرجاع آخر عناصر n في الصفيف.

_.rest([5, 4, 3, 2, 1]);
=> [4, 3, 2, 1]

بقية _.rest(array, [index]) أسماء مستعارة: ذيل ، قطرة
يرجع بقية العناصر في صفيف. قم بتمرير فهرس لإرجاع قيم الصفيف من ذلك الفهرس.

_.compact([0, 1, false, 2, '', 3]);
=> [1, 2, 3]

تسطيح _.flatten(array, [shallow])
تسطيح مجموعة متداخلة (يمكن أن يكون التعشيش لأي عمق). إذا قمت بتمرير سطح ضحل ، فلن يتم تسوية الصفيف إلا بمستوى واحد.

_.flatten([1, [2], [3, [[4]]]]);
=> [1, 2, 3, 4];

_.flatten([1, [2], [3, [[4]]]], true);
=> [1, 2, 3, [[4]]];

بدون _.without(array, *values) دون _.without(array, *values)
تقوم بإرجاع نسخة من الصفيف مع إزالة كافة مثيلات القيم .

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
=> [2, 3, 4]

union _.union(*arrays)
يحسب الاتحاد من المصفوفات التي تم تمريرها: قائمة العناصر الفريدة ، بالترتيب ، الموجودة في صف واحد أو أكثر من المصفوفات .

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

تقاطع _.intersection(*arrays)
يحسب قائمة القيم التي هي تقاطع كل المصفوفات . كل قيمة في النتيجة موجودة في كل صفائف .

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]

الاختلاف _.difference(array, *others)
تشبه إلى بدون ، ولكن تعيد القيم من الصفيف غير الموجودة في المصفوفات الأخرى .

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

uniq _.uniq(array, [isSorted], [iteratee]) الاسم المستعار: فريد
ينتج نسخة خالية مكررة من الصفيف ، وذلك باستخدام === لاختبار مساواة الكائنات. على وجه الخصوص يتم الاحتفاظ فقط بالظهور الأول لكل قيمة. إذا كنت تعرف مقدمًا أنه يتم فرز المصفوفة ، فإن تشغيل true لـ isSorted سيشغل خوارزمية أسرع بكثير. إذا كنت ترغب في حساب العناصر الفريدة استنادًا إلى عملية تحويل ، فمرر وظيفة iteratee .

_.uniq([1, 2, 1, 4, 1, 3]);
=> [1, 2, 4, 3]

zip _.zip(*arrays)
يدمج قيم كل من المصفوفات مع القيم في الموضع المناظر. مفيد عندما يكون لديك مصادر بيانات منفصلة يتم تنسيقها من خلال مطابقة فهارس المصفوفة. استخدم مع تطبيق للمرور في صفيف من المصفوفات. إذا كنت تعمل مع مصفوفة من المصفوفات المتداخلة ، فيمكن استخدام هذا لتحويل المصفوفة.

_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]

unzip _.unzip(array)
عكس zip . بالنظر إلى صفيف من المصفوفات ، تقوم بإرجاع سلسلة من المصفوفات الجديدة ، يحتوي أولها على جميع العناصر الأولى في صفائف الإدخال ، ويحتوي الثاني منها على جميع العناصر الثانية ، وهكذا.

_.unzip([["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]);
=> [['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]]

object _.object(list, [values])
يحول المصفوفات إلى كائنات. قم بتمرير إما قائمة واحدة من أزواج [المفتاح ، القيمة] ، أو قائمة من المفاتيح ، وقائمة من القيم. المرور عن طريق أزواج هو عكس الأزواج . في حالة وجود مفاتيح مكررة ، فستفوز القيمة الأخيرة.

_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
=> {moe: 30, larry: 40, curly: 50}

_.object([['moe', 30], ['larry', 40], ['curly', 50]]);
=> {moe: 30, larry: 40, curly: 50}

قطعة _.chunk(array, length)
قطع صفيف في صفائف متعددة ، كل تحتوي على طول أو عدد أقل من العناصر.

_.indexOf([1, 2, 3], 2);
=> 1

indexOf _.indexOf(array, value, [isSorted])
لعرض الفهرس الذي توجد به القيمة في الصفيف ، أو إذا كانت القيمة غير موجودة في الصفيف . إذا كنت تعمل باستخدام مصفوفة كبيرة ، وكنت تعرف أن الصفيف تم فرزه بالفعل ، فعليك تمرير true لـ isSorted لاستخدام بحث ثنائي أسرع ... أو ، تمرير رقم كوسيطة ثالثة من أجل البحث عن المطابقة الأولى قيمة في الصفيف بعد الفهرس المعطى.

_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
=> 4

lastIndexOf _.lastIndexOf(array, value, [fromIndex])
لعرض فهرس آخر تكرار للقيمة في الصفيف ، أو إذا كانت القيمة غير موجودة. قم بالمرور من إندستكس لبدء البحث في فهرس معين.

_.sortedIndex([10, 20, 30, 40, 50], 35);
=> 3

var stooges = [{name: 'moe', age: 40}, {name: 'curly', age: 60}];
_.sortedIndex(stooges, {name: 'larry', age: 50}, 'age');
=> 1

sortedIndex _.sortedIndex(array, value, [iteratee], [context])
يستخدم بحثًا ثنائيًا لتحديد الفهرس الذي يجب إدخال القيمة به في الصفيف من أجل الحفاظ على ترتيب الفرز الخاص بالصفيف . إذا تم توفير وظيفة iteratee ، فسيتم استخدامها لحساب تصنيف الفرز لكل قيمة ، بما في ذلك القيمة التي تمررها. قد يكون iteratee أيضًا اسم سلسلة الخاصية للفرز حسب (على سبيل المثال ، الطول ).

_.findIndex([4, 6, 8, 12], isPrime);
=> -1 // not found
_.findIndex([4, 6, 7, 12], isPrime);
=> 2

findIndex _.findIndex(array, predicate, [context])
على غرار _.indexOf ، تقوم بإرجاع الفهرس الأول حيث يمر اختبار الحقيقة المسند . خلاف ذلك إرجاع -1 .

var users = [{'id': 1, 'name': 'Bob', 'last': 'Brown'},
             {'id': 2, 'name': 'Ted', 'last': 'White'},
             {'id': 3, 'name': 'Frank', 'last': 'James'},
             {'id': 4, 'name': 'Ted', 'last': 'Jones'}];
_.findLastIndex(users, {
  name: 'Ted'
});
=> 3

findLastIndex _.findLastIndex(array, predicate, [context])
مثل _.findIndex لكنه يكرر الصفيف في الاتجاه المعاكس ، _.findIndex الفهرس أقرب إلى النهاية حيث يمر اختبار الحقيقة المسند .

_.range(10);
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
=> [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0);
=> []

range _.range([start], stop, [step])
وظيفة لإنشاء قوائم مرقمة من الأرقام الصحيحة ، في متناول اليد لكل حلقات الخريطة . بداية ، إذا تم حذفها ، فإن القيمة الافتراضية صفر ؛ افتراضية خطوة إلى 1 . لعرض قائمة بالأعداد الصحيحة من البداية (شاملة) للتوقف (خاص) ، أو زيادة (أو تناقص) حسب الخطوة ، حصريًا. تجدر الإشارة إلى أن النطاقات التي تتوقف قبل بدء التشغيل تعتبر ذات طول صفري بدلاً من سلبية - إذا كنت تريد نطاقًا سلبيًا ، فاستخدم خطوة سلبية.

var func = function(greeting){ return greeting + ': ' + this.name };
func = _.bind(func, {name: 'moe'}, 'hi');
func();
=> 'hi: moe'

وظيفة (اه ، مهم) وظائف

ربط _.bind(function, object, *arguments)
ربط وظيفة إلى كائن ، وهذا يعني أنه كلما تم استدعاء الدالة ، ستكون قيمة هذا الكائن . اختياريًا ، قم بتمرير الوسيطات إلى الدالة لتعبئتها مسبقًا ، وتُعرف أيضًا باسم التطبيق الجزئي . للتطبيق الجزئي دون ربط السياق ، استخدم partial .

var buttonView = {
  label  : 'underscore',
  onClick: function(){ alert('clicked: ' + this.label); },
  onHover: function(){ console.log('hovering: ' + this.label); }
};
_.bindAll(buttonView, 'onClick', 'onHover');
// When the button is clicked, this.label will have the correct value.
jQuery('#underscore_button').on('click', buttonView.onClick);

bindAll _.bindAll(object, *methodNames)
بربط عدد من الأساليب على الكائن ، المحددة بواسطة methodNames ، ليتم تشغيلها في سياق ذلك الكائن كلما تم استدعائه. سهل جدا للوظائف الملزمة التي ستستخدم كمعاملات الأحداث ، والتي كان من الممكن التذرع بها بخلاف ذلك . مطلوب methodNames .

var subtract = function(a, b) { return b - a; };
sub5 = _.partial(subtract, 5);
sub5(20);
=> 15

// Using a placeholder
subFrom20 = _.partial(subtract, _, 20);
subFrom20(5);
=> 15

جزئي _.partial(function, *arguments)
تطبيق دالة جزئياً عن طريق ملء أي عدد من الحجج الخاصة بها ، دون تغيير هذه القيمة الديناميكية الخاصة بها. ابن عم قريب من bind . يمكنك تمرير _ في قائمة الوسيطات الخاصة بك لتحديد وسيطة لا يجب ملؤها مسبقًا ، ولكنها تترك مفتوحة للعرض في وقت الاستدعاء.

var fibonacci = _.memoize(function(n) {
  return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});

_.memoize(function, [hashFunction])
Memoizes وظيفة معينة عن طريق التخزين المؤقت للنتيجة المحسوبة. مفيدة لتسريع عمليات التشغيل بطيئة التشغيل. إذا تم تمرير وظيفة تجزئة اختيارية ، فسيتم استخدامها لحساب مفتاح التجزئة لتخزين النتيجة ، استنادًا إلى الوسيطات إلى الوظيفة الأصلية. يستخدم التجزئة التجزئة فقط الوسيطة الأولى إلى الدالة memoized كمفتاح. يتوفر ذاكرة التخزين المؤقت للقيم memoized كخاصية التخزين المؤقت على الدالة التي تم إرجاعها.

var log = _.bind(console.log, console);
_.delay(log, 1000, 'logged later');
=> 'logged later' // Appears after one second.

delay _.delay(function, wait, *arguments)
مثل setTimeout ، استدعاء الدالة بعد الانتظار ميلي ثانية. إذا قمت بتمرير الوسيطات الاختيارية ، فسيتم إعادة توجيهها إلى الدالة عند استدعائها.

_.defer(function(){ alert('deferred'); });
// Returns from the function before the alert runs.

تأجيل _.defer(function, *arguments)
Defers استدعاء الدالة حتى يتم مسح مكدس الاستدعاءات الحالي ، على غرار استخدام setTimeout بتأخير 0. من المفيد إجراء عمليات حسابية باهظة الثمن أو عرض HTML في أجزاء بدون حظر مؤشر ترابط واجهة المستخدم من التحديث. إذا قمت بتمرير الوسيطات الاختيارية ، فسيتم إعادة توجيهها إلى الدالة عند استدعائها.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

throttle _.throttle(function, wait, [options])
يقوم بإنشاء وإرجاع نسخة جديدة مخففة من الدالة التي تم تمريرها ، والتي ، عند استدعاءها بشكل متكرر ، ستقوم فعليًا باستدعاء الوظيفة الأصلية في المرة الواحدة في كل ميلي ثانية بالانتظار . مفيد لأحداث تحديد معدل تحدث أسرع مما يمكنك مواكبة.

بشكل افتراضي ، سيقوم الخانق بتنفيذ الوظيفة بمجرد تسميتها للمرة الأولى ، وإذا قمت باستدعائها مرة أخرى أي عدد من المرات خلال فترة الانتظار ، فبمجرد انتهاء هذه الفترة. إذا كنت ترغب في تعطيل ميزة الاتصال المتقدمة ، فمرر {leading: false} ، وإذا كنت تريد تعطيل التنفيذ على الحافة الخلفية ، فمرر
{trailing: false} .

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

إذا كنت تحتاج إلى إلغاء دواسة الوقود المجدولة ، يمكنك استدعاء .cancel () على وظيفة مخنوق.

debounce _.debounce(function, wait, [immediate])
يقوم بإنشاء وإرجاع نسخة deburred جديدة من الدالة التي تم تمريرها والتي سيتم تأجيل التنفيذ حتى بعد انقضاء ميلي ثانية الانتظار منذ آخر مرة تم استدعاؤه. مفيدة لتنفيذ السلوك الذي يجب أن يحدث فقط بعد توقف الإدخال. على سبيل المثال: تقديم معاينة تعليق Markdown ، إعادة حساب تخطيط بعد توقف الإطار يتم تغيير حجمه ، وهكذا.

في نهاية فترة الانتظار ، سيتم استدعاء الدالة مع الوسائط التي تم تمريرها مؤخرًا إلى الدالة debound.

قم بالمرور على الحجة الفورية لتسبب التناقض لتشغيل الدالة على المسافة بين السطور بدلاً من الحافة الخلفية لفترة الانتظار . مفيد في ظروف مثل منع النقر المزدوج غير المقصود على زر "إرسال" من إطلاق مرة ثانية.

var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.

إذا كنت بحاجة إلى إلغاء تسجيل جدولة مجدولة ، فيمكنك الاتصال بـ .cancel () على الدالة التي تم إلغاء صلاحيتها .

مرة واحدة. بمجرد _.once(function)
ينشئ إصدارًا من الدالة التي لا يمكن استدعائها إلا مرة واحدة. لن يكون للمكالمات المتكررة إلى الوظيفة المعدلة أي تأثير ، حيث يتم إرجاع القيمة من المكالمة الأصلية. مفيد في وظائف التهيئة ، بدلاً من الاضطرار إلى تعيين علامة منطقية ثم التحقق من ذلك لاحقًا.

var renderNotes = _.after(notes.length, render);
_.each(notes, function(note) {
  note.asyncSave({success: renderNotes});
});
// renderNotes is run once, after all notes have saved.

بعد _.after(count, function)
ينشئ إصدارًا من الدالة التي سيتم تشغيلها فقط بعد استدعاء أوقات العد . من المفيد تجميع الاستجابات غير المتزامنة ، حيث تريد أن تتأكد من انتهاء جميع المكالمات غير المتزامنة ، قبل المتابعة.

var monthlyMeeting = _.before(3, askForRaise);
monthlyMeeting();
monthlyMeeting();
monthlyMeeting();
// the result of any subsequent calls is the same as the second call

قبل _.before(count, function)
ينشئ إصدارًا من الدالة التي لا يمكن استدعاءها أكثر من مرة. يتم استدعاء نتيجة آخر استدعاء دالة وإرجاعها عند الوصول إلى العدد.

var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
  return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'

wrap _.wrap(function, wrapper)
يلتف الدالة الأولى داخل دالة المجمّع ، تمريرها كالوسيطة الأولى. يسمح ذلك للمجمع بتنفيذ التعليمة البرمجية قبل وبعد تشغيل الوظيفة وضبط الوسيطات وتنفيذها بشكل مشروط.

var isFalsy = _.negate(Boolean);
_.find([-2, -1, 0, 1, 2], isFalsy);
=> 0

negate _.negate(predicate)
تقوم بإرجاع إصدار تالف جديد من دالة المسند .

var greet    = function(name){ return "hi: " + name; };
var exclaim  = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'

يؤلف _.compose(*functions)
إرجاع تكوين قائمة الوظائف ، حيث تستهلك كل دالة قيمة الإرجاع للدالة التالية. في مصطلحات الرياضيات ، ينتج عن تأليف الدوال f () و g () و h () f (g (h ()) .

_.keys({one: 1, two: 2, three: 3});
=> ["one", "two", "three"]

restArguments _.restArguments(function, [startIndex])
تقوم بإرجاع إصدار من الدالة ، عندما يتم استدعاؤه ، يتلقى جميع الوسائط من وإلى ما بعد startIndex المجمعة في صفيف واحد. إذا لم تقم بتمرير startIndex صريح ، فسيتم تحديده من خلال النظر في عدد الوسيطات إلى الوظيفة نفسها. يشبه بناء جملة المعلمات بقية ES6 ل.

function Stooge(name) {
  this.name = name;
}
Stooge.prototype.silly = true;
_.allKeys(new Stooge("Moe"));
=> ["name", "silly"]

وظائف الكائن

مفاتيح _.keys(object)
استرجاع جميع أسماء الخصائص التي يحصى الخاصة الكائن .

_.values({one: 1, two: 2, three: 3});
=> [1, 2, 3]

allKeys _.allKeys(object)
استرجاع جميع أسماء الممتلكات الخاصة والموروثة.

_.mapObject({start: 5, end: 12}, function(val, key) {
  return val + 5;
});
=> {start: 10, end: 17}

قيم _.values(object) القيم _.values(object)
قم بإرجاع كافة قيم خصائص الكائن .

_.pairs({one: 1, two: 2, three: 3});
=> [["one", 1], ["two", 2], ["three", 3]]

mapObject _.mapObject(object, iteratee, [context])
مثل map ، ولكن للأشياء. تحويل قيمة كل الممتلكات بدوره.

_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};

أزواج _.pairs(object) أزواج _.pairs(object)
قم بتحويل كائن إلى قائمة من أزواج [مفتاح وقيمة] . عكس الكائن .

var moe = _.create(Stooge.prototype, {name: "Moe"});

عكس _.invert(object)
إرجاع نسخة من الكائن حيث أصبحت المفاتيح القيم والقيم مفاتيح. لكي يعمل هذا ، يجب أن تكون كل قيم الكائن الخاص بك فريدة من نوعها وترسل السلسلة.

_.functions(_);
=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...

إنشاء _.create(prototype, props)
ينشئ كائنًا جديدًا باستخدام النموذج الأولي المعطى ، مع إرفاق مجموعة من الأدوات الدعائية اختياريًا. في الأساس ، Object.create ، ولكن دون كل من الجاز واصف الخاصية.

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}

وظائف _.functions(object) الاسم المستعار: أساليب
لعرض قائمة مرتبة بأسماء كل طريقة في كائن - وهذا يعني ، اسم كل خاصية دالة للكائن.

_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');
=> {name: 'moe', age: 50}
_.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
  return _.isNumber(value);
});
=> {age: 50}

findKey _.findKey(object, predicate, [context])
على غرار _.findIndex ولكن لمفاتيح في الكائنات. إرجاع المفتاح حيث يمر اختبار الحقيقة الأصلي أو غير محدد . يتم تحويل المسند من خلال iteratee لتسهيل بناء الجملة الاختزال.

تمديد _.extend(destination, *sources)
قم بنسخ كافة الخصائص في كائنات المصدر إلى الكائن الوجهة بشكل ضحل ، وإرجاع الكائن الوجهة . سيتم نسخ أي كائنات أو صفائف متداخلة حسب المرجع ، وليس تكرارًا. في ترتيب ، لذلك سيتجاوز المصدر الأخير خصائص لها نفس الاسم في الوسائط السابقة.

_.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
=> {name: 'moe', age: 50}
_.omit({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
  return _.isNumber(value);
});
=> {name: 'moe', userid: 'moe1'}

expandOwn _.extendOwn(destination, *sources) الاسم المستعار: تعيين
مثل التمديد ، ولكن نسخ الخصائص الخاصة فقط إلى الكائن الوجهة.

اختيار _.pick(object, *keys)
قم بإرجاع نسخة من الكائن ، تمت تصفيته بحيث لا يحتوي إلا على قيم لمفاتيح القائمة البيضاء (أو مجموعة من المفاتيح الصالحة). بدلا من ذلك يقبل المسند تشير إلى مفاتيح لاختيار.

var iceCream = {flavor: "chocolate"};
_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});
=> {flavor: "chocolate", sprinkles: "lots"}

احذف _.omit(object, *keys)
قم بإرجاع نسخة من الكائن ، تمت تصفيتها لإلغاء مفاتيح القائمة السوداء (أو مجموعة من المفاتيح). بدلا من ذلك يقبل المسند تشير إلى أي مفاتيح لإغفال.

_.clone({name: 'moe'});
=> {name: 'moe'};

defaults _.defaults(object, *defaults)
إرجاع الكائن بعد ملء خصائصه غير المحددة مع القيمة الأولى الموجودة في قائمة الكائنات الافتراضية الافتراضية التالية.

_.chain([1,2,3,200])
  .filter(function(num) { return num % 2 == 0; })
  .tap(alert)
  .map(function(num) { return num * num })
  .value();
=> // [2, 200] (alerted)
=> [4, 40000]

clone _.clone(object)
إنشاء نسخة مستنسخة الضحلة من كائن سهل المقدمة. سيتم نسخ أي كائنات أو صفائف متداخلة حسب المرجع ، وليس تكرارًا.

_.has({a: 1, b: 2, c: 3}, "b");
=> true

انقر _.tap(object, interceptor)
يستدعي المعترض مع الكائن ، ثم يقوم بإرجاع الكائن . الغرض الأساسي من هذه الطريقة هو "الاستفادة" من سلسلة الطريقة ، من أجل إجراء عمليات على نتائج وسيطة داخل السلسلة.

var stooge = {name: 'moe'};
'moe' === _.property('name')(stooge);
=> true

has _.has(object, key)
هل يحتوي الكائن على المفتاح المعطى؟ متطابقة مع object.hasOwnProperty (مفتاح) ، ولكن يستخدم إشارة آمنة إلى وظيفة hasOwnProperty ، في حال تم تجاوزه عن طريق الخطأ .

var stooge = {name: 'moe'};
_.propertyOf(stooge)('name');
=> 'moe'

خاصية _.property(path)
تقوم بإرجاع دالة تقوم بإرجاع الخاصية المحددة لأي كائن تم تمريره. يمكن تحديد المسار كمفتاح بسيط ، أو كصفيف من مفاتيح الكائن أو فهرس الصفيف ، لجلب الملكية العميقة.

var ready = _.matcher({selected: true, visible: true});
var readyToGoList = _.filter(list, ready);

propertyOf _.propertyOf(object)
معكوس _.property . يأخذ كائن ويقوم بإرجاع دالة ستقوم بإرجاع قيمة خاصية تم توفيرها.

var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]};
var clone  = {name: 'moe', luckyNumbers: [13, 27, 34]};
stooge == clone;
=> false
_.isEqual(stooge, clone);
=> true

_.matcher(attrs) الاسم المستعار: مباريات
يرجع دالة المسند التي ستخبرك ما إذا كان الكائن الذي تم تمريره يحتوي على جميع خصائص المفتاح / القيمة الموجودة في attrs .

var stooge = {name: 'moe', age: 32};
_.isMatch(stooge, {age: 32});
=> true

isEqual _.isEqual(object, other)
إجراء مقارنة عميقة محسنة بين الجسمين ، لتحديد ما إذا كان ينبغي اعتبارهما متساويين.

_.isEmpty([1, 2, 3]);
=> false
_.isEmpty({});
=> true

isMatch _.isMatch(object, properties)
يخبرك إذا كانت المفاتيح والقيم الموجودة في الخصائص موجودة في الكائن .

_.isElement(jQuery('body')[0]);
=> true

isEmpty _.isEmpty(object)
إرجاع true إذا احتوى كائن لا يحصى على قيم (لا توجد خصائص خاصة به). بالنسبة للسلاسل والكائنات المشابهة للمصفوفة ، يتم فحص ما إذا كانت خاصية الطول هي 0.

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

isElement _.isElement(object)
إرجاع true إذا كان الكائن عنصر DOM.

_.isObject({});
=> true
_.isObject(1);
=> false

isArray _.isArray(object)
إرجاع true إذا كان الكائن عبارة عن مصفوفة.

(function(){ return _.isArguments(arguments); })(1, 2, 3);
=> true
_.isArguments([1,2,3]);
=> false

isObject _.isObject(value)
إرجاع true إذا كانت القيمة هي كائن. لاحظ أن مصفوفات جافا سكريبت ووظائفها هي كائنات ، في حين أن الأوتار والأرقام (العادية) ليست كذلك.

_.isFunction(alert);
=> true

isArguments _.isArguments(object)
إرجاع true إذا كان الكائن عبارة عن كائن وسيطات.

_.isString("moe");
=> true

isFunction _.isFunction(object)
إرجاع true إذا كان الكائن دالة.

_.isNumber(8.4 * 5);
=> true

isString _.isString(object)
إرجاع true إذا كان الكائن عبارة عن سلسلة.

_.isFinite(-101);
=> true

_.isFinite(-Infinity);
=> false

isNumber _.isNumber(object)
إرجاع true إذا كان الكائن رقمًا (بما في ذلك NaN ).

_.isBoolean(null);
=> false

isFinite _.isFinite(object)
Returns true if object is a finite Number.

_.isDate(new Date());
=> true

isBoolean _.isBoolean(object)
Returns true if object is either true or false .

_.isRegExp(/moe/);
=> true

isDate _.isDate(object)
Returns true if object is a Date.

try {
  throw new TypeError("Example");
} catch (o_O) {
  _.isError(o_O);
}
=> true

isRegExp _.isRegExp(object)
Returns true if object is a RegExp.

_.isNaN(NaN);
=> true
isNaN(undefined);
=> true
_.isNaN(undefined);
=> false

isError _.isError(object)
Returns true if object inherits from an Error.

_.isNull(null);
=> true
_.isNull(undefined);
=> false

isSymbol _.isSymbol(object)
Returns true if object is a Symbol .

_.isUndefined(window.missingVariable);
=> true

isMap _.isMap(object)
Returns true if object is a Map .

var underscore = _.noConflict();

isWeakMap _.isWeakMap(object)
Returns true if object is a WeakMap .

var stooge = {name: 'moe'};
stooge === _.identity(stooge);
=> true

isSet _.isSet(object)
Returns true if object is a Set .

var stooge = {name: 'moe'};
stooge === _.constant(stooge)();
=> true

isWeakSet _.isWeakSet(object)
Returns true if object is a WeakSet .

obj.initialize = _.noop;

isNaN _.isNaN(object)
Returns true if object is NaN .
Note: this is not the same as the native isNaN function, which will also return true for many other not-number values, such as undefined .

_(3).times(function(n){ genie.grantWishNumber(n); });

isNull _.isNull(object)
Returns true if the value of object is null .

_.random(0, 100);
=> 42

isUndefined _.isUndefined(value)
Returns true if value is undefined .

_.mixin({
  capitalize: function(string) {
    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
  }
});
_("fabio").capitalize();
=> "Fabio"

Utility Functions

noConflict _.noConflict()
Give control of the _ variable back to its previous owner. Returns a reference to the Underscore object.

// No value
_.iteratee();
=> _.identity()

// Function
_.iteratee(function(n) { return n * 2; });
=> function(n) { return n * 2; }

// Object
_.iteratee({firstName: 'Chelsea'});
=> _.matcher({firstName: 'Chelsea'});

// Anything else
_.iteratee('firstName');
=> _.property('firstName');

identity _.identity(value)
Returns the same value that is used as the argument. In math: f(x) = x
This function looks useless, but is used throughout Underscore as a default iteratee.

_.uniqueId('contact_');
=> 'contact_104'

constant _.constant(value)
Creates a function that returns the same value that is used as the argument of _.constant .

_.escape('Curly, Larry & Moe');
=> "Curly, Larry &amp; Moe"

noop _.noop()
Returns undefined irrespective of the arguments passed to it. Useful as the default for optional callback arguments.

_.unescape('Curly, Larry &amp; Moe');
=> "Curly, Larry & Moe"

times _.times(n, iteratee, [context])
Invokes the given iteratee function n times. Each invocation of iteratee is called with an index argument. Produces an array of the returned values.
Note: this example uses the object-oriented syntax .

var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
_.result(object, 'cheese');
=> "crumpets"
_.result(object, 'stuff');
=> "nonsense"
_.result(object, 'meat', 'ham');
=> "ham"

random _.random(min, max)
Returns a random integer between min and max , inclusive. If you only pass one argument, it will return a number between 0 and that number.

_.now();
=> 1392066795351

mixin _.mixin(object)
Allows you to extend Underscore with your own utility functions. Pass a hash of {name: function} definitions to have your functions added to the Underscore object, as well as the OOP wrapper. Returns the Underscore object to facilitate chaining.

var compiled = _.template("hello: <%= name %>");
compiled({name: 'moe'});
=> "hello: moe"

var template = _.template("<b><%- value %></b>");
template({value: '<script>'});
=> "<b>&lt;script&gt;</b>"

iteratee _.iteratee(value, [context])
Generates a callback that can be applied to each element in a collection. _.iteratee supports a number of shorthand syntaxes for common callback use cases. Depending upon value 's type, _.iteratee will return:

var compiled = _.template("<% print('Hello ' + epithet); %>");
compiled({epithet: "stooge"});
=> "Hello stooge"

The following Underscore methods transform their predicates through _.iteratee : countBy , every , filter , find , findIndex , findKey , findLastIndex , groupBy , indexBy , map , mapObject , max , min , partition , reject , some , sortBy , sortedIndex , and uniq

You may overwrite _.iteratee with your own custom function, if you want additional or different shorthand syntaxes:

_.templateSettings = {
  interpolate: /\{\{(.+?)\}\}/g
};

var template = _.template("Hello {{ name }}!");
template({name: "Mustache"});
=> "Hello Mustache!"

uniqueId _.uniqueId([prefix])
Generate a globally-unique id for client-side models or DOM elements that need one. If prefix is passed, the id will be appended to it.

_.template("Using 'with': ", {variable: 'data'})({answer: 'no'});
=> "Using 'with': no"

escape _.escape(string)
Escapes a string for insertion into HTML, replacing & , < , > , " , ` , and ' characters.

<script>
  JST.project = ;
</script>

unescape _.unescape(string)
The opposite of escape , replaces &amp; , &lt; , &gt; , &quot; , &#96; and &#x27; with their unescaped counterparts.

_.map([1, 2, 3], function(n){ return n * 2; });
_([1, 2, 3]).map(function(n){ return n * 2; });

result _.result(object, property, [defaultValue])
If the value of the named property is a function then invoke it with the object as context; otherwise, return it. If a default value is provided and the property doesn't exist or is undefined then the default will be returned. If defaultValue is a function its result will be returned.

var lyrics = [
  {line: 1, words: "I'm a lumberjack and I'm okay"},
  {line: 2, words: "I sleep all night and I work all day"},
  {line: 3, words: "He's a lumberjack and he's okay"},
  {line: 4, words: "He sleeps all night and he works all day"}
];

_.chain(lyrics)
  .map(function(line) { return line.words.split(' '); })
  .flatten()
  .reduce(function(counts, word) {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
  }, {})
  .value();

=> {lumberjack: 2, all: 4, night: 2 ... }

now _.now()
Returns an integer timestamp for the current time, using the fastest method available in the runtime. Useful for implementing timing/animation functions.

var stooges = [{name: 'curly', age: 25}, {name: 'moe', age: 21}, {name: 'larry', age: 23}];
var youngest = _.chain(stooges)
  .sortBy(function(stooge){ return stooge.age; })
  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
  .first()
  .value();
=> "moe is 21"

template _.template(templateString, [settings])
Compiles JavaScript templates into functions that can be evaluated for rendering. Useful for rendering complicated bits of HTML from JSON data sources. Template functions can both interpolate values, using <%= … %> , as well as execute arbitrary JavaScript code, with <% … %> . If you wish to interpolate a value, and have it be HTML-escaped, use <%- … %> . When you evaluate a template function, pass in a data object that has properties corresponding to the template's free variables. The settings argument should be a hash containing any _.templateSettings that should be overridden.

_.chain([1, 2, 3]).reverse().value();
=> [3, 2, 1]

You can also use print from within JavaScript code. This is sometimes more convenient than using <%= ... %> .

var compiled = _.template("<% print('Hello ' + epithet); %>");
compiled({epithet: "stooge"});
=> "Hello stooge" 

If ERB-style delimiters aren't your cup of tea, you can change Underscore's template settings to use different symbols to set off interpolated code. Define an interpolate regex to match expressions that should be interpolated verbatim, an escape regex to match expressions that should be inserted after being HTML-escaped, and an evaluate regex to match expressions that should be evaluated without insertion into the resulting string. You may define or omit any combination of the three. For example, to perform Mustache.js -style templating:

_.templateSettings = {
  interpolate: /\{\{(.+?)\}\}/g
 }؛

var template = _.template("Hello {{ name }}!");
template({name: "Mustache"});
=> "Hello Mustache!" 

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name with the variable setting. This can significantly improve the speed at which a template is able to render.

_.template("Using 'with': ", {variable: 'data'})({answer: 'no'});
=> "Using 'with': no" 

Precompiling your templates can be a big help when debugging errors you can't reproduce. This is because precompiled templates can provide line numbers and a stack trace, something that is not possible when compiling templates on the client. The source property is available on the compiled template function for easy precompilation.

 <script>
  JST.project = ;
</script> 

Object-Oriented Style

You can use Underscore in either an object-oriented or a functional style, depending on your preference. The following two lines of code are identical ways to double a list of numbers.

_.map([1, 2, 3], function(n){ return n * 2; });
_([1, 2, 3]).map(function(n){ return n * 2; }); 

Chaining

Calling chain will cause all future method calls to return wrapped objects. When you've finished the computation, call value to retrieve the final value. Here's an example of chaining together a map/flatten/reduce , in order to get the word count of every word in a song.

var lyrics = [
  {line: 1, words: "I'm a lumberjack and I'm okay"},
  {line: 2, words: "I sleep all night and I work all day"},
  {line: 3, words: "He's a lumberjack and he's okay"},
  {line: 4, words: "He sleeps all night and he works all day"}
];

_.chain(lyrics)
  .map(function(line) { return line.words.split(' '); })
  .flatten()
  .reduce(function(counts, word) {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
  }, {})
  .value();

=> {lumberjack: 2, all: 4, night: 2 ... } 

In addition, the Array prototype's methods are proxied through the chained Underscore object, so you can slip a reverse or a push into your chain, and continue to modify the array.

chain _.chain(obj)
Returns a wrapped object. Calling methods on this object will continue to return wrapped objects until value is called.

var stooges = [{name: 'curly', age: 25}, {name: 'moe', age: 21}, {name: 'larry', age: 23}];
var youngest = _.chain(stooges)
  .sortBy(function(stooge){ return stooge.age; })
  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
  .first()
  .value();
=> "moe is 21"

value _.chain(obj).value()
Extracts the value of a wrapped object.

_.chain([1, 2, 3]).reverse().value();
=> [3, 2, 1]

原文