跳到主要内容

迭代

数组迭代是一项很重要的操作,在 ECMAScript 5 之前主要用 for 语句实现,这种方式不是很方便,为此 ECMAScript 5 新增了 5 个与迭代有关的方法。

for/in

使用 for/in 和 for 都可以迭代数组。 for 语句需要配合数组下标 length 属性和数组下标来实现,执行效率不如 for/in,另外, for/in 会体跳过空元素。

forEach

forEach()方法对数组中的每一项执行回调函数,其语法格式如下:

oArray.forEach(callbackFunction[,thisObject])
  • callbackfn : 必须函数,最多可接受三个函数,对每一个元素都会调用一次
  • thisAry : 可选参数, callbackfn 函数中的 this 关键字可引用的对象。如果省略 thisAry ,则 undefined 将用作 this

forEach 方法不用于修改原始数组,但回调函数会修改它

除了数组对象外, forEach 方法还可以用于具有 length 属性的具有已按数字编制索引的属性名的任何对象,如关联数组、 Arguments 等

回调函数语法如下:

function callbackFunction(value, index, array) {}
  • 参数 callbackFunction 定义对数组中的每一元素进行匹配运算的函数。该函数可以包含3个参数,即元素值、元素索引和 Array 对象:
  • 函数可以包含简单的比较操作或者更复杂的操作,函数没有返回值。
  • 参数 thisObject 定义函数的 this 对象。

该方法对数组中的每一元素执行回调函数,在该函数中可以处理每个元素。

forEach 启动后的条件元素是否传递给回调函数
在数组的原始长度之外添加长度
添加元素以填充数组中缺少的元素是,如果该索引尚未传递给回调函数
元素已更改是,如果该元素尚未传递给回调函数
从数组中删除元素否,除非改善元素已传递给回调函数

下面的代码遍历所有元素:

var A_Team = new Array('Tom', 'Tommy', 'John');
function getAllFn(value, index, array) {
console.log(index + '===' + value);
}
A_Team.forEach(getAllFn);

输出结果如下:

((0 === Tom1) === Tommy2) === John;

下例使用 forEach 迭代 numbers ,然后计算数组元素的和并输出。

var number = [10, 11, 12];
var sum = 0;
number.forEach(function addNumber(value) {
sum += value;
});
console.log(sum); // 返回 33

下例演示如何使用 thisArg 参数,该参数指定可对引用 this 关键字的对象。

var obj = {
showResults: function (value, index) {
var squared = this.calcSquare(value);
console.log('value' + value);
console.log(' index ' + index);
console.log(' squared ' + squared);
console.log('');
},
calcSquare: function (x) {
return x * x;
},
};

var numbers = [5, 6];
numbers.forEach(obj.showResults, obj);
numbers.forEach(function (value, index) {
this.showResults(value, index);
}, obj);

迭代器方法

ES6 中, Array 的原型上暴露了 3 个用于检索数组内容的方法: keys()、 values()和 entries()。 keys()返回数组索引的迭代器, values()返回数组元素的迭代器,而 entries()返回 索引/值对的迭代器:

const a = ['foo', 'bar', 'baz', 'qux'];
// 因为这些方法都返回迭代器,所以可以将它们的内容
// 通过 Array.from()直接转换为数组实例
const aKeys = Array.from(a.keys());
const aValues = Array.from(a.values());
const aEntries = Array.from(a.entries());
console.log(aKeys); // [0, 1, 2, 3]
console.log(aValues); // ["foo", "bar", "baz", "qux"]

console.log(aEntries); // [[0, "foo"], [1, "bar"], [2, "baz"], [3, "qux"]]
const a = ['foo', 'bar', 'baz', 'qux'];
for (const [idx, element] of a.entries()) {
alert(idx);
alert(element);
}
// 0
// foo // 1 // bar // 2 // baz
// 3 // qux

every

every()方法对数组中的每一项执行测试函数,直到获得对指定的函数返回 false 的项,其语法格式如下:

oArray.every(callbackFunction [,thisObject])

如果 callbackfn 函数为所有的数组元素返回 true ,则返回值为 true ;否则返回值为 false 。如果数组没有元素,则 every 返回 true 。

every 按照升序对每一个数组元素调用一次 callbackfn 函数,直到 callbackfn 返回 false 。如果找到导致 callbackfn 返回 false 的元素,则 every 方法立即返回 false 。否则, every 返回 true 。 every 不为数组中缺少的元素调用该回调函数。

参数 callbackFunction 定义对数组中的每一元素进行匹配运算的函数。该函数可以包含3个参数,即元素值、元素索引和 Array 对象,格式如下:

function callbackFunction(value, index, array) {}

函数可以包含简单的比较操作或者更复杂的操作,函数的返回值为 true 或 false 。

参数 thisObject 定义函数的 this 对象。

数组对象可由回调函数修改。

例如下面的代码,演示了如何使用该方法:

var A_Team = new Array('Tom', 'Tommy', 'John');
function getItemsFn(value, index, array) {
if (value.length > 4) {
return;
false;
} else {
console.log(index + '===' + value);
}
}
var N_Team = A_Team.every(getItemsFn);

上述代码返回如下结果,因为到第2个元素就返回了 false ,所以,即使第3个元素也满足小于等于4个字符,也不会进行测试了:

0 === Tom;

下例判断数组是否全为偶数。

function CheckIfEven(value, index, arr) {
console.log(value + ' ');
if (value % 2 == 0) return true;
else return false;
}
var numbers = [2, 4, 5, 6, 8];
if (numbers.every(CheckIfEven)) console.log('都是偶数');
else console.log('不全是偶数');

下例检测数组元素是否在指定的范围内。范围通过一个对象直接量 obj 来设置。用此例来演示 thisArg 参数的用法,该参数指定对其引用 this 关键字。

var checkNumericRange = function (value) {
if (typeof value !== 'number') return false;
else return value >= this.minimum && value <= this.maximum;
};
var numbers = [10, 15, 19];
var obj = { minimum: 10, maximum: 20 };
if (numbers.every(checkNumericRange, obj)) console.log('都在指定范围内');
else console.log('部分不在范围内');

some()方法

some()方法对数组中的每一项执行测试函数,直到获得返回 true 的项,其语法格式如下:

oArray.some(callbackFunction[,thisObject])

参数说明。

  • array: 必须参数,一个数组对象
  • callbackfn: 必须参数,一个接收最多 3 个参数的函数。 some 方法会为 array 中每一个元素调用 callbackfn 函数,直到返回 true ,或直到到达数组的结尾
  • thisArg :可选参数,可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg ,则 undefined 作为 this 的值

some 会按照升序索引顺序对每一个数组元素调用 callbackfn 函数,直到 callbackfn 函数返回 true 。如果找到导致 callbackfn 返回 true 的元素,则 some 返回 true 。如果回调不对任何元素返回 true ,则会返回 false 。

some 不为数组中缺少的元素调用该回调函数。除了数组对象之外,如果 some 方法可由 length 属性且具有已按数字编制索引的属性名的任何对象使用,如关联数组、 Arguments 等。

例如下面的代码,演示了如何使用该方法:

function CheckIfEven(value, index, arr) {
if (value % 2 == 0) return true;
}
var numbers = [1, 15, 4, 10, 11, 22];
var evens = number.some(CheckIfEven);
if (evens) console.log('不全是奇数。');
else console.log('全是奇数。');

map()方法

map 对数组的每一个元素调用回调函数并返回包含结果。

array.map( callbackfn [, thisArg}] )

参数说明。

  • array: 必须参数,一个数组对象
  • callbackfn: 必须参数,一个接收最多 3 个参数的函数。 map 方法会为 array 中每一个元素调用 callbackfn 函数
  • thisArg :可选参数,可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg ,则 undefined 作为 this 的值

map 方法返回一个新数组,其中每个元素均为关联的原始数组元素的回调函数返回值。对于数组中每个元素, map 都会调用一次 callbackfn 函数一次(采用升序索引顺序)。将不会为数组中缺少的元素调用回调函数。

除了数组对象以外, map 方法可由具有 length 属性,且具有已按数字编制索引的属性名的对象使用,如 Arguments 参数对象。

Map 启动后的条件元素是否传递给回调函数
在数组的原始长度之外添加长度
添加元素以填充数组中缺少的元素是,如果该索引尚未传递给回调函数
元素已更改是,如果该元素尚未传递给回调函数
从数组中删除元素否,除非改善元素已传递给回调函数
function AreaOfCircle(radius) {
var area = Math.PI * (radius * radius);
return area.toFixed(0);
}
var radii = [10, 20, 30];
var areas = radii.map(AreaOfCircle);
// 314 ,1257 ,2827
console.log(area);

下例演示 map 方法映射数组 number ,把数组中每个元素的值除以 divisor 的值,然后返回这个新的数组。其中回调函数和 divisor 都作为对象 obj 的属性处在、、存在,通过这种方法演示如何在 map 中使用 thisArg 参数:

var obj = {
divisor: 10,
remainder: function (value) {
return value % this.divisor;
},
};
var numbers = [6, 12, 25, 30];
var result = number.map(obj.remainder, obj);
console.log(result);
// 6, 2 ,5 ,0

该方法对数组中的每一元素执行测试函数,根据测试返回一个值,该值将会被作为新数组的元素。

例如下面的代码,演示了如何使用该方法:

var A_Team = new Array('Tom', 'Tommy', 'John');
function getItemsFn(value, index, array) {
if (value.length >= 4) {
return;
value;
} else {
return 'small'; // 如果字符数小于4,那么就返回这个值
}
}
var N_Team = A_Team.map(getItemsFn);
console.log(N_Team); // 输出 small,Tommy,John

filter

返回数组中的满足回调函数中指定的条件的元素。

array.filter(callbackfn[,thisArg])

使用方法类似于 map 。

  • callbackfn :必须参数,一个接受最多三个参数的函数。对于数组中的每个元素, filter 方法都会调用 callback 函数一次
  • thisArg :可选参数,可在 callback 函数中为其引用 this 关键字的对象。如果省略 thisArg ,则 undefined 将作为 this 的值

返回值是一个包含回调函数为返回 true 的所有值的新数组。

filter()方法对数组中的每一项执行测试函数,根据函数结果构造一个新数组,其语法格式如下:

oArray.filter(callbackFunction[,thisObject])

参数含义同 every()方法。

该方法对数组中的每一元素执行测试函数,并构造一个新数组,其中的所有元素都对指定的函数返回 true 。如果某项返回 false ,则新数组中将不包含此元素。

下面的代码用于找出元素字符串中字符数大于等于4的项:

var A_Team = new Array('Tom', 'Tommy', 'John');
function filterFn(value, index, array) {
if (value.length < 4) return false;
if (value.length >= 4) return true;
} // 按照自定义函数进行匹配,自定义函数是根据元素字符串长度进行对比的
var N_Team = A_Team.filter(filterFn);
console.log(N_Team); //
输出 Tommy, John;

通过下面的运算,可以找出数组元素字符串中字符数最多的项:

var A_Team = new Array('Tom', 'Tommy', 'John');
function filterFn(value, index, array) {
if (index < array.length - 1 && index > 0) {
if (value.length < array[index + 1].length) return false;
if (value.length >= array[index + 1].length) return true;
}
if (index == array.length) {
if (value.length < array[index - 1].length) return false;
if (value.length >= array[index - 1].length) return true;
}
if (index == 0) {
if (value.length < array[index + 1].length) return false;
if (value.length >= array[index + 1].length) return true;
}
}
// 按照自定义函数进行排序,自定义函数是根据元素字符串长度进行对比的
var N_Team = A_Team.filter(filterFn);
console.log(N_Team); // 输出 Tommy

通过下面使用 filter ()方法过滤掉字符串中每个单词的首字母。

function f(value, index, ar) {
//第一个字母直接选择
if (index == 0) return true;
//如果前面是空字符串,则返回这个字符
else return ar[index - 1] === ' ';
}
var a = 'The quick brown fox jumps over the lazy dog.';
var submit = [].filter.call(a, f);
console.log(submit);
//T 、 q 、 b 、 f 、 j 、 o 、 t 、 l 、 d

使用 keys 迭代数组

keys()是 Object 的静态对象,专门用来遍历对象获取键名。 Object.keys()函数。

var o = { a: 'A', b: 'B', c: 'C' };
console.log(Object.keys(o)); //返回 ["a","b","c"]
var a = ['A', 'B', 'C'];
console.log(Object.keys(a)); //返回["0","1","2"]

keys()功能单一,应用范围比较窄,但是执行效率比较高。

除了获取键名集合外,还可以间接获取对象的长度。

//返回3
var o = [a:"A",b:"B",c:"C"]console.log(Object.keys(o).length);
//返回3
var a = ["A","B","C"]console.log(Object.keys(a).length);