adding OO-style object wrapping (thanks macournoyer) -- now you can to _(array).each();

This commit is contained in:
Jeremy Ashkenas
2009-11-07 12:39:59 -05:00
parent 51298c78ca
commit 4f0afda61c
6 changed files with 50 additions and 9 deletions

View File

@@ -4,6 +4,7 @@ $(document).ready(function() {
test("arrays: first", function() {
equals(_.first([1,2,3]), 1, 'can pull out the first element of an array');
equals(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
});
test("arrays: last", function() {
@@ -35,6 +36,7 @@ $(document).ready(function() {
test("arrays: intersect", function() {
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
equals(_.intersect(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays');
equals(_(stooges).intersect(leaders).join(''), 'moe', 'can perform an OO-style intersection');
});
test('arrays: zip', function() {

View File

@@ -32,7 +32,7 @@ $(document).ready(function() {
answer = null;
_.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
ok(answer, 'can reference the original collection from inside the iterator');
ok(answer, 'can reference the original collection from inside the iterator');
});
test('collections: map', function() {
@@ -41,6 +41,9 @@ $(document).ready(function() {
var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3});
equals(tripled.join(', '), '3, 6, 9', 'tripled numbers with context');
var doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
equals(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers');
});
test('collections: reduce', function() {
@@ -53,6 +56,9 @@ $(document).ready(function() {
sum = _.inject([1, 2, 3], 0, function(sum, num){ return sum + num; });
equals(sum, 6, 'aliased as "inject"');
sum = _([1, 2, 3]).reduce(0, function(sum, num){ return sum + num; });
equals(sum, 6, 'OO-style reduce');
});
test('collections: reduceRight', function() {
@@ -100,6 +106,7 @@ $(document).ready(function() {
ok(_.include([1,2,3], 2), 'two is in the array');
ok(!_.include([1,3,9], 2), 'two is not in the array');
ok(_.include({moe:1, larry:3, curly:9}, 3), '_.include on objects checks their values');
ok(_([1,2,3]).include(2), 'OO-style include');
});
test('collections: invoke', function() {

View File

@@ -8,12 +8,15 @@ $(document).ready(function() {
var bound = _.bind(func, context);
equals(bound(), 'name: moe', 'can bind a function to a context');
var func = function(salutation, name) { return salutation + ': ' + name; };
bound = _(func).bind(context);
equals(bound(), 'name: moe', 'can do OO-style binding');
func = function(salutation, name) { return salutation + ': ' + name; };
func = _.bind(func, this, 'hello');
equals(func('moe'), 'hello: moe', 'the function was partially applied in advance');
func = _.bind(func, this, 'curly');
equals(func(), 'hello: curly', 'the function was completely applied in advance');
var func = _.bind(func, this, 'curly');
equals(func(), 'hello: curly', 'the function was completely applied in advance');
});
test("functions: bindAll", function() {

View File

@@ -33,6 +33,7 @@ $(document).ready(function() {
var clone = {name : 'moe', lucky : [13, 27, 34]};
ok(moe != clone, 'basic equality between objects is false');
ok(_.isEqual(moe, clone), 'deep equality is true');
ok(_(moe).isEqual(clone), 'OO-style deep equality works');
});
test("objects: isElement", function() {

View File

@@ -11,6 +11,12 @@
return timesTwo;
});
JSLitmus.test('_(list).each()', function() {
var timesTwo = [];
_(numbers).each(function(num){ timesTwo.push(num * 2); });
return timesTwo;
});
JSLitmus.test('_.map()', function() {
return _.map(objects, function(obj){ return obj.num; });
});

View File

@@ -16,15 +16,20 @@
// Save the previous value of the "_" variable.
var previousUnderscore = root._;
// Create a safe reference to the Underscore object for the functions below.
var _ = root._ = {};
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions.
var wrapper = function(obj) { this.wrapped = obj; };
// Create a safe reference to the Underscore object for reference below.
var _ = root._ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for CommonJS.
if (typeof exports !== 'undefined') _ = exports;
// Current version.
_.VERSION = '0.3.3';
_.VERSION = '0.3.3';
/*------------------------ Collection Functions: ---------------------------*/
// The cornerstone, an each implementation.
@@ -447,6 +452,13 @@
return prefix ? prefix + id : id;
};
// Return a sorted list of the function names available in Underscore.
_.functions = function() {
var functions = [];
for (var key in _) if (Object.prototype.hasOwnProperty.call(_, key)) functions.push(key);
return _.without(functions, 'VERSION', 'prototype', 'noConflict');
};
// JavaScript templating a-la ERB, pilfered from John Resig's
// "Secrets of the JavaScript Ninja", page 83.
_.template = function(str, data) {
@@ -472,6 +484,16 @@
_.foldr = _.reduceRight;
_.filter = _.select;
_.every = _.all;
_.some = _.any;
_.some = _.any;
_.methods = _.functions;
/*------------------- Add all Functions to the Wrapper: --------------------*/
_.each(_.functions(), function(name) {
wrapper.prototype[name] = function() {
Array.prototype.unshift.call(arguments, this.wrapped);
return _[name].apply(_, arguments);
};
});
})();