检查value
is anError
,EvalError
,RangeError
,ReferenceError
,SyntaxError
,TypeError
, orURIError
object.
function isError(value) { if (!isObjectLike(value)) { return false; } return (objectToString.call(value) == errorTag) || (typeof value.message == 'string' && typeof value.name == 'string'); }
objectToString
之后是一个'[object Error]'
value.message
和value.name
都应该是字符串检查value是不是一个有限数值
/** 检测node中的自由变量global. global在nodejs中的全局变量,有点相似在浏览器中的windows */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; /**检测self变量*/ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** 用做保存全局对象的引用 */ var root = freeGlobal || freeSelf || Function('return this')(); var nativeIsFinite = root.isFinite; function isFinite(value) { return typeof value == 'number' && nativeIsFinite(value); }
number
类型window.isFinite
来判断是不是有限制。window
在代码中没看到, Function('return this')();
在浏览器里运行返回的是window
javascript
linkjava
https://segmentfault.com/a/11...node
将value转换位一个数字。
https://segmentfault.com/a/11...
检查value是不是一个整数
function isInteger(value) { return typeof value == 'number' && value == toInteger(value); }
固然用到了一个工具方法chrome
/**将value转换成一个整数*/ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; }
判断是否是map类型。segmentfault
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; var nodeUtil = (function() { try { return freeProcess && freeProcess.binding('util'); } catch (e) {} }()); // 若是是node环境,保存了util的引用 var nodeIsMap = nodeUtil && nodeUtil.isMap; // util.isMap ,nodejs 判断map类型的方法 function baseIsMap(value) { return isObjectLike(value) && getTag(value) == mapTag; }// 是对象,在判断toString返回的字符串符合mapTag
判断是不是
NaN
在js中,NaN是惟一个一个不等于本身的值。windows
function isNaN(value) { // An `NaN` primitive is the only value that is not equal to itself. NaN是惟一一个本身不等于本身的value return isNumber(value) && value != +value; }
该方法实际上是基于Number.isNaN
.而不是(window || global).isNaN
方法,window.isNaN(undefined)
返回true。promise
检查 value 是不是一个原生函数。
注意: 这种方法不能可靠地检测在core-js包中存在的本地函数,由于 core-js 规避这种检测。尽管有多个请求,core-js 维护者已经明确表态:任何试图修复检测将受阻。这样一来,咱们别无选择,只能抛出一个错误。不幸的是,这也影响其余的包,好比依赖于 core-js的babel-polyfill。浏览器
检查 value 是不是 null 或者 undefined。
function isNil(){ return value == null }
判断value
是否等于null
function isNull(value){ return value === null }
判断value是
Number
类型
考虑到其它几种判断类型的方法,此处判断Numberl类型的时候仍然要考虑到new Numnber()这种类型安全
function isNumber(value){ return typeof value == 'number' || (isObjectLike(value)) && objectToString.call(value) == numberTag) }
判断value是
RegExp
类型
var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
baseUnary实际上是个很简单的方法,接收一个函数,只让它接收一个参数。babel
function baseUnary(func) { return function(value) { return func(value); }; } /** 也就是说,对于baseUnary返回的方法,不论传入多少个参数,它只接收第一个参数*/ function consoleArgs(){ console.log(...args) } var testFn = baseUnary(consoleArgs); testFn(1,2,3,4,5,6) // => [1]
至于说到的nodeIsRegExp
即是util.isRegExp
,是nodejs中的方法。
继续说baseIsRegExp
便没有任何神秘感了。
function baseIsRegExp(value) { return isObject(value) && objectToString.call(value) == regexpTag; }
Checks if value
is a safe integer. An integer is safe if it's an IEEE-754 double precision number which isn't the result of a rounded unsafe integer.
value是不是一个安全整数。一个安全整数应该符合IEEE-754的非双精度浮点数
Note: This method is based onNumber.isSafeInteger
.
var MAX_SAFE_INTEGER = 9007199254740991, function isSafeInteger(value) { return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; }
value是一个整数类型,而且在正负-MAX_SAFE_INTEGER之间
value是不是一个set对象。
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
var nodeIsSet = nodeUtil && nodeUtil.isSet;
判断node环境中的isSet
方法存在。
浏览器的环境中,执行的是baseIsSet
.
function baseIsSet(value) { return isObjectLike(value) && getTag(value) == setTag; }
走到这,getTag
的方法即是返回对应的value的tag
.但是为何不用Object.prototype.toString了呢
是由于,IE11等特殊状况作了兼容处理。
date views,maps,sets,weak maps
// Fallback for data views, maps, sets, and weak maps in IE 11, // for data views in Edge < 14, and promises in Node.js. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || (Map && getTag(new Map) != mapTag) || (Promise && getTag(Promise.resolve()) != promiseTag) || (Set && getTag(new Set) != setTag) || (WeakMap && getTag(new WeakMap) != weakMapTag)) { getTag = function(value) { var result = objectToString.call(value), Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : undefined; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; }
Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : undefined; // - var funcToString = Function.prototype.toString function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; }
若是是个Map类型的value,经过toSource
处理后,在chrome中返回"function Map() { [native code] }"。在上边的几种状况下,不能直接用Object.prototype.toString.call
调用。才有了针对几种特殊状况,toSource
处理后,返回修正后的tag。
检查value是不是字符串
function isString(value) { return typeof value == 'string' || (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); }
检查是不是Symbol类型
function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && objectToString.call(value) == symbolTag); }
判断是不是typedArray
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; function baseIsTypedArray(value) { return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; }
下边为typedArrayTabs的类型集合。
var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; //- 之上的tag都为true,其它为false typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
检查是不是undefined
function isUndefined(value) { return value === undefined; }
检查 value 是不是 WeakMap 对象。
function isWeakMap(value) { return isObjectLike(value) && getTag(value) == weakMapTag; }
参照isSet
检查 value 是不是 WeakSet 对象。
function isWeakSet(value) { return isObjectLike(value) && objectToString.call(value) == weakSetTag; }
参照isSet