为了巩固下前面学习的以前学习的知识,所以打算写一个系列的笔记博客,同时对比分析下ES5 和 ES6(泛指ES2015以后的版本)的区别。
今天先来复习下数组。
1.创建数组
方法一:数组直接量
var arr = [];
注意两点:1.直接量中的某个值,省略的元素将被赋予undefined值 2.直接量的语法允许有可选的逗号,故[,,]只有两个元素而非三个。
方法二:调用构造函数
var a = new Array() //创建一个没有任何元素的空数组
var a = new Array(10) //创建一个指定长度的数组
var a = new Array(4,5,6,4) //创建一个指定元素的数组
2.数组元素的读和写
数组是对象的特殊形式,数组的特别之处在于当使用2的32次方的非负整数作为属性名时数组会自动维护其length属性值。所有的索引都是属性名,但只有在0~2的32次方-2之间
的整数名才是索引。
注意:可以使用负数或非整数来索引数组。这种情况下,数值转换为字符串,字符串作为属性名来使用。如果凑巧使用了是非负整数的字符串,它就当做数组索引,
而非对象属性。当使用一个浮点数和一个整数相等的时也将作为数组的索引。
数组索引仅仅是对象属性名的一种特殊类型,这意味着js数组没有‘越界’错误的概念,当查询不存在的对象属性时只会得到undefined,不会报错。
3稀疏数组
稀疏数组就是包含从0开始不连续索引的数组(注意:在直接量中省略值时所得到的数组也是稀疏数组如:[1,,3])
可以用Array()构造函数或简单地指定数组的索引值大于当前数组长度来创建稀疏数组。
4.数组长度
数组有两个特殊的行为:
1.如果为一个数组元素赋值,它的索引i大于或等于现有数组的长度时,length属性的值将设置为i+1;
2.如果设置length属性为一个小于当前长度的非负整数N时,当前数组中那些索引值大于或等于N的元素将从中删除。
5.数组元素的添加和删除
添加:
1.为新索引赋值
2.使用push()方法在数组末尾增加一个或者多个元素
3.使用unshift()方法在数组首部插入一个元素
删除:
1.delete 注意:对一个数组元素使用delete不会修改数组的length属性,也不会将元素从高索引处一下来填充已删除的空白,原数组会变成稀疏数组。
2.设置length属性长度
3.pop()方法,从数组尾部删除一个元素
4.shift()方法,从数组头部删除一个元素
5.splice()通用的方法来插入、删除或替换数组元素
6.数组的遍历
1.for/in循环中不存在的属性名不会得到遍历
2.for/in循环能够枚举继承的属性名,所以在数组上不应该使用for/in循环,除非额外检测
3.ECMAScript规范允许for/in循环以不同的顺序便利对象的属性
7.多维数组
js不支持真正的多维数组,但可以用数组的数组来近似
8.数组的方法
Array.join()可以指定一个可选的字符串在生成的字符串中来分隔数组的各个元素,默认使用逗号
var a = [2, [3, [4,5]]];
a.join();//"2,3,4,5"
Array.reverse()方法将数组中的元素颠倒顺序,返回逆序的数组。
会改变原先的数组。
var a = [1,2,3];
a.resver().join() // '3,2,1' 并且现在的a是[3,2,1]
Array.sort()将数组中的元素排序并返回排序后的数组。
会改变原先的数组
注意:
1.当不带参数调用sort()时,数组元素以字母表顺序排列(如有必要将临时转化为字符串比较)
2.如果数组包含undefined,他们会被包含到数组的尾部
Array.concat()创建并返回一个新的数组,它的元素包括调用concat()的原始数组的元素和concat()的每个参数。
注意:
1.如果这些参数中的任何一个自身是数组,则连接的是数组的元素而非数组本身
2.concat()不会递归扁平化数组的数组
3.不会修改调用的元素
Array.slice()方法返回指定数组的一个片段或子数组。返回的数组包含第一个参数指定的位置和所有到但不包含第二个参数指定的位置之间的所有数组元素。
1.如果指指定一个元素,返回的数组将包含从开始位置到数组结尾的所有元素。
2.如果参数中出现负数,它表示相对于数组中最后一个元素的位置,例如:-1表示最后一个元素
3.不会修改调用的元素
Array.splice()在数组中插入或删除元素的通用方法。在插入或删除点之后的元素会根据需要增加或减小他们的索引值,因此数组的其他部分仍然保持连续
1.会修改调用的数组
2.第一个参数指定了插入或者删除的起始位置
3.第二个参数指定了删除元素个数,如果省略,删除从起始点开始到数组结尾的所有元素
4.第二个元素以后指定了需要插入到数组中的元素(注意:如果元素是数组,splice()会插入数组本身,而非数组的元素)
5.返回由删除元素组成的数组,如果没有删除元素就返回一个空数组
以下四个方法都会修改原始数组:
push()方法在数组的尾部添加一个或多个元素,并返回数组新的长度。
pop()方法删除数组的最后一个元素,减小数组长度,并返回它的删除值。
unshift()在数组头部添加一个或多个元素,返回数组新的长度。注意:参数是一次性插入的,而非一次一个插入
a = [1,2,3];
a.unshift(4,5,6); //[4, 5, 6, 1, 2, 3]
shift()删除数组的第一个元素并返回。
Array.toString()方法将每个元素转化为字符串并且输出用逗号分隔的字符串列表,注意:输出不包括方括号或其他任何形式包裹数组值得分隔符。
9.ES5中的数组方法
概述:
1.ES5中大多数方法的第一个参数接收一个函数,并且对数组中的每一个元素(或一些元素)调用一次该函数,如果是稀疏数组则不调用传递的函数
2.大多数情况下调用提供的函数使用三个参数:数组元素、元素的索引、元素本身;
3.数组方法中如果有第二个参数,则调用的函数被看作是第二个参数的方法
4.ES5中的数组方法都不会修改他们调用的原始数组
forEach()从头至尾遍历数组,为每个元素调用指定的函数。
注意:forEach()无法在所有元素都传递给调用的函数之前终止遍历,也就是说没办法像for循环中使用相应的break语句,如果要提前终止,必须把forEach()方法放在一个try块中,并能抛出一个异常。如果forEach()调用的函数抛出foreach.break异常,循环会提前终止。
map()方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。
注意:如果是稀疏数组,返回的也是相同方式的稀疏数组:它具有相同的长度,相同的缺失元素。
filter()返回的数组元素是调用的数组的一个子集。如果调用函数返回值为true或者能转化为true的值,那么传递给判定函数的元素就是这个子集的成员。
注意:filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密的。可用来压缩稀疏数组
every()和some()是数组的逻辑判定:他们对数组元素应用指定的函数进行判定,返回true或false
注意:一旦every()和some()确认该返回什么值他们就会停止遍历数组。根据数学上的习惯空数组调用every()时返回true,调用some()时返回false.
reduce()和reduceRight()使用指定的函数将数组元素进行组合,生成单个值。
reduce需要两个参数:
第一个参数是执行化简操作的函数,化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值。
第二个参数可选,是一个传递给函数的初始值。
数组元素、元素索引、数组本身将作为第2~4个参数传递给函数。
第一次调用函数时,第一个参数是一个初始值,它就是传递给reduce()的第二个参数。在接下来的调用中这个值就是上一次化简函数的返回值。
如果没有指定初始值,将使用数组的第一个元素作为其初始值,意味着第一次调用简化函数就使用了第一个和第二个数组元素作为其第一个和第二个参数。
注意:
1.在空数组上不带初始值参数调用reduce()将导致类型错误异常
2.数组只有一个元素并且没有指定初始值,或者有一个空数组并且指定一个初始值,reduce()只是简单地返回那个值而不会调用化简函数。
3.reduce和reduceRight()都能接收一个可选的参数,它指定了化简函数调用时的this关键字的值,可选的初始值参数仍然需要占一个位置。
indexOf()和laseIndexOf()搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引如果没有找到就返回-1
第一个参数是搜索的值,第二个参数指定一个索引表示从那里开始搜索(也可以是负数,表示相对数组末尾的偏移量)
注意:字符串也有indexOf方法和laseIndexOf方法。
10.数组类型
ES5中可以用Array.isArray()函数来判断未知对象是否为数组。
ES5以前可用于判断是否为数组的方法:
1.instanceof 只能用于简单的情形,当窗体混淆时一个窗体中的对象将不可能是另一个窗体中的构造函数的实例;
2.Object.prototype.toString.call(o).slice(8) === "Array"
11.类数组对象
拥有一个数值length属性和对应非负整数属性的对象。
ES5中所有的数组方法是通用的,ES3中除了toString和toLocaleString()以外的所有方法也是通用的。
注意:concat()方法是个特例,虽然可以用在类数组对象上,但它没有将那个对象扩充进返回的数组中。
这些方法不能直接调用但是可以用Function.call方法调用。
Firefox浏览器中还将上述方法的版本在Array()构造函数中直接定义为静态函数,当使用类数组对象是这样的方法十分有用。
12.作为数组的字符串
除了charAt()方法来访问单个字符串以外,还可以使用方括号。
注意:字符串是不可变值,故把他们当作数组看待时,他们是只读的。在字符串上调用会修改原数组的方法时,是无效的,而且使用数组方法来修改字符串会导致错误,且出错时没有提示。