值
一:和数组相关的几个需要关注的点
-
数组可以容纳任何类型的值。
-
数组声明时不需要预先设置大小。可以动态改变。
-
使用delete运算符可以将数组中的某个元素删除,但是这个操作不会改变数组的length属性。
var a = [1,2,3]; a[0]; // 1 delete a[0]; // true a.length; // 3 a[0]; // undefined
-
稀疏数组:即含有空白或空缺单元的数组(数组中的某一项为undefined)。
-
我们都知道数组可以通过索引进行取值,但我们也知道数组也是对象,所以我们可以用键值对的方式给数组赋值:
var a = [1,2,3]; a.length; // 3 a.name = 'abc'; a.name; // 'abc' a.length; // 3
如上所示,数组的length属性并不会发生变化,但有一种情况例外,就是如果键的值可以转换为十进制数字的话,那么这个键会被当做索引处理:
var a = [1]; a.length; // 1 a['13'] = 2; a.length; // 14
所以可以看出在数组中存储键值对并不是一个值得推荐的做法,还是用对象好一些。
二、类数组向数组的转换
类数组:一组通过数字索引的值。并非真正意义上的数组,但是非常相似,都是通过数字索引取值,都有length属性。
例如DOM查询操作。我们假设存在一个id为'container'的div元素,且这个div元素含有子元素:
var domContainer = document.getElementById('container');
var nodeList = domContainer.childNodes; // 返回节点类数组,NodeList,也是对象一种子类型
此时的nodeList就是一个类数组。目前的nodeList是无法调用数组的API进行处理的,所以我们需要先将其转换为真正的数组:
var trueNodeArray = [].slice.call(nodeList); // 返回节点数组
// 同上
var trueNodeArray = Array.prototype.slice.call(nodeList);
ES6新增的Arry.form也可以实现这个转换:
var trueNodeArray = Array.from(nodeList); // 从一个类数组或者可迭代对象中创建一个新的数组实例
三、有关字符串和数组相互转换的两个方法
在日常的开发中,我们经常需要将字符串转为数组进行处理并且在处理完后再转为字符串。之所以要进行这个转换是因为将字符串作为数组处理可以调用数组的API,在某些操作上会方便很多。
- String.prototype.split() 可以将字符串转为数组
- Array.from() 同上
- Array.prototype.join() 可以将数组转为字符串
四、undefined、null和NaN
undefined类型只有一个值,即undefined。null类型也只有一个值,即null。
- null指空值。有值,但是值为空。
- undefined指没有值。
NaN是一个数字类型的值。本身没有任何的数学意义,唯一的作用就是告诉,这个数学运算产生了一个非数字的运算结果或者这个运算没有成功,这个结果是数字无法表示的,所以用NaN来表示。需要注意的一点是, NaN != NaN返回值为true。
如果我们需要判断运算结果是不是NaN,可以使用全局工具函数isNaN()。但是这个全局函数有个BUG,那就是非数字类型的值也会返回true。ES6新增的Number.isNaN()修复了这个问题。
五:负零,-0
JS中的0有两种,正0和负0。这两个0在大小上没有任何差别,所以这里的正负号并不是为了体现大小,而是为了体现方向。如果要区分正0和负0,可以通过如下所示的区别来进行区分:
1 / 0 === Infinity; // true
1 / -0 === -Infinity; // true
六:Object.is方法
这个方法被用来判断两个值是否是相同的值。JS提供了三种不同的方式来判断两个值是否相同,详细内容参见——JavaScript中的相等性判断。
这里介绍一下Object.is比较特殊的两个地方:
Object.is(NaN, NaN); // true
Object.is(-0, 0); // false
注意,能使用 == 和 === 的不要使用Object.is方法。因为前者效率更高。Object.is主要用来处理特殊的相等比较,返回你想要的特殊的比较结果。
七:值和引用
在JS中,赋值和参数传递操作传递的值还是引用在语法是没有区别的,完全由值得类型决定。这一点是比较特殊的。
在JS中,简单值总是通过值复制的方式来赋值或是传递的,也就是值传递。包括null、undefined、字符串、数字、布尔和ES6中的Symbol。复合值,也就是对象(包括子类型)和函数,则是通过引用复制的方式传递的,即引用传递。
注:JS中我们是无法自行决定是使用值复制还是引用复制的,一切由值得类型决定。