1) typeof 检测数据类型 原理
先来几个大家都会的例子,想一想为什么结果是这样的呢?
console.log(typeof 1); //number
console.log(typeof 'a'); //string
console.log(typeof false); //boolean
console.log(typeof []); //object
console.log(typeof /a/); //object
console.log(typeof {}); //object
console.log(typeof null); //object
console.log(typeof undefined);//undefined
检测数据类型的底层原理:
+ 所有的数据类型值,在计算机底层都是按照 “64位” 的二进制值进行存储的!
+ typeof是按照二进制值进行检测类型的
+ 二进制的前三位是0,认为是对象,然后再去看有么有实现call方法,
如果实现了,返回 'function',没有实现,则返回 'object'
按照计算机底层存储的二进制进行检测「效率高」
- 000 对象
- 1 整数
- 010 浮点数
- 100 字符串
- 110 布尔
- 000000…. null
- -2^30 undefined
- ……
+ null是64个零 typeof null -> 'object' 「局限性」
+ ...
+ 检测未被声明的变量,值是'undefined'
2)对象类型转化number类型的过程
基本数据类型的相关操作开发者对其往往只是使用,知其然不知其所以然。
比如:Array是如何转化成Number类型的呢
==>第一步 直接转化
let arry =[10];
console.log(Number(arry)); //10 输出10没什么问题
==>第二步 我们稍微修改下看看arry的 toString 方法再看看效果呢
arry.toString = function(){return '12'};
console.log(Number(arry));//12 这已经变成12了哦
==>第三步 修改valueOf 方法再看看效果呢
arry.valueOf = function(){return '14'};
console.log(Number(arry));//14 又变成14了哦
==>第四步 修改**[Symbol.toPrimitive]** 方法再看看效果呢
arry[Symbol.toPrimitive] = function(){return '16'};
console.log(Number(arry)); //16 咋又变了呢?
按照上面步骤执行下来我们来分析下完整程序
我们再来打印arry所有方法的值都还是多少呢?
arry =[10];
//输出获取这三个方法
console.log(arry[Symbol.toPrimitive]); //undefined
console.log(arry.valueOf()); //[10]
console.log(arry.toString()); //10
console.log(Number(arry)); //10
//重写
arry.toString = function(){return '12'};
arry.valueOf = function(){return '14'};
arry[Symbol.toPrimitive] = function(){return '16'};
//再次输出获取这三个方法
console.log(arry.toString()); //12
console.log(arry.valueOf()); //14
console.log(arry[Symbol.toPrimitive]()); //16
结果分析
在arry转化为Number类型时转换过程如下
首先 arr[Symbol.toPrimitive] -> undefined
其次 arr.valueOf() 获取原始值 -> [10] 不是原始值
再此 arr.toString() 转换为字符串 -> '10'
最后 再把字符串‘10’转化为数字 -> 10
[Symbol.toPrimitive]并不会覆盖valueOf和toString,
同样valueOf也不会影响toString
2.1. 拓展面试题
实现 a==1&a==2&&a==3 是true
利用对象转换Number特性来做
a = {n:0,toString:function(){return ++this.n}}
console.log(a==1&&a==2&&a==3);//true