前言:
目前小伙伴们对“js不属于基本类型的是”大体比较关切,兄弟们都想要了解一些“js不属于基本类型的是”的相关资讯。那么小编在网摘上网罗了一些对于“js不属于基本类型的是””的相关资讯,希望看官们能喜欢,我们快快来了解一下吧!先看几个问题:
为什么有的编程规范要求用 void 0 代替 undefined?字符串有最大长度吗?0.1 + 0.2 为什么不等于 3?ES6 新加入的 Symbol 是什么?为什么给对象添加的方法能用在基本类型上?
类型
JavaScript 语言的每一个值都属于某一种数据类型。JavaScript 规定了 7 种语言类型:
UndefinedNullBooleanNumberStringObjectSymbol
undefined、null
问题一:为什么有的编程规范要求使用void 0 代替 undefined?
Undefined 类型表示未定义,只有一个值即 undefined。任何变量在赋值前都是 Undefined 类型,值为 undefined。
一般我们可以用全局变量 undefined(即名为 undefined 的这个变量)来表示这个值,或者使用 void 运算,来把任意一个表达式变成 undefined 值
但因为 JavaScript 中 undefined 是一个变量,而非一个关键字,所以为了避免无意中被篡改,建议使用 void 来获取 undefined.
Undefined 跟 null 有一定的表意差别。null 表示定义了但为空。所以在实际编程中,我们不会把变量赋值为 undefined,这样可以保证所有值为 undefined 的变量,都是从未赋值的自然状态。
Null 类型也只有一个值就是 null,他的语义表示是空值,与 undefined 不同,null 是 JavaScript 关键字,故在任何代码中,都可以放心使用 null 关键字来获取 null 值
Boolean
Boolean 类型有两个值,true 和 false,用于表示逻辑意义上的真和假。
String
String 用于表示文本数据。String 有最大长度是 2^53 - 1。
String 的意义并非“字符串”,而是字符串的 UTF16 编码,我们字符串的操作charAt、charCodeAt、length等方法针对的都是 UTF16 编码。所以,字符串的最大长度,实际上是是受字符串的编码长度影响的.
Number
JavaScript 中的 Number 类型有(2^64 - 2^53 + 3)个值。
JavaScript 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,但 JavaScript 为了表达几个额外的语言场景(如不让除以 0 出错,而引入了无穷大的概念),规定了几种例外的情况:
NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;Infinity, 无穷大;-Infinity,负无穷大;
值得注意的是,JavaScript 中有+0 和-0,在加法类运算中它们没有区别,但除法的场合需要特别留意。区分+0 和-0 的方式:检测 1/x 是 Infinity 还是-Infinity
根据双精度浮点数的定义,Number 类型中有效的整数范围是 -0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 无法精确表示此范围外的整数。
为什么在 JavaScript 中,0.1 + 0.2 !== 0.3?
console.log(0.1 + 0.2 === 0.3) // false
根据浮点数的定义,非整数的 Number 类型无法用 == (===也不行)来比较
正确的比较方法是使用 JavaScript 提供的最小精度值:
const abs = Math.abs(0.1 + 0.2 - 0.3)
console.log(abs <= Number.EPSILON ) // true
检查等式左右两边差的绝对值是否属于最小精度,才是比较浮点数的正确方法。
Symbol
ES6 引入的新类型,它是一切非字符串的对象 key 的集合。
// 创建Symbol类型变量
var mySymbol = Symbol('my symbol')
Object
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。
在 JavaScript 中,对象的定义是“属性的集合”。属性分为数据属性和访问器属性,二者都是 key-value 结构,key 可以是字符串或者 Symbol 类型。
JavaScript 中的“类”仅仅是运行时对象的一个私有属性,而 JavaScript 是无法自定义类型的。
JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”
NumberStringBooleanSymbol 所以 3 !== new Number(3), 3 是一个 Number 类型数据,而 new Number(3)是一个对象类型
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,他们表示强制类型转换。
JavaScript 语言上设计试图模糊对象和基本类型间的关系,所以我们日常代码可以把对象的方法在基本类型上使用,如:
console.log('abc'.charAt(0)); // a
甚至在原型上添加方法,都可以基于基本类型,如下,在 Symbol 原型上添加了 hello 方法,在任何 Symbol 类型变量都可以调用
Symbol.prototype.hello = ()=>console.log('hello')
var a = Symbol('a')
console.log(typeof a); // symbol, a并非对象
a.hello() // hello
所以:为什么给对象添加的方法能用在基本类型上?因为==.运算符==提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法。
类型转换
因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换,然后运算。
StringToNumber
字符串到数字的类型转换,存在一个语法结构,类型转换支持十进制、二进制、八进制和十六进制
var a = '111sdfsf'
Number(a) // NaN
parseInt(a) // 111
parseFloat(a) // 111
var b = '1112'
var numb = +b // 1112
parseInt 会忽略非数字字符,不支持科学计数法。
建议在任何环境下,都传入 parseInt 的第二个参数,明确指定转换的进制数,以免出现错误
而 parseFloat 则直接把源字符串作为十进制来解析,他不会引入任何的其他进制,可以放心使用
NumberToString
var a = 111
var stra = a + ''
装箱操作
每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,就是把基本类型转换为对应的对象,他是类型转换中一种相当重要的种类
对于全局 Symbol 函数无法使用 new 类调用,但我们可以利用函数的 call 方法来强迫其产生装箱操作。
var symbolTest = Symbol('a')
var symbolObject = (function(){return this;}).call(symbolTest)
console.log(typeof symbolObject) // object
console.log(symbolObject instanceof Symbol) // true
console.log(symbolObject.constructor === Symbol) // true
装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型进行装箱转换
每一类装箱对象皆有私有的 Class 属性,这些属性可以使用 Object.prototype.toString 获取
var symbolObject = Object(Symbol('a'))
console.log(Object.prototype.toString.call(symbolObject)) // [object Symbol]
在 JavaScript 中,没有任何方法可以更改私有的 Class 属性,因此Object.prototype.toString是可以准确识别对象的基本类型的方法,比 instanceof 更加准确
拆箱转换
在JavaScript标准中,规定了ToPrimitive函数,它是对象类型到基本类型的转换(即,拆箱转换)
对象到String和Number的转换都遵循了先拆箱再转换的规则。通过拆箱转换,把对象变为基本类型,再从基本类型转换为对应的String或者Number。
拆箱转换会尝试调用valueOf和toString来获得拆箱后的基本类型。如果valueOf和toString都不存在,或者没有返回基本类型,则会产生类型错误 TypeError
var o = {
valueOf: ()=> {console.log("valueOf"); return {}},
toString: ()=>{console.log('toString'); return {}}
}
o * 2
// valueOf
// toString
// TypeError
上面代码中先执行了valueOf方法,然后执行了toString方法,最后抛出了一个TypeError,说明这个拆箱转换失败了。
喜欢的话,记得关注我的公众号哦!
你的喜欢是我坚持的动力!
标签: #js不属于基本类型的是