JS数据类型的内容你都了解吗?

117 阅读4分钟

数据类型的概念:

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。但具体的情况又一下几种:

  1.      let a; 声明, 没有赋值 ,变量声明时,JS类型由值来决定; 
  2.    函数没有返回值 const fnNoRturn = () =>{} console.log(fnNoRturn());
  3.    参数不传值

             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。

数据检测:

  1. 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。

今天的分享就到此为止了。