JavaScript之判断数据类型和包装类

140 阅读3分钟

面试将近,关键时候基础不能掉链子

本文思路如下:

  1. js数据类型
  2. 包装类
  3. toString方法
  4. 如何判断js数据类型

1.js数据类型

类型
基本数据类型boolean,string,number,null,undefined,symbol
引用数据类型Object,Function,Array,Date,Math,RegExp
包装类Number,String,Boolean

2.包装类

例子1:

let num=99
console.log(num.toString())
//返回"99"

发现问题:上述代码中num明明是基本数据类型,不可能有方法和属性,为什么不报错,并且输出“99”?

问题解决:系统帮我们做了组包拆包操作

问题解析如下:

//系统扫描代码到num.toString()时,做了组包,
new Number(num).toString()
//此刻变成了一个valueOf为num的Number对象在访问包装类Number上面的toString方法

例子2:

let person='abc'
person.name='xujii'
console.log(person.name)
//输出undefined

发现问题:为什么不输出'xujii'而输出了undefined

问题解决:系统帮我们做了组包拆包操作

问题解析如下:

person.name='xujii'  //系统扫描到这句代码,做了组包和拆包作用
                     //1.组包:New String(person).name='xujii'
                     //2.拆包:组包后js进行了delete拆包操作,此时已经没有valueOf为person的String类型对象了
                     
console.log(person.name) //系统扫描到这句代码,又做了组包和拆包作用
                         //1.组包:console.log(New String(person).name)  查找不到,返回undefined
                         //2.拆包:组包后js进行了delete拆包操作

3.详细说说toString方法

代码如下:

let num=456
console.log('abc'.toString(),typeof 'abc'.toString());
console.log([1,2,3].toString(),typeof [1,2,3].toString());
console.log(num.toString(),typeof num.toString());
console.log(flag.toString(),typeof flag.toString());
let obj={
name:'xujii'
}
console.log(obj.toString(),typeof obj.toString());
let fun=function(){
console.log('I am a function')
}
console.log(fun.toString(),typeof fun.toString());

返回值:

abc string
1,2,3 string
456 string
true string
[object Object] string
function(){
console.log('I am a function')
} string

发现问题: 同一个toString方法,不同类型数据调用会返回不同值。number,string,boolean会返回对应值的字符串类型,Array会返回将数组元素用逗号连接的字符串,Object会返回[object Object],Function会返回整个函数的字符串模式。

问题解决:toString方法是Object原型对象的方法,而Array,Function,Boolean(包装类),Stirng(包装类),Number(包装类)改写了toString()方法。

4.判断js数据类型的三种方法

4.1 typeof
代码返回值(小写的字符串形式)
typeof 123'number'
typeof 'abc''string'
typeof true'boolean'
typeof undefined'undefined'
typeof null'object'
typeof [1,2,3]'object'
typeof {}'object'
typeof fun'function'

因为null和Function特殊,并且除了Function以外的引用类型只能返回object,所以该方法只对除了null以外的基本数据类型有作用。

注意:typeof (typeof 123) //返回'string'

4.1.1 为什么typeof null返回 object

解释:这是js的一个bug,最初js使用的是32位系统,为了性能考虑,在低位存储变量的类型信息。000开头代表的是对象,而null是全0.所以产生了这个错误。

4.2 instanceof

原理:原型链

代码如下:

let str=new String()
let str1='abc'
let n=function fun(){
    console.log('I am a function');
}
console.log(str1 instanceof String);  //false
console.log(str instanceof String); //true
console.log(n instanceof Function); //true
console.log(n instanceof String);  //false
console.log(n instanceof Object);  //true

//以下为涉及原型链知识
console.log(str.__proto__===String.prototype);  //返回true
console.log(String.prototype.__proto__==Object.prototype);  //返回true
console.log(Function.prototype.__proto__==Object.prototype);  //返回true
4.3 Object.prototype.toString.call()----最可靠

代码如下:

 console.log(Object.prototype.toString.call('123'));
console.log(Object.prototype.toString.call(123));
console.log(Object.prototype.toString.call(true));
console.log(Object.prototype.toString.call(undefined));
console.log(Object.prototype.toString.call(null));
console.log(Object.prototype.toString.call({}));
console.log(Object.prototype.toString.call([1,2,3]));
console.log(Object.prototype.toString.call(function fun(){}));
console.log(Object.prototype.toString.call(new Date()));

返回值如下:

[object String]
[object Number]
[object Boolean]
[object Undefined]
[object Null]
[object Object]
[object Array]
[object Function]
[object Date]

总结:通过call方法改变了调用Object.prototype.toString方法主体。

该题涉及面试会问的call手写题复刻Object.prototype.toString方法在后续文章会详细讨论

参考资料(非常感谢大佬们的分享,感激之情溢于言表)

包装类
通过Object.prototype.toString精确判断对象的类型
牛客最新前端面经面试题汇总