寫這篇文章的初衷是來源於JS基礎問題-類型判斷,僅看成鞏固下知識。javascript
咱們常說學習一個知識點要學會延伸思考,點畫線,線繪面,造成本身的知識體系。java
一個小小的類型判斷其實也能夠拓展出不少知識點。node
計算機程序的運行須要對值進行操做,而在編程語言中,可以表示並操做的值的類型稱爲數據類型。git
編程語言最基本的特徵就是支持多種數據類型。github
JS有兩類數據類型:原始類型(primitive type)和對象類型(object type)。web
指的注意的是null確實屬於基本類型,由於有時它容易被誤認爲是對象類型。編程
typeof null === 'object' // 這應該算語言的一個bug
複製代碼
對typeof null 感興趣的能夠看這個討論。segmentfault
實際上JS還有不少特殊的對象子類型,咱們能夠稱之爲複雜基本類型。數組
好比說:編程語言
這裏又會有一個思考:基本數據類型與引用數據類型的區別,常見於函數的入參。
基本數據類型它是按值訪問。
const a = 10;
let b = a;
b = 20;
複製代碼
引用類型數據在棧內存中保存的其實是對象在堆內存中的引用地址(「指針」)。經過這個引用地址能夠快速查找到保存中堆內存中的對象。
const obj1 = new Object();
const obj2 = obj1;
obj2.name = "我有名字了";
複製代碼
由於JS自帶的類型判斷方法不能知足咱們的需求。
console.log(typeof '11') // string
console.log(typeof 11) // number
console.log(typeof true) // boolean
console.log(typeof undefined) // undefined
console.log(typeof null) // object, 算語言的bug,實際上該方式並不能判斷出null
console.log(typeof Symbol('test')) // symbol
console.log(typeof /.?/gi) // object
console.log(typeof []) // object
console.log(typeof new Date()) // object
複製代碼
下面幾個簡單題目測試下是否掌握了typeof用法。
var y = 1, x = y = typeof x;
console.log(x) // undefined
複製代碼
var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();//"undefined"
})(foo.bar);
複製代碼
instanceof 主要的做用就是判斷一個實例是不是其父類型或者祖先類型的實例。它是基於原型鏈的查找。
let person = function () {
}
let nicole = new person()
nicole instanceof person // true
複製代碼
咱們看下面這個demo你就知道爲何有些場景下不能用instanceof來判斷數據類型了。
const arr = []
const obj = {}
const func = function() {}
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true
console.log(obj instanceof Object) // true
console.log(func instanceof Object) // true
複製代碼
下面咱們看看lodash是如何進行JS類型判斷的。
/** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * isObjectLike({}) * // => true * * isObjectLike([1, 2, 3]) * // => true * * isObjectLike(Function) * // => false * * isObjectLike(null) * // => false */
function isObjectLike(value) {
return typeof value === 'object' && value !== null
}
export default isObjectLike
複製代碼
const toString = Object.prototype.toString
// Gets the `toStringTag` of `value`.
// 這個方法很重要
function getTag(value) {
if (value == null) {
return value === undefined ? '[object Undefined]' : '[object Null]'
}
return toString.call(value)
}
function isArguments(value) {
return isObjectLike(value) && getTag(value) == '[object Arguments]'
}
複製代碼
// 檢查 value 是否爲有效的類數組長度。
function isLength(value) {
return typeof value === 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER
}
function isArrayLike(value) {
return value != null && typeof value !== 'function' && isLength(value.length)
}
複製代碼
// isBoolean(null) false
function isBoolean(value) {
return value === true || value === false ||
(isObjectLike(value) && getTag(value) == '[object Boolean]')
}
複製代碼
這裏就不詳細列舉,感興趣強烈推薦閱讀lodash源碼
ps: 感興趣的關注個人公衆號。