九大数据类型
- 基本数据类型:
- Number 数字
- String 字符串
- Boolean 布尔
- Null
- Undefined
- Symbol 唯一的
- BigInt 最大整数
- 引用数据类型:
- 对象(Object)
-
- 普通对象 { }
-
- 日期对象 Date
-
- 正则 RegExp
-
- 数组 Array
-
- 实例(构造函数执行)
-
- prototype 原型
-
- ...
- 函数(Function)
var A = Symbol("fn1");
var obj = {
fn1:function(){
console.log(1)
}
}
obj[A] = function(){
console.log(2)
}
console.log(obj.fn1());
=> 1
console.log(obj[A]());
=> 2
BigInt 最大整数
在js 中 Number 数据类型的值是有范围的: -9007199254740991 ~ 9007199254740991 在这个范围之外的数据就失去精度
- 最大范围:Number.MAX_SAFE_INTEGER
- 最小范围:Number.MIN_SAFE_INTEGER
超出范围会失去精度
创建bigint 数据类型的两种办法
1、直接在数据类型后面加n
10n
2、构造函数的方法:BigInt(数值)
BigInt(10)
=> 10n
BigInt(10)==10
=> true
BigInt(10) === 10
=> false
用 BigInt 创建的数据,类型是bigint,如果是两个等号比较,会进行隐式转换,所以等号左边的值会转化为10,等号两边相等,所以是true;三个等号的比较的时候,是绝对相等的比较,不会进行隐式转换,数据类型必须相等,所以例子中是false。
number 数据类型中比较特殊的
NaN
1、NaN:虽然是非有效数字,但是属于number类型 2、NaN 永远不属于其他的数据类型,判断一个数据是不是非有效数字的时候,不能用 xxx ==NaN ,这样判断的结果永远是false
isNaN
isNaN可以用来判断是否是非有效数字,返回值是布尔数据类型,如果值是true,说明是非有效数字,如果是false,说明是有效数字 isNaN在判断数据的时候,如果是非number数据类型的,会隐式调用Number方法,转化为number数据类型,然后再进行判断
isNaN("12px");
=> true
分析:不是number数据类型,Number("12px")=>NaN,(把字符串转化为number类型,里面如果包含了非有效数字字符,转换的结果就是NaN),是非有效数字,所以是true
等号比较原则
- 数据类型相同的:
1、引用数据类型比较的时候,比的是引用地址(空间地址)
{}={} => false
[] = [] =>false
var obj1 ={};
var obj2 = obj1;
console.log(obj1 == obj2); => true
2、NaN 不等于任何一个数据,包括它本身
NaN == NaN =>false
NaN === NaN =>false
- 数据类型不同的:
1、undefined 和 null
undefined == null; =>true
undefined === null; =>false
2、对象和字符串在进行比较的时候:把对象先转换为字符串,然后再进行比较
[] == ""
=>先把对象数据类型转换为字符串类型
[].toString() => ""
=> "" == ""
=> true
3、剩下的,对于不同的数据类型在进行比较的时候,都是转化为number数据类型再进行比较
BigInt(10) == "10"
=>true
经典面试题
console.log([]==false) =>true
分析:等号两边数据类型不同,都转化为number类型再比较,[]先转化为""然后转化为0,false转化为0,所以相等
typeof 数据类型检测
typeof 返回的结果一定是字符串类型的
typeof typeof 1 =>"string"
特殊的: typeof null 的结果是 "object"
可以理解为计算机的一个bug,计算机在存储值的时候,是以二进制进行存储的,以000开头的,一般转化过来的都是对象,但是在存 null 的时候,把开头存成了000,所以在转换的时候变成了对象。其实 null 并不是对象
typeof null =>"object"
typeof 1 => "number"
typeof "a" => "string"
typeof false => "boolean"
typeof undefined =>"undefined"
typeof Symbol() =>"symbol"
typeof 10n =>"bigint"
typeof {} =>"object"
数据类型的转化
转化为数字类型的方法
- Number()
- parseInt/parseFloat
- 隐式转化 如isNaN()
转化为字符串类型的方法
- String()
- toString()
- 隐式转化 如 alert()
转化为布尔类型的方法
- Boolean()
- ! 取反之前先转化为布尔类型再取反
- !! 两次取反相当于只把数据转化为布尔类型
- 隐式转化 如 if()
面试题:
console.log(![] == false) =>true
分析:先将等号左边计算出来,[]转布尔类型是true,取反是false,所以等号两边相等
Number()转化为数字类型的方法中的细节
-
把字符串转化为数字,如果字符串中包含非有效数字字符,结果就是NaN
-
把对象转化为数字,需要隐式调用 toString 方法先转化为字符串,再转化为数字
-
但是对于普通对象,调用的是Object.prototype.toString这个方法,它是用来检测数据类型的,而且检测的结果都是"[object Object]"
var obj ={};
obj.toString() =>"[object Object]"
-
bigint类型的可以转化为数字
-
symbol类型的不可以转化为数字
一些练习
parseInt("")
Number("")
isNaN("")
parseInt(null)
Number(null)
isNaN(null)
parseInt("12px")
Number("12px")
isNaN("12px")
parseFloat("1.6px")+parseInt("1.2px")+typeof parseInt(null)
isNaN(Number(!!Number(parseInt("0.8"))))
typeof !parseInt(null) + !isNaN(null)
NaN
0
false
NaN
0
false
12
NaN
true
"2.6number"
false
"booleantrue"
字符串的特殊性
- 字符串和加号遇到一起的时候,是字符串拼接
- ++i/+i
- {}+0 大括号在左边的,大括号不参与运算,将大括号视为代码块 =>0
- ({}+0) =>"[object Object]0" 字符串拼接
- 0+{} =>"0[object Object]" 字符串拼接
parseInt进制转化
var n = parseInt("11",2)
把"11"按照2进制进行解析,把结果转化为10进制
console.log(n) => 3
parseInt进行进制转化时,第一个参数是要被转化的字符串,第二个参数是进制数,将第一个参数的符合整数的部分且符合第二个参数规定的进制的范围内位的截取出来,按照第二个参数的进制数,将截取到的符合规定的数转化为十进制的数
1、前提是要从左往右截取出来字符串的每一位都符合在对应的进制的范围内的,不在进制范围内的位,不进行截取,一旦出现不符合的位立即终止截取,将截取的位返回,进行转化
- 二进制数的每一位只能出现 0 或 1
- 三进制数的每一位只能出现 0、1、2
- 八进制数的每一位只能出现 0~7
- 十进制数的每一位只能出现 0~9
2、找到符合的位以后看权值
权值:就是对应进制的幂次
- 个位数的权值:0
- 十位数 1
- 百位数 2
- ......
- 小数点左边的:从右向左权值依次为:0、1、2、3...
- (本例中用不到这个,parseInt只截取整数位)小数点右边的:从左向右权值依次为:-1、-2...
"11" 按2进制转化为10进制
1*2^1 + 1*2^0 = 2+1 => 3
3、还需要注意的是:第二个参数的进制,有一个范围,要求在2~36之间,第二个参数如果写0或者不写,就默认为十进制,不在此范围内的,结果返回NaN
练习
let arr = [10.18,0,10,25,23];
arr = arr.map(parseInt);
console.log(arr);
=>[10,NaN,2,2,11]
4、不写第二个参数的特殊情况
- 第一个参数以0 开头 默认这个数为八进制的数,转化为十进制
parseInt(016) => 8 + 6 = 14
- 第一个参数以0x 开头 默认这个数为十六进制的数,转化为十进制
parseInt(0x16) => 16 + 6 = 22