资讯专栏INFORMATION COLUMN

JavaScript基础系列--数据类型及类型判断

duan199226 / 3258人阅读

摘要:中有五种基本数据类型,以及一种复杂引用类型数据类型,中还细分了很多具体的类型,比如等等中又新增了一种类型。类型的数值范围是,超出这个范围的值为,可以使用函数来判断数值是否在范围内。

ECMAScript5中有五种基本数据类型:Undefined,Null,Boolean,Number,String,以及一种复杂(引用类型)数据类型:ObjectObject中还细分了很多具体的类型,比如:Array, Function, Date等等;ECMAScript6中又新增了一种Symbol类型。

typeof操作符

typeof是操作符,而不是函数,它可能返回:

"undefined":如果这个值未定义

"boolean":如果这个值是布尔值

"string":如果这个值是字符串值

"number":如果这个值是数值

"object":如果这个值是对象或者null

"function":如果这个值是函数

"symbol":如果这个值是Symbol

函数在ECMAScript中是对象,不是一种数据类型;但是函数却也有一些特殊的属性,所以通过typeof来区分对象和函数是有必要的

Undefined类型

Undefined类型只有一个值 —— undefined,当一个变量仅声明而未初始化时,这个变量的值就是undefined(当一个变量未声明(未定义)时,如果访问它将会报错)

var a;
let b;
console.log(a,b);//undefined undefined
console.log(c);//ReferenceError: c is not defined

ES6之前,typeof是一个百分之百安全的操作,因为即使是对于未声明的变量,typeof会返回"undefined",而不会报错。

但是ES6引入了let,const来声明变量,这两个命令没有声明提升,一定要在声明语句之后才能使用,否则就会报错;而且let,const还存在暂时性死区

只要块级作用域内存在let或const命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
ES6 明确规定,如果区块中存在let或const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量,就会报错
let tmp = 123;

if (true) {
  tmp = "abc"; // ReferenceError: tmp is not defined
  let tmp;
}

上面的代码中存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

所以“暂时性死区”也意味着typeof不再是一个百分之百安全的操作,这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就报错

Null类型

Null类型只有一个值 —— null,从逻辑角度来看,null表示一个空对象指针,这也是用typeof操作符检测null会返回"object"的原因。

undefined值是派生自null值的,所以undefined == null会返回true,但是它们两者的用途完全不同。

只要意在保存对象的变量还没有真正保存对象,就应该让该变量保存null值,这样做不仅可以体现null作为空指针对象的惯例,还有助于区分nullundefined

Boolean类型

Boolean类型有两个字面值,表示真的true和表示假的falseECMAScript中所有类型的值都有与这两个Boolean值等价的值,可以通过Boolean()函数转换

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""空字符串
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined 不适用 undefined
Symbol 任何 不适用
Number类型

Number类型的数值字面量格式有八进制(严格模式下使用八进制将会报错)、十进制和十六进制,其中八进制字面值的第一位必须为0,十六进制前两位必须为0x。在进行算术计算时,八进制和十六进制都会转换为十进制。

Number类型使用IEEE754标准定义的64位浮点数表示,存储为8字节,使用时不区分整数与浮点数,1与1.0是一样的,存储情况如下:

符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负

指数位E:中间的 11 位存储指数(exponent),用来表示次方数

尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍零

其中尾数位即有效数字部分,IEEE754规定,有效数字第一位默认总是1,即有效数字总是1.xx...xx的形式,其中第一位不进行存储,而xx..xx的部分保存在64位浮点数之中,最长可能为52位。因此,JavaScript实际提供的有效数字最长为53个二进制位,一个数字可以表示为:

(-1)^符号位 * 1.xx...xx * 2^指数位

有效数字精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即在-(Math.pow(2, 53) - 1Math.pow(2, 53) - 1范围内的整数都可以精确表示(安全整数),而不在该范围内的整数则会丧失精度。

es6中增加了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER来表示安全整数范围的上下限,还增加了方法Number.isSafeInteger来判断是否处于安全整数范围内。

浮点数的最高精度是17位小数,但是计算时的精度远远不如整数,浮点数值计算会产生舍入误差的问题,这是使用基于IEEE754数值的浮点计算的通病,所以永远不要测试某个特定的浮点数数值

Number类型的数值范围是Number.MIN_VALUE ~ Number.MAX_VALUE,超出这个范围的值为Infinity,可以使用isFinite()函数来判断数值是否在范围内。

Number类型有一个特殊的值——NaN(Not a Number)

他表示一个本来要返回数值的操作数却未返回数值的情况,NaN是数字类型 但是不是数字,他有两个特点

任何涉及NaN的操作都会返回NaN

NaN与任何值都不相等,包括它自己

0处于0返回NaN,其他的除以0返回infinity-infinity

NaN的布尔值是false

isNaN()函数可以判断传入的参数是否“不是数值”,判断前会自动调用Number()进行转换,转换后再进行判断,任何不能转换为数值的值都会导致这个函数返回true;这个函数也适用于对象,在基于对象调用它时,会先调用对象的valueOf()方法,然后确定该方法的返回值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,再测试返回值

有以下几种方法可以把非数值转换为数值

Number()函数

可以用于任何类型,包括对象

如果是undefined值,返回NaN

对于字符串,数字的前导0会忽略,如果字符串包含了除数值,0x以外的字符将会返回NaN

如果是对象,先调用对象的valueOf()方法,然后确定该方法的返回值是否可以转换为数值。如果不能,即返回值是NaN,则基于这个返回值再调用toString()方法,再去转换返回的字符串值

parseInt()函数

字符串转整数

忽略字符串前面的空格,直到找到第一个非空格字符,如果第一个字符不是数字字符或者正负号(小数点不是有效的数字字符),返回NaN。所以转换空字符串返回NaN

可以识别并指定进制数,然后按照相应进制数转换为相同大小的十进制。(因为ECMAScript 3ECMAScript 5在解析八进制字面量字符时有分歧,ECMAScript 5 中的parseInt()已经不具备解析八进制的能力,前导0会被忽略,所以最好指定进制数,也就是第二个参数)

parseFloat()函数

字符串转浮点数

忽略字符串前面的空格,直到找到第一个非空格字符,如果第一个字符不是浮点数字字符(字符中第一个小数点是有效的,后面的小数点都是无效的)或者正负号,返回NaN

始终忽略前导0,它只解析十进制值,所以它只有一个参数。如果是十六进制会返回0,因为十六进制的0xparseFloat()函数只会解析到0

字符串里如果是可以解析为整数的数,那会返回整数

~符号(按位非)

按位非的本质是 操作数的负值减1

对于NaNInfinity,应用位操作符会被当做0来处理

console.log(~NaN);// -1
console.log(~Infinity);// -1

非数值应用位操作符时会先使用Number()函数将该值转换为数值,在应用位操作符

console.log(~"12");// -13
console.log(~"w12");// -1

如果是对浮点数应用位操作符,将会对其取整(直接把小数点舍去的这种取整),再应用位操作符

console.log(~1.2);// -2
console.log(~-1.2);// 0

~~符号(两次按位非)

执行两次按位非,可以实现取整效果,直接把小数点舍去的这种取整

++-- ,可以转换数据类型,是按Number()函数来转换的

先将++/--后面的内容按Number函数转换,再加减

var a = "0xf";
a++;
console.lgo(a);// 16

+- 可以转换数据类型,将其他的转为数字类型

Number()函数来转换的

+号前面没有其他东西时,+字符串会按照Number()函数来转换字符串,其他的时候是字符串连接

-转换后,会在转换后的数值前加上负号,所以都是用+好来转换

String类型

String类型表示由零个或多个16Unicode字符组成的字符序列——字符串,JavaScript创建的时候,Unicode是一个16位字符集,所以JavaScript中的字符都是16位的,采用UCS-2编码方式(关于Unicode的知识可以参见)

字符串是不可变的,一旦创建,值就不能改变;要改变就要先销毁原来的字符串(销毁过程在后台完成),再用另一个包含新值的字符串填充该变量

String类型包含一些特殊的字符字面量,比如 , ,,xnn,unnnn等,他们称为转义序列,可以出现在字符串的任意位置,将被当做一个字符来解析;但是如果包含双字节字符,字符串将解析错误,length也将返回错误的结果

var a = "Look this: ";
var b = "Look this: u20BB7";
console.log(a,a.length);//"Look this:  " 12
console.log(b,b.length);//"Look this:  7" 13

为了解决这个问题,ES6中对字符的Unicode表示法做了改进,只要将Unicode码点放入大括号,就能正确解读该字符,但是length属性还是返回错误,若想要正确的可以通过Array.form(xx).length

var b = "Look this: u{20BB7}";
console.log(b,b.length);//"Look this:            
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95534.html

相关文章

  • 三、值类型与引用类型

    摘要:它们的区别之一就是在计算机中的存储方式不同基本类型数据是将变量名及值存储在变量对象中,而引用类型的数据是将变量名和地址存储在变量对象中,真正的值是存储在堆内存中。 showImg(https://segmentfault.com/img/remote/1460000017151449); 说点别的 这是《关于 JavaScript 你必须要知道的 33 个概念 》系列的第三篇文章,今天...

    tinysun1234 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • javascript系列】布尔类型转换

    摘要:基本值原始值原始的布尔类型有两个值和。创建布尔值的方式直接用字面量用函数,将其他任意值转换成对应的原始布尔值。使用两次非运算符,将其转换成对应的布尔类型。下面来看一些将其他类型转换成布尔类型的例子。 基本值(原始值) 原始的布尔类型boolean有两个值: false 和 true。 > typeof false boolean > typeof true boolean 创建布尔值的...

    wangxinarhat 评论0 收藏0
  • JavaScript基础系列---变量其值类型

    摘要:但对于引用类型的数据主要是对象和数组,变量指向的内存地址,保存的只是一个引用地址指针,只能保证这个引用地址指针是固定的,至于它指向的堆内存中的存储的值是不是可变的,就完全不能控制了。 基础概念 变量是存储信息的容器,这里需要区分一下:变量不是指存储的信息本身,而是指这个用于存储信息的容器,可以把变量想象成一个个用来装东西的纸箱子 变量需要声明,并且建议在声明的同时进行初始化,如下所...

    sugarmo 评论0 收藏0
  • javascript知识点

    摘要:模块化是随着前端技术的发展,前端代码爆炸式增长后,工程化所采取的必然措施。目前模块化的思想分为和。特别指出,事件不等同于异步,回调也不等同于异步。将会讨论安全的类型检测惰性载入函数冻结对象定时器等话题。 Vue.js 前后端同构方案之准备篇——代码优化 目前 Vue.js 的火爆不亚于当初的 React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。我们先在代...

    Karrdy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<