From 66dc6c2ac1b4c4d74ad2f4d044cba0d056549957 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sun, 6 Dec 2009 22:48:40 -0500 Subject: [PATCH] shrunk down all of the 'is' functions into a single generation, added isRegExp, added a regexp equality test to isEqual, after grayrest's patch --- test/objects.js | 1 + test/utility.js | 2 +- underscore.js | 50 ++++++++++++++++++------------------------------- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/test/objects.js b/test/objects.js index 355b2937b..a6b63e0d4 100644 --- a/test/objects.js +++ b/test/objects.js @@ -37,6 +37,7 @@ $(document).ready(function() { ok(!_.isEqual(5, NaN), '5 is not equal to NaN'); ok(_.isEqual(NaN, NaN), 'NaN is equal to NaN'); ok(_.isEqual(new Date(100), new Date(100)), 'identical dates are equal'); + ok(_.isEqual((/hello/ig), (/hello/ig)), 'identical regexes are equal'); }); test("objects: isEmpty", function() { diff --git a/test/utility.js b/test/utility.js index 0d02b3041..99aa7cab2 100644 --- a/test/utility.js +++ b/test/utility.js @@ -35,7 +35,7 @@ $(document).ready(function() { "compose","defer", "delay", "detect", "each", "every", "extend", "filter", "first", "flatten", "foldl", "foldr", "forEach", "functions", "head", "identity", "include", "indexOf", "inject", "intersect", "invoke", "isArray", "isDate", "isElement", "isEmpty", "isEqual", - "isFunction", "isNaN", "isNull", "isNumber", "isString", "isUndefined", "keys", "last", "lastIndexOf", "map", "max", + "isFunction", "isNaN", "isNull", "isNumber", "isRegExp", "isString", "isUndefined", "keys", "last", "lastIndexOf", "map", "max", "methods", "min", "pluck", "range", "reduce", "reduceRight", "reject", "rest", "select", "size", "some", "sortBy", "sortedIndex", "tail", "template", "toArray", "uniq", "uniqueId", "values", "without", "wrap", "zip"]; diff --git a/underscore.js b/underscore.js index 49d5b08c1..b734430cb 100644 --- a/underscore.js +++ b/underscore.js @@ -30,9 +30,6 @@ // Export the Underscore object for CommonJS. if (typeof exports !== 'undefined') exports._ = _; - // Maintain a reference to the Object prototype for quick access. - var objPro = Object.prototype; - // Current version. _.VERSION = '0.4.7'; @@ -395,7 +392,7 @@ _.keys = function(obj) { if(_.isArray(obj)) return _.range(0, obj.length); var keys = []; - for (var key in obj) if (objPro.hasOwnProperty.call(obj, key)) keys.push(key); + for (var key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) keys.push(key); return keys; }; @@ -425,16 +422,22 @@ if (atype != btype) return false; // Basic equality test (watch out for coercions). if (a == b) return true; - // Check dates' integer values. - if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); // One of them implements an isEqual()? if (a.isEqual) return a.isEqual(b); + // Check dates' integer values. + if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); // Both are NaN? if (_.isNaN(a) && _.isNaN(b)) return true; + // Compare regular expressions. + if (_.isRegExp(a) && _.isRegExp(b)) + return a.source === b.source && + a.global === b.global && + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; // If a is not an object by this point, we can't handle it. if (atype !== 'object') return false; // Check for different array lengths before comparing contents. - if (!_.isUndefined(a.length) && a.length !== b.length) return false; + if (a.length && (a.length !== b.length)) return false; // Nothing else worked, deep compare the contents. var aKeys = _.keys(a), bKeys = _.keys(b); // Different object sizes? @@ -454,31 +457,6 @@ return !!(obj && obj.nodeType == 1); }; - // Is a given value a real Array? - _.isArray = function(obj) { - return objPro.toString.call(obj) == '[object Array]'; - }; - - // Is a given value a Function? - _.isFunction = function(obj) { - return objPro.toString.call(obj) == '[object Function]'; - }; - - // Is a given value a String? - _.isString = function(obj) { - return objPro.toString.call(obj) == '[object String]'; - }; - - // Is a given value a Number? - _.isNumber = function(obj) { - return objPro.toString.call(obj) == '[object Number]'; - }; - - // Is a given value a Date? - _.isDate = function(obj) { - return objPro.toString.call(obj) == '[object Date]'; - }; - // Is the given value NaN -- this one is interesting. NaN != NaN, and // isNaN(undefined) == true, so we make sure it's a number first. _.isNaN = function(obj) { @@ -495,6 +473,14 @@ return typeof obj == 'undefined'; }; + // Define the isArray, isDate, isFunction, isNumber, isRegExp, and + // isString functions based on their toString identifiers. + _.each(['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'], function(type) { + _['is' + type] = function(obj) { + return Object.prototype.toString.call(obj) == '[object ' + type + ']'; + }; + }); + /* -------------------------- Utility Functions: -------------------------- */ // Run Underscore.js in noConflict mode, returning the '_' variable to its