类型  

  首先明确一点,Js中的类型是针对值来说,而不是针对变量,值就是所谓的42, 'abc', false 等能用js 操作的数据。在js 中说某某某是什么数据类型,其实是说的这些值是什么类型。值呢?有7种数据类型: number, string, boolean, null, undefined, object, symbol. 42 就是number 类型了。怎么判断出来的,最简单的办法就是typeof 操作符了,它返回一个字符串来表示类型

console.log(typeof 42); // 'number'

  这时,你可能想到,不对啊,以前也用typeof 操作过变量啊?也返回类型了啊。

let a = 42
console.log(typeof a); // 'number'

  其实这里仍然是对值进行的类型判断,因为你不能说变量a就是number 类型,因为 js 是弱类型语言,完全可以把重新赋值为一个变量。

let a = 42
console.log(typeof a); // 'number'
a = 'str';
console.log(typeof a); // 'string'

  这时,你就说不出变量a 是什么类型了。在js 中,如果对一个变量进行typeof 操作,一定是对当时变量所指向或所包含的值进行typeof 操作,变量没有类型,值有。

  但使用typeof 进行类型判断的时候,它有一个bug, typeof null 返回的是'object' 而不是'null'.  null 值是'null' 类型的唯一值,它竟然返回了'object'. 这时,如果你就想用typeof 操作符来判断一个值是不是null, 你就要再加一个判断了。只有对象和null 执行typeof 操作时候,才返回'object', 只要找出二者的不同就可以了,很简单,所有对象都是真值,null 是假值,!a 是true 就可以区分了。所以使用typeof 判断null的时候,如下

let a = null;
(!a && typeof a === 'object') // true

  其时 typeof 还一个小问题,就是typeof 一个函数的时候,返回的是一个'funciton',

let a = () => {};
console.log(typeof a); // 'function'

  这可能让人产生误会,误以为'funciton' 也是一种数据类型,其实并不是,所有的函数都是对象,不过这也提供了一个判断函数的简便方法。

  当然,typeof 操作符还有一个好处,就是如果一个变量没有声明的话,执行typeof 操作,不会报错,而是返回undefined, 这就是提供了一个安全的操作,因为,如果你直接引用一个没有声明的变量就会报错。有时,你想判断一个变量存不存在,如要写a == undefined, 完了,报错了,引用了一个没有声明的变量a. 如果使用 typeof a == undefined, 没有问题。

  Number类型

  Js 中,只有一种数字类型,就是Number, 实际上它是双精度的浮点型,在其它语言中称为double,也就是说Js 中没有整数类型, 所谓的整数只不过是没有小数,或小数后面全是0,如42 或42.00。 默认情况下, 数值的输出方式,都是10进制,并且会把末尾的0 去掉。

var a = 42.300;
var b = 42.0;
console.log(a); // '42.3'
console.log(b) // 42

  但是如果一个数特别大或特别小的话,它会以指数形式进行输出,在chrome 浏览器中,只要整数大于20次方,它就会转化为指向,小数的话,只要后面有7位,就会转化为指数

var a = 5000000000000000000000;
var b = 0.0000005;
console.log(a); // 5e+21
console.log(b) // 5e-7

  使用浮点数来表示数值时,它有一个问题, 就是0.1 + 0.2 === 0.3 为false. 计算整数的时候,没有问题,计算小数就有可能出问题,那怎么办法?怎么才能让0.1 + 0.2 和0. 3 进行比较的时候,表示相等呢?一种是办法是设置一个容错的边界, 当小于这个值 的时候,就表示这两个值相等了,这个值在js 中是2的-52 次方Math.pow(2,-52),Es6 专门定义了这个常量Number.EPSILON,  只要两者进行比较小于这个数,就证明这两个值相等。

// 无限接近相等
function isCloseEnoughToEqual(n1,n2) {return Math.abs( n1 - n2 ) < Number.EPSILON;
}
let a = 0.1 + 0.2;
let b = 0.3
console.log(isCloseEnoughToEqual(a, b)) // true

  计算整数没有问题,这个整数也是有边界的, 对于double双精度浮点数,用 1 位表示符号,用 11 位表示指数,52 位表示尾数,所以浮点数表示的最大整数是2的53次方-1(Math.pow(2, 53))最小整数是-2的53次方, 即[-2^53, 2^53 - 1], 超出了这个边界,计算也是不准确

let a = 9007199254740992; // 2^53
let b = a + 1;
console.log(a == b) // true

  a + 1 和a 是相等的,所以出现了问题了。为些,Es6 定义了安全数值 的字面量和判断安全数值的方法 Number.MAX_SAFE_INTEGER, Number.MIN_SFTE_INTEGER

以及Number.isSafeInteger(); 当然也提供了判断整数的方法Number.isInteger();

let a = 9007199254740991; // 2^53 -1
let b = a + 1;
console.log(Number.isSafeInteger(a)) // true
console.log(Number.isSafeInteger(b)) // false
console.log(Number.isInteger(a)) // true
console.log(Number.isInteger(b)) // true

  a 和 b 都是整数,但a 是安全整数,b 不是

  Number 类型中的特殊值--- NaN。当我们执行算术操作的时候,这个操作并没有成功,按理说,它应该报错,但是Js 并不会,而是返回特殊的值NaN。

let a = 2 / 'foo';
console.log(a ) // NaN

  我们怎么判断值是NaN, 可能最简单的就是 它=== NaN, 但是很不幸,NaN 和它本身并不相等,NaN === NaN 返回的是false. 其次还有一个isNaN 的函数来判断NaN, 但是它也有点问题,传给isNaN的参数,首先会进行自动类型转化,看能不能转化成数字,如能就是返回true, 如果不能返回false.

let a = 2 / 'foo';
console.log(isNaN(a)) // true
let b = 'foo';
console.log(isNaN(b)) // true

  可以看到 b 不是NaN, 但是isNaN 仍然返回了true, 也就是说,即使isNaN() 返回了true, 我们也不能确定这个值是不是NaN。为了解决这个问题,ES6增加了Number.isNaN(), 如果值为NaN, 它返回ture ,否则返回false.

let a = 2 / 'foo';
console.log(Number.isNaN(a)) // true
let b = 'foo';
console.log(Number.isNaN(b)) // false

  Number.isNaN() 是怎么判断的呢?首先它判断这个值是不是number 类型,NaN 作为值,它其实是number 类型

let a = 2 / 'foo';
console.log(typeof a === 'number') // true

  其次才是调用isNaN 方法来判断。

  Number 类型中的特殊值--- +0 和-0.  Js 中的0 有两个,+0 和-0. 除了字面量的方式可以得到-0 外,使用* 或 / 操作符,也可以得到,但+ - 操作符不能。

let a = -1 * 0;
let b = 0 / -1;
console.log(a, b) // -0

  有两个0 也不要紧,但是它有几个奇怪的行为

    1, +0 和 -0 使用== 或=== 比较的时候,是相等。

let a = -0;
let b = 0
console.log(a === b) // true

  其实它两个是不相等,所以ES6 增加了Object.is() 方法,来判断它两个并不相等。

  2, -0 转化成字符串的时候,输出的结果是‘0’ ,而是不-0. JSON.stringify(-0) 也是得到'0'

let a = -0;
console.log(a.toString()) // '0'console.log(JSON.stringify(a)) // '0'

  然而当一个'-0' 字符串转化数字的时候,它返回的是-0, 正常的。

+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0

  null 和undefined

  null 是一个关键字,不能用它作为变量名,更不能给它赋值,但undefined 不是,它可以是一个标示符,可以给它赋值,当然,这仅限在非严格模式,如果是严格模式的话,会报错。

 var undefined = 2;

 "use strict";
var undefined = 2; // 报错

  由于undefined 可以被改写,有一个void 操作符,它后面可以是任何表达式,返回的值是undefined, 不过一般使用 void 0, 这样undefined 就不会被改写了。

console.log(void 0 === undefined) // true

  对象(引用类型)

  如果一个值执行typeof 操作返回 ‘object’,那么它就是引用类型,其实,还可以进行细分,它具体是对象下面的哪一个类型,数组,还是函数,使用的是Object.prototype.toString.call(值)

let a = [1,2];
let b = function(){};
let c = new Date();console.log(Object.prototype.toString.call(a)) // '[object Array]' Array 类型
console.log(Object.prototype.toString.call(b)) // '[object Function]' Function 类型
console.log(Object.prototype.toString.call(c)) // '[object Date]' Date 类型

  那对基本数据类型调用toString() 方法呢?它返回基本类型的包装类型,甚至对null, undefined 都可以调用, 返回值如下

console.log(Object.prototype.toString.call(1)) // '[object Number]'
console.log(Object.prototype.toString.call('abc')) // '[object String]'
console.log(Object.prototype.toString.call(false)) // '[object Boolean]'
console.log(Object.prototype.toString.call(null)) // '[object Null]'
console.log(Object.prototype.toString.call(undefined)) // '[object Undefined]'
console.log(Object.prototype.toString.call(Symbol())) // '[object Symbol]' 

  数组类型

  1, 删除数组元素的时候,不要用delete, 使用delete 可以把数组中的元素及元素在数组中的位置(slot)删除掉, 但不用更新数组的length 长度。

let a = [1, 2];
delete a[0];
console.log(a);
console.log(a.length)

  下图是chrome 浏览器的返回值。

  可以使用splice() 进行删除

  2, 不要创建稀疏数组。当创建稀疏数组的时候,两个不相邻元素之间的slot 是不存在的,a[0] 和a[2] 之间并没有slot, 尽管获取到它的值是undefined

var a = [ ];
a[0] = 1;
// 没有 a[1] slot
a[2] = 3;
a[1]; // undefined
a.length; // 3

  当我们使用构造函数创建数组时, 给它传递一个数字,它就会创建length 为参数的数组,这个数组其实也是一个稀疏数组. 比如,你传递了一个3,那么创建的数组的length 为3,我们以为这个数组有了3个slot, 值为undefined, 其实它没有任何的slot. 当你使用forEach 的时候,什么都没有输出

arr.forEach((item, index) => {console.log(item);console.log(index);
})

  3, 尽管数组是对象,但千万不要作为对象进行使用,比如 a["name"] = 'Sam', 尤其是属性是数字字符串的时候,这时它会把字符串转化为数字,作为数组的元素

let a = [];
a['5'] = 5;
console.log(a.length) // 6

  类型转化

  首先要记住的是,Js中的类型转化,它得到的结果永远是基本类型,也就可以分为两种情况,基本类型和基本类型之间的转化,引用类型转化为基本类型,不可能出现基本类型转化为引用类型。类型转化出现最多就是转化成number, string, 和boolean. 这就是说,我们在学习类型转化的时候,也要分为两种情况去学,比如转化成string,  基本类型是怎么转化string的,引用类型是怎么转化成string的。

  

  

  

转载于:https://www.cnblogs.com/SamWeb/p/10984301.html

JS 中类型和类型转换相关推荐

  1. JS基础类型和引用类型

    JS基础类型和引用类型脑图

  2. 《js中原型和原型链的深入理解》的笔记

    前言:在微信公众号前端大全上看过<js中原型和原型链的深入理解>,个人认为这是我看过的js原型链的文章中,在思维结构上理解最清楚的一个文章了,本着温故而知新,有害怕找不到这个文章,我就把文 ...

  3. JS 之 数据类型转换

          首先我们来简单了解一下JS中的数据类型,JavaScript拥有字符串.数字.布尔.数组.对象.Null.Undefiend 6中数据类型.同一时候,JavaScript拥有动态类型. 也 ...

  4. 【JS基础】类型转换——不同数据类型比较

    小试牛刀 输出下列数据比较结果 [] == 0; //==============================================================true[] == f ...

  5. java和Js中的类型转换_JavaScript 类型转换

    原标题:JavaScript 类型转换 Number() 转换为数字, String() 转换为字符串, Boolean() 转化为布尔值. Java 数据类型 在 Java 中有 5 种不同的数据类 ...

  6. 前端 js 将字符串类型转换成其他类型

    方法一 eval(argStr) 函数,一般传入任何参数都能强转成对应类型.如果想把参数先转成字符串再使用 eval 转成真实类型,可以使用 String() 函数进行强转,String(argObj ...

  7. 深入理解js基本类型和引用类型的区别

    1.基本类型: 我们知道基本的数据类型有:undefined,boolean,number,string,null.按值访问,可操作保存在变量中的实际的值.基本类型值指的是简 单的数据段. 基本类型的 ...

  8. 前端开发:JS中原型和原型链的介绍

    前言 在前端开发过程中,涉及到JS原理相关的内容也就是常用的几大模块,不仅常用而且很重要,但是涉及到原理的话会有点难懂,尤其是对JS接触不太久的开发者来讲.本篇博文就来分享一下关于JS的原型和原型链相 ...

  9. JS 中原型和原型链深入理解

    作者: erdu segmentfault.com/a/1190000014717972 首先要搞明白几个概念: 函数(function) 函数对象(function object) 本地对象(nat ...

最新文章

  1. 一文概述2017年深度学习NLP重大进展与趋势
  2. [Abp vNext 源码分析] - 18. 单元测试
  3. 软件测试:职场上那些你不得不学会的事儿
  4. 为什么我推荐你立刻使用Java 8 Stream?性能逆天了
  5. ironpython使用dictionary_Ironpython引用C#数据结构
  6. 软件推荐┊最有效防止被聚生网管、P2P终结者等管理软件控制的小工具——ARP防火墙单机版...
  7. 摩尔庄园手游服务器链接不稳定,摩尔庄园手游公测常见问题解决方法一览
  8. 新手村-数组-P2141 珠心算测验
  9. 大学计算机课程制作生日卡片,计算机《制作生日贺卡》教学设计.doc
  10. R语言McSpatial_R语言天气可视化应用
  11. 利用Xshell映射云端服务器的visdom,进行训练过程可视化
  12. 2022智源大会议程公开 | 神经计算与生物智能论坛
  13. UE4开关门简单记录
  14. EOJ Monthly 2020.11 Sponsored by TuSimple F题“天桥”题解
  15. 单链表删除元素之狸猫换太子法
  16. Apache shiro 漏洞总结
  17. Smith Chart - for myself
  18. mapreduce软件框架中作业与任务的含义
  19. wordpress 邀请码注册插件 Ashuwp invitaion code
  20. st7735s SPI驱动显示图标

热门文章

  1. Smali 语法文档
  2. Android 中Base64的操作
  3. Redis 中两种持久化机制详解
  4. 【PyQt5】连接 mysql 查询数据 并显示在 tableWidget 表格
  5. 一篇文章总结暴力破解方法大全
  6. Linux系统管理(9)——系统状态监控命令top使用详解
  7. 结构化思维:掌握这3点,分析报告不再愁
  8. 那些让老板赞不绝口的可视化大屏,附模板和教程
  9. 一文讲透数据库,以后别说你不懂数据库
  10. 如何从0开始,搭建企业的实时数据中台?