2. JS数据类型检测_封装一个数据类型检测的方法库

JS中的数据类型分为三大类:

简单类型
引用数据类型
symbol 创建唯一值

数据类型检测四种方式

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call()

typeof

语法:typeof [value]

基于 typeof检测结果

1.首先是一个字符串;
2.字符串中包含对应的类型;
3.字符串中包含对应的数据类型,例如:"number"、"object"、"undefined"、"function"、"boolean"、"symbol"...
4.因为typeof检测的结果都是字符串,所以只要两个及两个以上同时检测,最后结果必然是“string”;

typeof 1 // "number"
typeof NaN // "number"
typeof '' // "string"
typeof "24" // "string"
typeof true // "boolean"
typeof false // "boolean"
typeof undefined // "undefined"
typeof null // "object" // null特殊情况,相当于空指针对象;
function fn () {} // typeof fn => "function"
typeof typeof typeof [] // =>typeof [] => "object" =>typeof "object" => "string"

@优势
使用方便,所以在真实项目中,我们也会大量应用它来检测,尤其是在检测基本类型值(除null之外)和函数类型值的时候,它还是很方便的

@局限性
1、 typeof null => “object” , 但是null 并不是对象,是空指针对象;
2、无法细分当前值是普通对象还是数组对象等, 如: 是正则 还是数组
因为只要是对象数据类型,返回的结果都是"object";

instanceof

语法:[实例] instanceof [类]

  • 用来检测某个实例是否属于这个类(对象类型)
  • 属于返回TRUE,不属于返回FALSE;

@局限性:

1、不能处理基本数据类型值
2、只要在当前实例的原型链(proto)中出现过的类,检测结果都是true(用户可能会手动修改原型链的指向:example.proto 或者 在类的继承中 等情况)

arr instanceof Object  // 都是true

// 如果是基本数据类型 需要通过构造函数方式创建的值(包装对象) 才能检测出来
1 instanceof Number // false
let num = new Number(1)
num instanceof Number    // true

'' instanceof String   // false
let str = new String('hello');
str instanceof String   // true

function CreatePerson(name,age){
            this.name = name;
            this.age = age;
}
CreatePerson('蓝蓝',15);  // this=>window  普通函数执行;

let person1 = new CreatePerson('黄黄',12);  
person1 instanceof CreatePerson   // =>true

constructor

@原理
在类的原型上一般都会带有CONSTRUCTOR属性,存储当前类本身,我们也是利用这一点,获取某实例的CONSTRUCTOR属性值,验证是否为所属的类,从而进行数据类型检测

@局限性
可以去随意修改对应的constructor值或者是手动给ary增加一个私有的constructor属性等;

var obj = {}
console.log(obj.constructor === Object)  // true
var arr = []
console.log(arr.constructor === Array)  // true
console.log(arr.constructor === Object)  // false 
var date = new Date()
console.log(date.constructor === Date)  // true
var reg = /\d+/
console.log(reg.constructor === RegExp)  // true

arr.constructor = 111; //=>设置私有属性
console.log(arr.constructor === Array); //=>false
Func.prototype={}; //=>这样原型上没有CONSTRUCTOR属性(重构了)

Object.prototype.toString.call([value])

"[object 所属类]" ,例如:"[object Array]"...

**所有的数据类型上都有toString方法,只有Object原型上的toString是检测当前实例所属类的详细信息的,其它原型的方法仅仅是转换为字符串;

@原理

1.首先基于原型链查找机制,找到Object.prototype.toString
2.把找到的方法执行,方法中的this -> obj
3.方法内部把this(obj)的所属类信息输出
=>方法执行,方法中的this是谁,就是检测谁的所属类信息

@优势

所有数据类型隶属的类信息检测的一清二楚
String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Math/Function...

console.log(Object.prototype.toString.call(1)) // "[object Number]"
console.log(Object.prototype.toString.call('a')) // "[object String]"

function func(n, m) {
            return n + m;
        }
let obj1 = {},
    obj2 = {
        name: '蓝蓝'
    }; */
console.log([12, 23].toString()); //=>"12,23"
console.log(/^\d+$/.toString()); //=>"/^\d+$/"
console.log(func.toString()); //=>"function func(n, m) {...}"
 console.log(obj1.toString()); //=>"[object Object]"
console.log(obj2.toString()); //=>"[object Object]"

结合每个方法,属性的优缺点,我们来封装一个简单的检测数据类型库:

let _obj = {
            isNumeric: "Number",
            isBoolean: 'Boolean',
            isString: 'String',
            isNull: 'Null',
            isUndefined: 'Undefined',
            isSymbol: 'Symbol',
            isPlainObject: 'Object',
            isArray: 'Array',
            isRegExp: 'RegExp',
            isDate: 'Date',
            isFunction: "Function",
            isWindow: 'Window'
        },
        _toString = _obj.toString,
        _type = {};

for (let key in _obj) {
    if (!_obj.hasOwnProperty(key)) break;
    let reg = new RegExp("^\\[object " + _obj[key] + "\\]$");
    _type[key] = function (val) {
        return reg.test(_toString.call(val));
    }
}

console.log(_type.isNumeric('ddd'))  // =>false
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容