共计 4937 个字符,预计需要花费 13 分钟才能阅读完成。
前言
本篇博客旨在清晰意识 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 场景
// 变量被申明了,但没有赋值时,返回 undefined
let i ;
i //undefined
// 调用函数时,应该提供的参数没有提供,该参数为 undefined
function f(x){console.log(x)
}
f()//undefined
// 对象没有赋值的属性,该属性的值为 undefined
let j = {}
j.p // undefined
// 函数没有返回值时,默认返回 undefined
let 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.3
let number = 0.1*10+0.2*10
let trueNumber = number/10 //0.3
toFixed(n):保留 n 位小数,不精确,且 n 不能过大。
//0.1+0.2!== 0.3。let number = 0.1+0.2
let 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)) // des1
console.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 //NaN
1*null // 0
'1a'-null // NaN , 因为 '1a' 无奈转化为数字
最初
走过路过,不要错过,点赞、珍藏、评论三连~