你好,我是南一。这是我在准备面试八股文的笔记,如果有发现错误或者可完善的地方,还请指正,万分感谢🌹
数据类型判断
1.typeof 操作符
number
//输出 number
console.log(typeof 1);
console.log(typeof NaN); // 尽管他是Not-A-Number
console.log(typeof Number('1')); // Number 会尝试把参数解析成数值
console.log(typeof Infinity); // 无限大也是number
console.log(typeof 42n); // 这个输出bigint
string
//输出 string
console.log(typeof 'mc');
console.log(typeof '');
console.log(typeof `adadad`); // 模板字符串
console.log(typeof (typeof 1)); // typeof 操作符 返回字符串
console.log(typeof String(1)); // String 将任意值转换为字符串,比 toString 更安全
boolean
//输出 boolean
console.log(typeof true);
console.log(typeof Boolean(1)); // Boolean(1)是true Boolean(0)是false
console.log(typeof !!(1));// 两次调用 ! (逻辑非) 操作符相当于 Boolean() true
undefined
声明但未初始化和未声明 typeof输出都是"undefined",但直接打印未声明变量是会报错的
console.log(typeof undefined); // undefined
console.log(typeof console.log()); // undefined
function
console.log(typeof Symbol) // function
console.log(typeof function () { }); // function
console.log(typeof new Function()) // function
object
// object
console.log(typeof []);
console.log(typeof {});
console.log(typeof null);
console.log(typeof new Date()); // 除 Function 外的所有构造函数的类型都是 'object'
console.log(typeof /regex/);
symbol
//symbol
console.log(typeof Symbol());
console.log(typeof Symbol('foo'));
console.log(typeof Symbol.iterator);
优点:能够快速区分基本数据类型
缺点:不能将Object、Array和Null区分,都返回object
typeof 实现原理:
js 在底层是怎么存储数据的类型信息呢?
其实,js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息
- 000:对象
- 010:浮点数
- 100:字符串
- 110:布尔
- 1:整数
但是,对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。
null:所有机器码均为0
undefined:用 −2^30 整数来表示
所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。
2.instanceof 运算符
instanceof运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
console.log(1 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function () { } instanceof Function); // true
console.log({} instanceof Object); // true
console.log(null instanceof Object); // false
优点:能够区分Array、Object、Function,适用于判断自定义的类实例对象
缺点:Nunmer、boolean、String基本数据类型不能判断
instanceof 原理模拟实现
function new_instance_of(leftVaule, rightVaule) {
var rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
}
其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。
3.Object.prototype.toString.call()
var toString = Object.prototype.toString;
console.log(toString.call(1)); //[object Number]
console.log(toString.call(true)); //[object Boolean]
console.log(toString.call('mc')); //[object String]
console.log(toString.call([])); //[object Array]
console.log(toString.call({})); //[object Object]
console.log(toString.call(function () { })); //[object Function]
console.log(toString.call(undefined)); //[object Undefined]
console.log(toString.call(null)); //[object Null]
console.log(toString.call(Symbol())); //[object Symbol]
优点:精准判断数据类型
缺点:写法繁琐不容易记,推荐进行封装后使用
简单封装
let typeUtil = {};
let types = ['String', 'Array', 'Number', 'Object', 'Undefined', 'Null', 'Boolean', 'Function', 'Symbol'];
types.forEach(type => {
typeUtil['is' + type] = function (obj) {
return Object.prototype.toString.call(obj) === `[object ${type}]`;
}
})
console.log(typeUtil);
//{
// isString: [Function (anonymous)],
// isArray: [Function (anonymous)],
// isNumber: [Function (anonymous)],
// isObject: [Function (anonymous)],
// isUndefined: [Function (anonymous)],
// isNull: [Function (anonymous)],
// isBoolean: [Function (anonymous)],
// isFunction: [Function (anonymous)],
// isSymbol: [Function (anonymous)]
//}
由于String基本包装类型的存在,在必要的时候JS引擎会把字符串字面量转换成一个String对象,从而可以执行访问属性和方法的操作
Object类型的每个实例都有toString方法,返回对象的字符串表示,所以每个实例化的对象都可以调用toString方法。