基本类型 vs 引用类型
1.基本数据类型 null undefined string number boolean symbol bitInt
2.symbol 定一个独一无二的值 为了解决全局变量被污染的问题
用法
// Symbol()在全局环境中唯一
s1 = Symbol(1)
s2 = Symbol(1)
s1 === s2 //false
// Symbol.for()会在全局环境中先找有没有登记过,不会重复生产
s1 = Symbol.for(1)
s2 = Symbol.for(1)
s1 === s2; //true
s1.description // 1 拿到描述
特性
- 作为属性 不会出现在for in for of Object.keys()中,可以用Object.getOwnPerpertySymbol()获取属性名 Reflect.ownerKeys()也能访问到全部的key包括symbol
- 不能转位数字 不能和其他值进行运算
3.引用数据类型 object array date function regexp
4.基本数据类型和引用数据类型的区别
1)存储位置:基本数据类型存在栈(先进后出,内存自动适配)中,空间小 大小固定,读取频繁;引用类型存在堆(优先队列,开发者分配)中,空间大,大小不固定,在栈中存的是指针,指向堆中的实际地址。
2)参数传递方式:基本数据类型是按照值传递,原始值改变和参数互不影响;引用类型是按照引用传递,原始值和参数指向同一个对象,互相影响
3)复制变量方式:基本类型复制的是变量的值,两者互不影响;应用类型复制的是变量的引用,两者指向同一对象,互相影响。
5.null undefined 区别
- Undefined的表示未定义 声明了变量未赋值 函数没有传参,null 表示空对象 一般给要返回的对象初始化值
- undefined不是保留字,可以作为变量名,但是不生效; null是保留字,不可以作为变量名
- Typeof undefined返回undefined, typeof null返回 object
6.0.1+0.2 !== 0.3
计算机是用二进制存储数据的,0.1 是一个循环数 0.2也是一个循环数。js是采用双精度浮点数,小数点最多能保留52位,会导致精度丢失。
浮点数存储:符号位(1)+指数位(11)+小数位(52)
解决办法:判断是否在误差范围内(小于) Number.EPSION
数据类型检测
1.typeof 能判断除了null的基本类型
Typeof null 等于 object 的原因是js最初设计的坑 数据都是以32位二进制存储的 前3为标志位存储了数据类型 null的类标识为是000和object的标签是一样的
2.Instanceof 判断对象的类型 本质是判断它的原型链是否存在该类型的原型(判断它的原型链中是否存在一个构造函数的protype属性) 不能判断基本类型(可以判断number string boolean他们的包装对象), 可以判断引用类型 改变了原型就不能用来判断类型
2 instanceof Number // false
"a" instanceof String // false
true instanceof Boolean // false
(new Number(1)) instanceof Number // true
[] instanceof Array // true
function(){} instanceof Function //true
{} instanceof Object // true
function Fn(){}
Fn.prototy = new Array()
var f = new Fn()
f instanceof Arrary // true
f instanceof Function // false
// 类似的方法有
Number.prototype.isPrototypeOf(new Number(1)) //true
String.prototype.isPrototypeOf(new String(1)) // true
Function.prototype.isPrototypeOf(F) // true
Date.prototype.isPrototypeOf(new Date())//true
3.constructor 可以判判断类型 改变了原型就不能用来判断类型 不能区分普通number string boolean和他们的包装对象
(2).constructor === Number //true
(new Number(2)).constructor === Number //true
('str').constructor === String //true
(true).constructor === Boo //true
([]).constructor === Array //true
(function() {}).constructor === Function //true
({}).constructor === Object //true
function Fn(){};
Fn.prototype = new Array();
var f = new Fn();
f.constructor===Fn // false
f.constructor===Array // true
obj.__proto__ === Array.prototype;
4.Object.prototype.toString.call()
var a = Object.prototype.toString
a.call(1) //'[object Number]'
a.call(new Number(1))//'[object Number]'
a.call('a') //'[object String]'
a.call('boolean') //'[object String]'
a.call(true) // '[object Boolean]'
a.call([]) // '[object Array]'
a.call(function(){}) //'[object Function]'
a.call({}) //'[object Object]'
a.call(undefined) //'[object Undefined]'
a.call(null) //'[object Null]'
function Fn(){};
Fn.prototype = new Array();
var f = new Fn();
a.call(f) // '[object Object]'
本质是使用原型链上的toString方法,如果参数是null undefined直接返回 [object null] [object undefined],如果不是,则将参数转为对象,再判断,原始类型就是装箱,转化为后,取得该对象的 [Symbol.toStringTag]属性 和object拼装,可以手动改[Symbol.toStringTag]属性
var o1 = { [Symbol.toStringTag]: "A" };
var o2 = { [Symbol.toStringTag]: null };
Object.prototype.toString.call(o1); // '[object A]'
Object.prototype.toString.call(o2); // => "[object Object]" //只能是字符串 不是忽略
5.Api 方法
Array.isArray(obj) //判断数组
isNaN(1) // 判断NAN 会先把数字转位number 转不了的为NaN
Number.isNaN(1) // 先判断是不是number 在判断是不是NaN 不转
类型转换
[] == ![] // true
[undefined] == false //true
– | String | Boolean | Null | Undefined | Number | Symbol | Array | Object |
---|---|---|---|---|---|---|---|---|
转为String | - | False: ‘false’ true:'‘true’ | ‘null’ | ‘undefined’ | ‘1’ | 只允许显式转换 ‘Symbol()’ 隐式转换保存 | []:‘’ ,其他字符串逗号拼接 | 调用toString方法 “[object object]” |
转为boolean | ‘’:false 其他:ture | - | False | False | +0 -0 Na N:false 其他true | True | True | True |
转为number | Number() “”:0 包含非数字:NaN | True:1 false:0 | 0 | NaN | 0 | 报错 | []:0 其他先转为基本类型再判断 | 转为基本类型 |
1.显式类型转换
- Number(a) 判断规则见上面的表格
- parseInt(b) 不会把其他类型转化为数字 从头开始识别数字 能识别到几返回 识别不到就停止,不是数字开头的字符串判断为NaN
- Boolean() null undefined NaN false ‘’ +0 -0为false其他为ture
2.隐式类型转换
-
加号 a+b
一侧为字符串 另一侧先转位字符串 拼接
一侧是数字 另一侧是基本类型非数字 将另一侧转为数字 相加
一侧是数字 另一侧是应用类型 就把两个转为字符串 拼接
两侧为boolean 就先转为数字
-
减号 乘号 除号 将非number转为number
-
isNaN() 转为数字
-
++a +b -b 转为数字
-
< > >= <= 转为boolean
-
==
1)类型相同 直接比较
2)类型不同 先转化类型 NaN和谁都不想等
3)undefined == null
4)String 和 number string会转为number
5)其中一个为boolean 另一个就会转为boolean
6) 其中一个是object 另一个不是 会先把object转为原始类型
3.装箱转换:把基本类型转为对象类型
3个包装对象 Number String Boolean Symbol
拆箱转换ToPrimitive: 把对象变为基本类型 会调用valueOf() toString() 如果之后不为基本类型 就会报typeError