数据类型概念
- 基础类型存储在栈内存,被引用或拷贝时,会创建一个完全相等的变量
- 引用类型存储在堆内存,存储的是地址,多个引用指向同一个地址,这里会涉及一个“共享”的概念
instanceof底层实现
function myInstanceof(left, right) {
// 这里先用typeof来判断基础数据类型,如果是,直接返回false
if(typeof left!=='object'||left===null) return false;
// getProtypeof是Object对象自带的API,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(left);
while(true) { // 循环往下寻找,直到找到相同的原型对象
if(proto === null) return false;
if(proto === right.prototype) return true; // 找到相同原型对象,返回true
proto = Object.getPrototypeof(proto);
}
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number)); // true
console.log(myInstanceof(123, Number)); // false
typeof 和 instanceof两种判断数据类型的差异
- instanceof可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
- 而typeof也存在弊端,它虽然可以判断基础数据类型(null除外),但是引用数据类型中,除了function类型以外,其他的也无法判断
第三种判断方法Object.prototype.toString.call()
返回[object Xxx]
数据类型转换
强制类型转换
Number() parseInt() parseFloat() toString() String() Boolean()
Number()方法的强制转换规则
布尔值 | true和false分别被转换为1和0 |
---|---|
数字 | 返回自身 |
null | 返回0 |
undefined | 返回NaN |
字符串 | 如果字符串中只包含数字,则将其转化为十进制 。 如果字符串中包含有效的浮点格式,将其转换为浮点数值。如果是空字符串,将其转换为0。如果不是以上格式的字符串,均返回NaN |
Symbol | 抛出错误 |
对象,并部署了[Symbol.toPrimitive] | 那么调用此方法,否则调用对象的valueOf()方法 |
Boolean()方法的强制转换规则
除了undefined、null、false、‘’、0(包括+0,-0)、NaN转换出来是false, 其他都是true。
隐式类型转换
逻辑运算符 | &&、||、! |
---|---|
运算符 | +、-、*、/ |
关系操作符 | >、<、<=、>= |
相等运算符 | == |
if/while条件 | - |
‘==’的隐式类型转换规则
- 如果类型相同,无须进行类型转换
- 如果其中一个操作值是null或者undefined,那么另一个操作符必须为null或者undefined才会返回true,否则都返回false
- 如果其中一个是Symbol类型,那么返回false
- 两个操作值如果都为string和number类型,那么就会将字符串转换为number
- 如果一个操作值是boolean,那么转换成number
- 如果一个操作值为object,且另一方为string、number或者symbol就会把object转为原始类型再进行判断
‘+’的隐式类型转换规则
‘+’ 号操作符,不仅可以用作数字相加,还可以用作字符串拼接
如果其中有一个是字符串,另外一个是undefined、null或布尔值则调用toString()方法进行字符串拼接
如果是纯对象、数组、正则等,则默认调用对象的转换方法会存在优先级,然后再进行拼接
如果其中有一个是数字,另外一个是undefined、null、布尔值或数字,则会将其转换成数字进行加法运算,对象的情况还是参考上一条规则。
如果其中一个是字符串、一个是数字,则按照字符串规则进行拼接
Object的转换规则
如果部署了Symbol.toPrimitive方法,优先调用再返回
调用valueOf(), 如果转换为基础类型则返回
调用toString(),如果转换为基础类型则返回
如果都没有返回基础类型,会报错