第二章 值
数组
在JS中数组的功能是十分强大的,与其他语言不同的是:
- 数组中的值可以是不同类型的,如 var a = [1,‘2’,[3]];
- 在JS中栈和队列都是通过数组实现的,相关的方法有push(),pop(),shift(),unshift()
- 在JS中数组也是一个对象,因此你可以给通过键值对赋值,如 a[‘name’] = ‘zhangsan’; 但这些键值对是不算在length长度中的,还有如果键名为数值的字符串表示,如a[‘13’], 那么这个‘13’会被强制转为数值的
- 数组可以声明后,再向其中加入值,如 var a = []; a[12] = 1; 那么a的长度为13,其中a[12]之前的都是空值, a[1] == undifined; //true
此外,在JS中还存在类数组对象, 如DOM操作中的ListNode, 函数参数中的arguments,这些对象都输数组类型,但是都有包含length 属性,以及通过数字索引存放值。 在ES6中可以使用Array.from() 转为数组类型。
字符串
在JS中还有一个与数组类似的类型就是字符串类型,在JS中你可以数组一样操作字符串(一些场景上)
- for-of
在JS中你可以通过for-of 遍历字符串上的每一个字符 - length() 方法
可以返回字符串的长度,遍历也可以这么写:
var str = "abc";
for(let i = 0; i<str.length;++i){
console.log(i); // a b c
}
- indexOf() 查询值所在的索引
- concat() 连接两个字符串
尽管一些方法上存在类似,但字符串和数组还是存在本质的区别的。在JS中字符串是一个不可变的值,而数组是可变的。不可变的意思是指字符串的成员函数不会改变其原始值,而是创建一个新的字符串。但数组的成员函数都是在原始值上进行操作的。
一些数组函数用于处理字符串很方便,虽然字符串没有这些函数,但是可以“借用”数组中的非变更方法处理字符串如:
var a = "foo";
var b = Array.prototype.join.call(a,"-"); // "f-o-o"
数字
在JS中数字是用个IEEE754标准中的双精度来实现的,一共64位(一位符号位,10位阶码,53位尾数)。
跟其他采取IEEE754标准的语言一样,会存在浮点数精度丢失的问题,即 0.1+0.2 == 0.3 // false. 因此在进行浮点数运算时需要特别注意,最常见的方法是设置一个误差范围值,通常称为“机器精度”,对于JS来说一般是2^-52. ES6中该值定义在Number.EPSILON中。
funciton isEqual(v1,v2){
return Math.abs(v1-v2)<Number.EPSILON;
}
var a = 0.1, b = 0.2, c = 0.3;
isEqual(a+b,c); // true
特殊数值
在JS中存在一些特殊的值需要特别注意
不是值的值
undefined类型只有一个值,即undefined。null类型也只有一个值null。它们的名称既是类型也是值。
两者一般都是用来表示“空”值或“不是值”的值。但这两者还是有细微区别。
- null 一般指空值(曾赋过值,但目前没有值)
- undefined 指没有值(从未赋过值)
undefined可以通过void 运算符得到。
不是数字的数字
- NaN
NaN 指的是“Not a Number”,一般是在运算时,无法返回一个有效的数字时会返回NaN,如 0/“foo”.
此外,NaN 是唯一个非自反的值。即 NaN !== NaN 成立。
- 无穷值
在JS中数值溢出,则会通过无穷值表示, 如 var a = 1/0 ; a 为Infinity。 Infinity 表示正无穷, 负无穷为:-Infinity。
在进行这些特殊值判断时,可以通过ES6中一个工具函数,Object.is(),来判断这两个值是否绝对相等。
值和引用
JS中赋值操作可以分为简单值赋值和引用赋值。简单值赋值指的就是那些基本值的赋值操作如,数值、字符串、布尔值、Symbol、null和undefined。引用赋值指的是那些对象的赋值,如Object、函数、数组等。
其最大的区别在于简单赋值是完全copy一份新的,你在这上面怎么操作都不会影响到之前那份。但引用赋值指向的还是同一份对象,相当于多了个入口可以访问修改这个对象。