数据类型的概念:
1.简单数据类型:undefined、Null、Boolean、String、Number、Symbol、BigInt。
2. 复杂数据类型:Object(Array(数组)、RexExp(正则)、Date(日期)、Math(数学函数)、Function(函数对象))
这里就说说一下BigInt、Null、undefiend:
-
BigInt数据类型:目的是比Number数据类型支持的范围更大的整数值。在对大整数执行数学运算时,以任意精度表示整数的能力尤为重要。使用BigInt,整数溢出将不再是问题。要创建BigInt,只需在整数的末尾追加n即可。
-
undefiend:当一个声明了一个变量未初始化时,得到的是undefined。但具体的情况又一下几种:
- let a; 声明, 没有赋值 ,变量声明时,JS类型由值来决定;
- 函数没有返回值 const fnNoRturn = () =>{} console.log(fnNoRturn());
- 参数不传值
const fn = (b) =>{
console.log(typeof b);
}
fn();
4. 应用了对象不存在的对象的Key
const o = {c:'1'};
console.log(o.d,'4'); o.d这个key并没有声明
undefined console.log(zr) 调用了没有声明的变量 语法错误
- Null:
数据类型大致可以分为:一是基础类型,它是存储在栈内存,当对它进行赋值操作不会改变它的值。如:b = 4;let a = b;其中的b的值不会变。
二是引用类型,它存储在堆内存中,存储的是地址,多个引用会指向同一个地址,这里好像会进行共享。
例如:
let a = {
name: '宫本',
age: 22
}
let b = a;
b.name = '娜可露露';
console.log(a.name);
console.log(b.name);
其中a.name和b.name的值是一样的,这由于指向的是指向同一个地址,所以它们的值都是一起改变的。
进阶版,如:
let a = {
name: '宫本',
age: 22
}
function message(c){
c.age = 30;
c = {
name: "剑仙李白",
age:27
}
return c;
}
let b = message(a);
console.log(a.age);
console.log(b.age);
这里有一个函数,其中打印的值分别为30,27。请注意function和return所带出来的地址是不同的,通过c.age = 30改变了原本a的age属性(22),但是函数中return又将c变成了age为27的内存地址,所以b.age = 27。
数据检测:
-
typeof
typeof 1 // 'number' typeof '1' // 'string' typeof undefined // 'undefined' typeof true // 'boolean' typeof Symbol() // 'symbol' typeof null // 'object' typeof [] // 'object' typeof {} // 'object' typeof console // 'object' typeof console.log // 'function'
typeof可以判断基础数据类型(null除外),但是引用数据类型,除了function类型以外,
其他的无法判断。
2. instanceof
let Car = function() {}
let tesila = new Car()
tesila instanceof Car // true
let car = new String('tesila')
car instanceof String // true
let str = 'baoma-7'
str instanceof String // false
instanceof可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
3. Object.prototype.toString
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/[a-z]/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
注意Object.prototype.toString()返回的值为[object xxx]
数据类型的转换:
1. 数值转换:
如果是布尔值,true 和 false 分别被转换为 1 和 0;
如果是数字,返回自身;
如果是 null,返回 0;
如果是 undefined,返回 NaN;
如果是字符串,遵循以下规则:如果字符串中只包含数字(或者是 0X / 0x 开头的十六进制数字字符串,允许包含正负号),则将其转换为十进制;如果字符串中包含有效的浮点格式,将其转换为浮点数值;如果是空字符串,将其转换为 0;如果不是以上格式的字符串,均返回 NaN;
如果是 Symbol,抛出错误;
如果是对象,就调用valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用toString()方法,再按照转换字符串的规则转换
2. Object 的转换规则
对象转换的规则,会先调用内置的 [ToPrimitive] 函数,其规则逻辑如下:
如果部署了 Symbol.toPrimitive 方法,优先调用再返回;
调用 valueOf(),如果转换为基础类型,则返回;
调用 toString(),如果转换为基础类型,则返回;
如果都没有返回基础类型,会报错。
3. '+' 的隐式类型转换规则
题目:{}+10和10+{}的类型为何不同:
因为对象在作为操作数时,解释器总是优先调用valueOf(),而其他情况,解释器总是认为我们想要的是字符串,所以会优先调用toString()。因此对象在前面返回结果就是Number;其他情况对象默认用toString。
今天的分享就到此为止了。