檢查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