diff --git a/lib/sys.js b/lib/sys.js index 28ec6ff740..3dfcdee77a 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -65,7 +65,7 @@ exports.inspect = function (obj, showHidden, depth) { // Functions without properties can be shortcutted. if (typeof value === 'function' && keys.length === 0) { - if (value instanceof RegExp) { + if (isRegExp(value)) { return '' + value; } else { return '[Function]'; @@ -73,13 +73,13 @@ exports.inspect = function (obj, showHidden, depth) { } // Dates without properties can be shortcutted - if (value instanceof Date && keys.length === 0) { + if (isDate(value) && keys.length === 0) { return value.toUTCString(); } var base, type, braces; // Determine the object type - if (value instanceof Array) { + if (isArray(value)) { type = 'Array'; braces = ["[", "]"]; } else { @@ -89,13 +89,13 @@ exports.inspect = function (obj, showHidden, depth) { // Make functions say that they are functions if (typeof value === 'function') { - base = (value instanceof RegExp) ? ' ' + value : ' [Function]'; + base = (isRegExp(value)) ? ' ' + value : ' [Function]'; } else { base = ""; } // Make dates with properties first say the date - if (value instanceof Date) { + if (isDate(value)) { base = ' ' + value.toUTCString(); } @@ -106,7 +106,7 @@ exports.inspect = function (obj, showHidden, depth) { } if (recurseTimes < 0) { - if (value instanceof RegExp) { + if (isRegExp(value)) { return '' + value; } else { return "[Object]"; @@ -140,7 +140,7 @@ exports.inspect = function (obj, showHidden, depth) { str = format(value[key], recurseTimes - 1); } if (str.indexOf('\n') > -1) { - if (value instanceof Array) { + if (isArray(value)) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); @@ -191,6 +191,29 @@ exports.inspect = function (obj, showHidden, depth) { } return format(obj, (typeof depth === 'undefined' ? 2 : depth)); }; +function isArray (ar) { + return ar instanceof Array + || Array.isArray(ar) + || (ar && ar !== Object.prototype && isArray(ar.__proto__)); +} +function isRegExp (re) { + var s = ""+re; + return re instanceof RegExp // easy case + || typeof(re) === "function" // duck-type for context-switching evalcx case + && re.constructor.name === "RegExp" + && re.compile + && re.test + && re.exec + && s.charAt(0) === "/" + && s.substr(-1) === "/"; +} +function isDate (d) { + if (d instanceof Date) return true; + if (typeof d !== "object") return false; + var properties = Date.prototype && Object.getOwnPropertyNames(Date.prototype); + var proto = d.__proto__ && Object.getOwnPropertyNames(d.__proto__); + return JSON.stringify(proto) === JSON.stringify(properties); +} var pWarning;