数据类型概念
数据类型大致可以分成两类来进行存储
- 基础类型存储在栈内存,被引用或拷贝时,会创建一个完全相等的变量
- 引用类型存储在堆内存,存储的是地址,多个引用指向同一个地址,这里涉及一个“共享”的概念
共享
举个例子:
let a = {
name: 'lee',
age: 18
}
let b = a;
console.log(a.name);
b.name = 'son';
console.log(a.name);
console.log(b.name);
打印结果:
‘lee’
‘son’
‘son’
在执行了 b.name='son’后,我们会发现 a 和 b 的 name 变成一样的,第二个和第三个的打印结果都是son,这里就体现了引用类型的共享特征,即这两个值都存在同一块内存中共享,一个发生了改变,另一个也随之变化。
再举个例子:
let a = {
name: 'Julia',
age: 20
}
function change(o) {
o.age = 24;
o = {
name: 'Kath',
age: 30
}
return o;
}
let b = change(a);
console.log(b.age);
console.log(a.age);
打印结果:
30
24
需要注意的是,function和return带来了不一样的东西,原因在于,函数传参进来的o,传递的是对象在堆中的内存地址,通过调用 o.age = 24 ,确实改变了a对象的age属性,但 return o 这一行又把 o 变成了另一个内存地址,将name为Kath,age为30的这个对象存入其中,最后返回b的值变成了name为Kath,age为30的这个对象。
数据类型检测(面试常考题目)
typeof
注意
第六行 typeof null 输出 object。
这只是js存在的一个悠久历史的bug,不代表null就是引用数据类型,并且null本身也不是对象,因此null在typeof返回的是错误的结果,不能作为判断null的方法。
如果需要在if语句中判断是否为null,直接通过===null判断就好。
此外还要注意引用数据类型用typeof判断的话,除了function会判断ok以外,其他都是object,是无法判断出来的。
instanceof
两种判断数据类型的差异
- instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
- typeof 虽然可以判断基础数据类型(null除外),但是引用数据类型中,除了function类型以外,其他的也无法判断
Object.prototype.toString(推荐)
这个方法可以很好地判断引用数据类型,但要注意返回的首字符是大写,typeof是小写
下面是一个实现全局通用判断诗句类型的代码,加深理解:
function getType(obj) {
let type = typeof obj;
if (type !== "object") {//先进行typeof判断,如果是基础数据类型,直接返回
return type;
}
//对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1')
}
数据类型转换
强制类型转换
Number()
Boolean()
parseInt():函数可解析一个字符串,并返回一个整数。
- 只有字符串中的第一个数字会被返回。
- 开头和结尾的空格是允许的。
- 如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。
console.log(parseInt(""))
NaN
隐式类型转换
‘==’的转化规则
‘+’的转换规则
Object 转换规则
var obj = {
value: 1,
valueOf() {
return 2;
},
toString() {
return '3';
},
[Symbol.toPrimitive]() {
return 4;
}
}
console.log(obj + 1);
console.log(10 + {});
console.log([1, 2, undefined, 4, 5] + 10);
5
10[object Object]
1,2,4,510