JavaScript类型:关于类型,有哪些你不知道的细节?

更新日期: 2019-03-05 阅读: 3k 标签: 类型

undefined和null

Undefined类型表示未定义,它的类型只有一个值为undefined。任何变量在赋值前都是undefined类型,值为undefined。但是JS中undefined是一个变量,并非是一个关键字,为了避免无意中的篡改,使用void 0来获取undefined值。

undefined和null有一定的表意差别,null表示“定义了但是为空”,它只一个值为null,并且是JS关键字,可以放心使用。


Number

非整数的Number类型无法使用 == 或 === 来比较,有一段著名的代码

console.log(0.1 + 0.2 == 0.3);

输出结果是false,说明两边不等,这是浮点运算的特点,浮点数运算的精度问题导致等式左右并不是严格相等,而是相差了个微小的值。

正确的比较方法是使用JS提供的最小精度值:

console.log(Math.abs(0.1 + 0.2 -0.3) <= Number.EPSILON);

检查等式左右两边差的绝对值是否小于最小精度值,才是正确的比较浮点数的方法。


类型转换

因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换。大部分类型转换符合人类的直觉,但是如果我们不去理解类型转换的严格定义,很容易造成一些代码中的判断失误。其中最为臭名昭著的是 JS 中的“ == ”运算,因为试图实现跨类型的比较,它的规则太过复杂。很多实践中推荐禁止使用“ ==”,而要求程序员进行显式地类型转换后,用 === 比较。

parseInt 和 parseFloat 是很常用的类型转换的方法。在不传入第二个参数的情况下,parseInt 只支持 16 进制前缀“0x”,而且会忽略非数字字符,也不支持科学计数法。在一些古老的浏览器环境中,parseInt 还支持 0 开头的数字作为 8 进制前缀,这是很多错误的来源。所以在任何环境下,都建议传入 parseInt 的第二个参数,而 parseFloat 则直接把原字符串作为十进制来解析,它不会引入任何的其他进制。

多数情况下,Number 是比 parseInt 和 parseFloat 更好的选择。


装箱转换

每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱。我们定义一个函数,函数里面只有 return this,然后我们调用函数的 call 方法到一个 Symbol 类型的值上,这样就会产生一个 symbolObject。

我们可以用 console.log 看一下这个东西的 type of,它的值是 object,我们使用 symbolObject instanceof 可以看到,它是 Symbol 这个类的实例,我们找它的 constructor 也是等于 Symbol 的,所以我们无论哪个角度看,它都是 Symbol 装箱过的对象:

    
var symbolObject = (function(){ 
    return this; 
}).call(Symbol("a"));

console.log(typeof symbolObject);         //object
console.log(symbolObject instanceof Symbol);     //true
console.log(symbolObject.constructor == Symbol);    //true

装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换。

使用内置的Object函数,可以在JS代码中显式的调用装箱能力。

var symbolObject = Object((Symbol("a"));

console.log(typeof symbolObject);         //object
console.log(symbolObject instanceof Symbol);     //true
console.log(symbolObject.constructor == Symbol);     //true

每一类装箱对象皆有私有的Class属性,这些属性可以用Object.protoype.toString获取:

var symbolObject = Object((Symbol("a"));
console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]

JS中,没有方法可以更改私有的Class属性,因此Object.prototype.toString是可以准确识别对象对应的基本类型的方法,它比instanceof更加准确。

但需要注意的是,call 本身会产生装箱操作,所以需要配合typeof来区分基本类型还是对象类型。


拆箱转换

JS标准中,规定了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

我们定义了一个对象 o,o 有 valueOf 和 toString 两个方法,这两个方法都返回一个对象,然后我们进行 o * 2 这个运算的时候,你会看见先执行了 valueOf,接下来是 toString,最后抛出了一个 TypeError,这就说明了这个拆箱转换失败了。

到 String 的拆箱转换会优先调用 toString。我们把刚才的运算从 o*2 换成 o + “”,那么你会看到调用顺序就变了。

var o = {
    valueOf : () => {console.log("valueOf"); return {}},
    toString : () => {console.log("toString"); return {}}
}
 o + ""
// toString
// valueOf
// TypeError



本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/2233

相关推荐

Js如何将String转化为Int

字符串到整型的一个转换,在面试过程中或者在工作中都会频繁遇到,那么string到js怎么转换呢 ?parseInt方法在format\'00\'开头的数字时会当作2进制转10进制的方法进行转换

Typescript内置类型与自定义类型

大家用过 Typescript 都清楚,很多时候我们需要提前声明一个类型,再将类型赋予变量。例如在业务中,我们需要渲染一个表格,往往需要定义:

Js实现base64,file和blob相互转换

JavaScript实现base64,file和blob相互转换:base64转为Blob;Blob转为base64;base64转换为file;js图片转换为base64;在Java中base64和File相互转换

Js的6种基本数据类型

在JS中一共有六种数据类型 String:字符串 Number:数值 Boolean:布尔值 Null:空值 Undefined:未定义 Object:对象 ,其中String,Number,Boolean,Null,Undefined属于基本数据类型而Object属于引用数据类型

JavaScript判断字符串是否为数字类型

JavaScript中有Number.isInteger可以判断一个字符串是否为整数。不过目前JS没有内置的函数来判断一个数字是否为包含小数的数字:

TypeScript never 类型

在类型理论(数学逻辑中的一种理论)中, 底部类型 是没有值的类型。也称为零或空类型,有时用 falsum(⊥)表示。 数学理论与计算机的发展是相辅相成的,底部类型在计算机科学中也有一定的应用场景。

JS数据类型转换表

下表显示了将不同的JavaScript值转换为Number,String和Boolean的结果:注意:引号(\\\"\\\")中的值表示字符串值。在红色的值是程序员可能不希望被转换为的值。

Js的typeof返回哪些数据类型?

JavaScript中的数据类型:值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。引用数据类型:对象(Object)、数组(Array)、函数(Function)。

为你的 JavaScript 项目添加智能提示和类型检查

近在做项目代码重构,其中有一个要求是为代码添加智能提示和类型检查。智能提示,英文为 IntelliSense,能为开发者提供代码智能补全、悬浮提示、跳转定义等功能,帮助其正确并且快速完成编码。

JS中的布尔 数字 字符串

JS中所有的值都可以转换成布尔类型 使用Boolean()或者 !!(两个感叹号),JS中所有的值都可以转换成数字类型,使用Number()或+。数字类型转换场景目的只有一个,用于计算,将后台传递的数据,从字符串转换为数字并参与计算

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!