UNPKG

sugar

Version:

A Javascript utility library for working with native objects.

138 lines (113 loc) 4.19 kB
'use strict'; var NATIVE_TYPES = require('./NATIVE_TYPES'), forEach = require('../internal/forEach'), isClass = require('../internal/isClass'), spaceSplit = require('../internal/spaceSplit'), isPlainObject = require('../internal/isPlainObject'); var isSerializable, isBoolean, isNumber, isString, isDate, isRegExp, isFunction, isArray, isSet, isMap, isError; function buildClassChecks() { var knownTypes = {}; function addCoreTypes() { var names = spaceSplit(NATIVE_TYPES); isBoolean = buildPrimitiveClassCheck(names[0]); isNumber = buildPrimitiveClassCheck(names[1]); isString = buildPrimitiveClassCheck(names[2]); isDate = buildClassCheck(names[3]); isRegExp = buildClassCheck(names[4]); // Wanted to enhance performance here by using simply "typeof" // but Firefox has two major issues that make this impossible, // one fixed, the other not, so perform a full class check here. // // 1. Regexes can be typeof "function" in FF < 3 // https://bugzilla.mozilla.org/show_bug.cgi?id=61911 (fixed) // // 2. HTMLEmbedElement and HTMLObjectElement are be typeof "function" // https://bugzilla.mozilla.org/show_bug.cgi?id=268945 (won't fix) isFunction = buildClassCheck(names[5]); // istanbul ignore next isArray = Array.isArray || buildClassCheck(names[6]); isError = buildClassCheck(names[7]); isSet = buildClassCheck(names[8], typeof Set !== 'undefined' && Set); isMap = buildClassCheck(names[9], typeof Map !== 'undefined' && Map); // Add core types as known so that they can be checked by value below, // notably excluding Functions and adding Arguments and Error. addKnownType('Arguments'); addKnownType(names[0]); addKnownType(names[1]); addKnownType(names[2]); addKnownType(names[3]); addKnownType(names[4]); addKnownType(names[6]); } function addArrayTypes() { var types = 'Int8 Uint8 Uint8Clamped Int16 Uint16 Int32 Uint32 Float32 Float64'; forEach(spaceSplit(types), function(str) { addKnownType(str + 'Array'); }); } function addKnownType(className) { var str = '[object '+ className +']'; knownTypes[str] = true; } function isKnownType(className) { return knownTypes[className]; } function buildClassCheck(className, globalObject) { // istanbul ignore if if (globalObject && isClass(new globalObject, 'Object')) { return getConstructorClassCheck(globalObject); } else { return getToStringClassCheck(className); } } // Map and Set may be [object Object] in certain IE environments. // In this case we need to perform a check using the constructor // instead of Object.prototype.toString. // istanbul ignore next function getConstructorClassCheck(obj) { var ctorStr = String(obj); return function(obj) { return String(obj.constructor) === ctorStr; }; } function getToStringClassCheck(className) { return function(obj, str) { // perf: Returning up front on instanceof appears to be slower. return isClass(obj, className, str); }; } function buildPrimitiveClassCheck(className) { var type = className.toLowerCase(); return function(obj) { var t = typeof obj; return t === type || t === 'object' && isClass(obj, className); }; } addCoreTypes(); addArrayTypes(); isSerializable = function(obj, className) { // Only known objects can be serialized. This notably excludes functions, // host objects, Symbols (which are matched by reference), and instances // of classes. The latter can arguably be matched by value, but // distinguishing between these and host objects -- which should never be // compared by value -- is very tricky so not dealing with it here. return isKnownType(className) || isPlainObject(obj, className); }; } buildClassChecks(); module.exports = { isSerializable: isSerializable, isBoolean: isBoolean, isNumber: isNumber, isString: isString, isDate: isDate, isRegExp: isRegExp, isFunction: isFunction, isArray: isArray, isSet: isSet, isMap: isMap, isError: isError };