JavaScript学习笔记: 数组(七)_html/css_WEB-ITnose

html教程评论2.5K views阅读模式

使用数组总是会碰到数组的遍历(迭代)操作。说到迭代,可能会立马想起 for 语句对数组进行迭代。比如需要迭代出下面数组 peoples 年龄( age )大于 30 的人名( name )。

var peoples = [    {        name: 'Agraj',        gender:'M',        age: 29,        address:        {            city: 'Delhi',            pincode: '110064'        }    },    {        name: 'Mark',        gender:'M',        age: 35,        address:        {            city: 'West Bengal',            pincode: '220013'        }    },    {        name: 'Lance',        gender:'M',        age: 39,        address:        {            city: 'Chandigarh',            pincode: '201201'        }    },    {        name: 'Vikas',        gender:'M',        age: 21,        address:        {            city: 'Noida',            pincode: '201301'        }    },    {        name: 'Kanika',        gender:'F',        age: 21,        address:        {            city: 'Noida',            pincode: '201301'        }    }];for (var i = 0; i < peoples.length; i++ ) {    if (peoples[i].age > 30) {        console.log(peoples[i].name + ':' + peoples[i].age);    }}

Chrome浏览器输出的结果:

Mark:35Lance:39

其实ES5为数组定义了五个迭代方法:

  • forEach() :没有返回值,只是针对每个数组项调用指定的函数( callbackfn )
  • every() : 返回一个布尔值( true 或 false ),判断每个数组项是否符合指定函数的条件,符合为 true ,反之为 false
  • some() : 返回一个布尔值( true 或false),判断每个数组项是否符合指定函数的条件,只要有任何一项返回为 true ,就会返回 true
  • filter() : 每个数组项调用指定的函数,条件为 true 的将返到一个新数组中
  • map() : 每个数组项调用指定的函数,返回每次函数调用的结果组成一个新数组

这五个数组迭代的方法中,其中 forEach() 、 every() 和 some() 方法不生成一个新数组,而 filter() 和 map() 方法将会生成一个新数组(符合条件)。并且这些方法都会调用指定的函数 callbackfn 。回调函数 callbackfn 语法如下:

function callbackfn (value, index, array) {...}

可以使用三个参数来声明回调函数 callbackfn :

  • value : 数组元素的值
  • index : 数组元素在数组中的索引值
  • array : 包含该元素的数组对象

今天主要一起了解这五个数组迭代方法是如何使用?在接下来的内容中都将以开头的数组为例。

forEach() 方法

forEach() 方法让数组的每一项都执行一次给定的函数。

语法

array.forEach(callbackfn[, thisArg])

参数

参数 说明
array 必选。一个数组对象。比如示例中的 peoples 数组
callbackfn 必选。最多可以接受三个参数的函数。对于数组中的每个元素, forEach 都会调用 callbackfn 函数一次。
thisArg 可选。 callbackfn 函数中的 this 关键字可引用的对象。如果省略 thisArg ,则 undefined 将用作 this 值。

forEach() 方法按升序为数组中含有效值的每一项执行一次 callbackfn 函数,那些已删除或者从未赋值的项将被跳过(但不包括哪些值为 undefined 的项)。

示例

开头使用 for 语句遍历出年龄大于 30 岁的名称,并且输出 people 的 name 和 age 。其实使用 forEach() 方法也可以实现:

peoples.forEach(function (people) {    if (people.age > 30) {        console.log(people.name + ':' + people.age);    }});

Chrome浏览器输出的结果:

Mark:35Lance:39

在此基础上,你可以做很多事情,比如说,将数组 peoples 中的 name 遍历出来,然后重新创建一个新数组 names ,可以这样做:

var names = [];var peoplesDb = peoples.forEach(function (people, index) {    names.push(people.name);});console.log(names); // ["Agraj", "Mark", "Lance", "Vikas", "Kanika"]

内部实现

看看 forEach() 方法内部实现的方法:

Array.prototype.forEach = function(fun /*, thisp*/) {    var len = this.length;    if (typeof fun != "function")        throw new TypeError();    var thisp = arguments[1];    for (var i = 0; i < len; i++)    {        if (i in this)        fun.call(thisp, this[i], i, this);    }};

every() 方法

every() 方法测试数组的所有元素是否都符合指定函数的条件,只要有有一个元素不符合,返回的都会是 false 。

语法

array.every(callbackfn[, thisArg])

every() 方法为数组中的每个元素执行一次 callbackfn 函数,直到它找到一个使 callbackfn 返回 false (表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素, every() 方法将会立即返回 false 。否则, callbackfn 为每一个元素返回 true , every() 就会返回 true 。 callbackfn 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。

示例

还是上面开头的数组,如果每一位的年龄都大于或等于 30 ,就会返回“都大于或等于30岁了”,反之返回“不是所有人都大于30岁了”。

function bigAge(ele,index,arr){    return (ele.age >= 30);}var isBigPeople = peoples.every(bigAge);if (isBigPeople) {    console.log('都大于或等于30岁了');} else {    console.log('不是所有人都大于30岁了');}

Chrome浏览器输出的结果:

// 不是所有人都大于30岁了

内部实现

Array.prototype.every = function(fun /*, thisp*/) {    var len = this.length;    if (typeof fun != "function")        throw new TypeError();    var thisp = arguments[1];    for (var i = 0; i < len; i++)    {        if (i in this && !fun.call(thisp, this[i], i, this))        return false;    }    return true;};

some() 方法

some() 方法和 every() 方法类似,不同的是, some() 方法在调用指定的函数 callbackfn 指定的条件符合就会返回 true ,不符合则返回 false 。

语法

array.some(callbackfn[, thisArg])

示例

只要数组中年龄 age 有一个大于或等于 30 ,就会返回“有部分人还是年纪大了”,反之返回“你们都还很年轻”:

function OldAge(ele,index,array){    return (ele.age >= 30);}var isOldPeople = peoples.some(OldAge);if (isOldPeople) {    console.log('有部分人还是年纪大了');} else {    console.log('你们都还年轻');}

内部实现

Array.prototype.some = function(fun /*, thisp*/) {    var len = this.length;    if (typeof fun != "function")        throw new TypeError();    var thisp = arguments[1];    for (var i = 0; i < len; i++)    {        if (i in this && fun.call(thisp, this[i], i, this))        return true;    }    return false;};

map() 方法

map() 方法返回一个由原数组中的每个元素调用一个指定函数 callbackfn 后的返回值组成的新数组。如果符合 callbackfn 会返回符合条件的一个值,将所有返回的值再创建一个新数组。

语法

array.map(callbackfn[, thisArg])

map() 方法会给原数组中的每个元素都按顺序调用一次 callbackfn 函数。 callbackfn 每次执行后的返回值组合起来形成一个新数组。 callbackfn 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

示例

使用 map() 方法遍历数组 peoples ,并且让 index 在以前的 index 增加 1 :

var usersDb = peoples.map(function (user, index) {user.id = index + 1; return user; }); console.table(usersDb);

Chrome浏览器输出的结果:

内部实现

Array.prototype.map = function(fun /*, thisp*/) {    var len = this.length;    if (typeof fun != "function")        throw new TypeError();    var res = new Array(len);    var thisp = arguments[1];    for (var i = 0; i < len; i++)    {        if (i in this)        res[i] = fun.call(thisp, this[i], i, this);    }    return res;};

filter() 方法

filter() 方法使用指定的函数 callbackfn 测试所有元素,并创建一个包含所有通过测试的元素的新数组。

语法

array.filter(callbackfn[, thisArg])

filter() 为数组中的每个元素调用一次 callbackfn 函数,并利用所有使得 callbackfn 返回 true 或 等价于 true 的值 的元素创建一个新数组。 callbackfn 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callbackfn 测试的元素会被跳过,不会被包含在新数组中。

示例

遍历出数组中 gender 为 M 的相关数组项:

var guys = peoples.filter(function (user) {      return user.gender === 'M';});console.table(guys);  

Chrome浏览器输出的结果:

内部实现

Array.prototype.filter = function(fun /*, thisp*/) {    var len = this.length;    if (typeof fun != "function")        throw new TypeError();    var res = new Array();    var thisp = arguments[1];    for (var i = 0; i < len; i++)    {        if (i in this)        {        var val = this[i]; // in case fun mutates this        if (fun.call(thisp, val, i, this))            res.push(val);        }    }    return res;};

总结

今天主要学习了数组的五个遍历方法: forEach() 、 every() 、 some() 、 map() 和 filter() 。其中 forEach() 、 every() 和 some() 方法不会改变原数组,而 map() 和 filter() 方法会根据指定的函数 callbackfn 创建一个新数组。其中 filter() 方法将符合 callbackfn 函数条件创建一个新数组,而 some() 将数组的每一项都是在原数组中的对应项上运行传入的函数 callbackfn 。另外, every() 和 some() 方法根据指定的函数 callbackfn 返回 true 或 false 值,其中 every() 方法,只要有一项不符合 callbackfn 指定的条件就会返回 false , some() 方法,将根据 callbackfn 函数指定的条件,只要符合就返回 true ,不符合则返回则返回 false 。

初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

企鹅博客
  • 本文由 发表于 2019年7月31日 05:59:22
  • 转载请务必保留本文链接:https://www.qieseo.com/365513.html

发表评论