前言
本篇博客旨在清晰意识JS六种根底类型以及特色。
面试答复
根底类型:值类型有string、number、Boolean、undefined、null、Symbol。值类型是栈内存,占用空间固定,保留和复制的是值自身。个别咱们用typeof去判断值类型,不过不能用来判断null,因为null在内存中属于援用类型,只不过因为不便效率所以归为值类型。至于typeof的检测原理,波及信息贮存和机器码的问题,就没有深刻了。
知识点
根底类型都是栈(stack),简略了解一下,有两个特色:1. 保留和复制值的自身。2.占用空间固定, 栈内存中,由操作系统主动分配内存空间,主动开释。
1.Boolean
对于Boolean类型就一句话:undefined、null、""、0、NaN、false除了这6个值在js中属于假值,其余均为真值。
2.Undefined
定义
undefined 示意申明了变量但未对其初始化时赋予该变量值的返回值。
利用场景
1.返回undefined场景
//变量被申明了,但没有赋值时,返回undefinedlet i ;i //undefined//调用函数时,应该提供的参数没有提供,该参数为undefinedfunction f(x){ console.log(x)}f()//undefined//对象没有赋值的属性,该属性的值为undefinedlet j = {}j.p // undefined//函数没有返回值时,默认返回undefinedlet x = function z(){}x //undefined
3.Null
定义
已定义,且示意"无"的值
对于null与undefined的异同能够从内存角度看:null在内存里属于援用类型,undefined在内存里属于根本类型。所以typeof null 的输入为Object,typeof undefined 的输入为undefined。之所以把null归为根本类型,是因为"效率"。当然,日常开发中,为了方便使用,将null了解为:申明并赋值的变量,该变量的值为null;将undefined了解为:申明变量,但没有赋值的返回值
4.Number
利用场景
1.精度问题
JavaScript 采纳“IEEE 754 规范定义的双精度64位格局” ,所以会呈现精度缺失的异常情况。
解决办法:
乘除法
//0.1+0.2 !== 0.3let number = 0.1*10+0.2*10let trueNumber = number/10 //0.3
toFixed(n):保留n位小数,不精确,且n不能过大。
//0.1+0.2!== 0.3。let number = 0.1+0.2let trueNumber = number.toFixed(2) //'0.30' string类型 ,
2.增加千分位
toLocaleString()
let num = 10000000 //输出必须是number类型num.toLocaleString()//"10,000,000" 输入的是字符串
当然简单非凡的增加千分号就不满足了,须要自定义,思路如下:
1、对立解决为字符串:JSON.stringify(a)2、切割整数和小数3、将整数局部颠倒,不便插入","4、for循环,每三位插入5、将整数局部颠倒回原样,并加上小数局部function transfor(data){ //1 if(typeof data === 'number'){ data = JSON.stringify(data) } //2、3 let integer = data.split('.')[0].split('').reverse() let decimal = data.split('.')[1] let num = '' //4 for(let i=0;i<integer.length;i++){ if((i+1)%3 === 0 && (i+1) !==integer.length ){ num += integer[i] + ',' }else{ num += integer[i] } } //5 num = num.split('').reverse().join('') if(decimal){ num = num +'.' + decimal }else{ num = num +'.00' } return num }console.log(transfor(1000000))//1,000,000.00
5.String
罕用API
indexOf(): 返回字符串中指定文本首次呈现的索引地位
split():依据参数将字符串宰割,输入为数组
trim():去掉字符串两端的空格
replace() : 依据参数替换指定字符
toLowerCase():把字符串转换成小写
toUpperCase():把字符串转换成大写
parseInt() :把字符串转换成整数
parseFloat() :把字符串转换成数字
let str = " Hello World " str.indexOf("o",6)//8 "o"示意要检索的字符串,6示意从哪里开始str.split("o",1) // [' Hell'] "o"示意宰割节点,1示意返回数组的最大长度str.trim() //'Hello World'str.replace("ell","ddd") // ' Hdddo World ' 这边须要留神的是str自身的值不扭转,相当于新建了一个对象str.toUpperCase() //' HELLO WORLD 'str.toLowerCase() //' hello world ' parseInt('1010',2) //10解析一个2进制的'1010'字符串并返回的十进制整数 ,2是对'1010'字符串是几进制的补充阐明。parseFloat('25.555') //25.555
6.Symbol
定义
"Symbol" ,示意惟一的标识符。
特点1:Symbol具备唯一性,即应用同一"形容"生成的值也不相等
特点2:Symbol具备暗藏性,这个特点使Symbol类型受到爱护,避免被意外应用或重写,不过能够通过Object.getOwnPropertySymbols办法读取到
相干API
创立Symbol
Symbol():Symbol()定义的值不放入全局symbol注册表中,每次都是新建,即便形容雷同值也不相等,即无奈被Symbol.for()查问到对应的值,所以创立Symbol也举荐应用Symbol.for()创立,除非你不打算获取Symbol()的值。
//Symbol 保障是惟一的,即便两个形容雷同的 Symbol 也是 不相等的let sym1 = Symbol("id"); let sym2 = Symbol("id");alert(id1 === id2); // false
查问Symbol的值
Symbol.for:承受一个"形容"作为参数,而后全局环境中搜寻是否有以该参数注册的Symbol值。如果有,就返回这个Symbol值。没有就创立并返回一个以该字符串作为名称的Symbol值,并放入一个全局 symbol 注册表中。
let sym1 = Symbol.for("foo");let sym2 = Symbol.for("foo");sym1 === sym2; // true
查问Symbol的形容
Symbol.keyFor():承受一个"变量名"作为参数,返回一个 Symbol的"形容"
let sym1 = Symbol("des1")let sym2 = Symbol("des2")console.log(Symbol.keyFor(sym1)) // des1console.log(Symbol.keyFor(sym2)) // des2
利用场景
1.代替常量 :保障常量的唯一性
const TYPE_MUSIC = Symbol.for("MUSIC")const TYPE_MOVIE = Symbol.for("MOVIE")const TYPE_IMG = Symbol.for("IMG") function test(data){ switch(data.type){ case TYPE_MUSIC: console.log('MUSIC') break; case TYPE_MOVIE: console.log('MOVIE') break; case TYPE_IMG: console.log('IMG') break; }}test({ type:Symbol.for("MUSIC")})
代码里常常会应用常量来管制业务逻辑关系,如果常量少还比拟好保护,然而常量一多,光是保护值得唯一性就是一项不小的工作。应用Symbol,能够保障常量的唯一性,也能够使代码绝对优雅标准一些。
2.作为属性名或变量名,防止重名带来的问题;作为属性名,必须应用[]运算符来定义和获取;
const name = Symbol.for('name');const obj = { [name]: 'test',}console.log(obj[name]) //test//留神:发送申请时,若对象中含有Symbol类型,不能作为参数,会报错//且用Symbol作为key,取值时,必须应用[]进行取值,如上console
3.作为内置对象的特定办法的属性名,不便开发者对其重写,相当于定义类的公有属性/办法
const PASSWORD = Symbol.for('password')class Login { constructor(username, password) { this.username = username this[PASSWORD] = password } checkPassword(pwd) { return this[PASSWORD] === pwd }}export default Login//因为使用者无奈在内部创立出一个雷同的Symbol,所以就无奈调用该参数
4.注意事项
对象的合并、笼罩、应用用JSON.stringify()
将对象转换成JSON字符串的时候,Symbol属性会被排除在输入内容之外;
for...in ,object.key()等办法拜访不到;
不会被隐式转换,如alert等,非要显示须要在它下面调用toString()办法, Symbol("id").toString()
利用
1. || 、&&操作符的返回后果
咱们常常依据某几个变量做if判断,如何确认判断后果是你想要的,能够应用上面这种办法:先确定返回后果,再依据"undefined、null、""、0、NaN、false除了这6个值在js中属于假值,其余均为真值",那么咱们便须要晓得根本数据类型及援用数据类型的操作符返回后果:
&&且运算符:1.当后果为真时,返回最初一个真值2.当后果为假时,返回第一个假值||或运算符:1.当后果为假时,返回最初一个假值2.当后果为真时,返回第一个真值判断逻辑:先去看&&,一假全假,返回第一个假let a=(undefined&&123)||(3||5)&&0的返回值是什么?因为&&0,所以在if判断中a必然为false,至于a的返回值是什么,须要判断(undefined&&123)||(3||5)是不是false(undefined&&123)||(3||5)其中(undefined&&123) 返回undefined(3||5) 返回3所以最终后果:3&&0 ,返回值为0
2.隐式类型转换
1.if判断undefined、null、false、NaN、''、0除了这6个值在js中为假值,其余均为真值2.加减乘除加:转为字符串优先1+2+'3' // '33''3'+2+null // '32null' ,多种数据类型算术:从左往右依照隐式类型转化的规定进行计算1+undefined //NaN'1a'+undefined //'1aundefine'1+null // null,在数值加减时,会被转换成数字0'1a'+null // 1anull减乘除:转为number优先'3'-2+'1' // '11''3'*2*null // 0 1*undefined //NaN'1a'-undefined //NaN1*null // 0'1a'-null // NaN ,因为'1a'无奈转化为数字
最初
走过路过,不要错过,点赞、珍藏、评论三连~