资讯专栏INFORMATION COLUMN

js 你不知道的 Array

yintaolaowanzi / 1675人阅读

摘要:删除数组的第一个元素,返回值是删除的元素对数组中的元素进行排序添加或删除数组中的一个或多个元素。循环迭代方法对数组中的每一个元素调用参数中指定的过滤函数,并将对于过滤函数返回值为的那些数组元素集合为新的数组返回。

一、在类数组对象上复用通用的数组方法

类数组有:arguments, NodeList, 字符串

什么是类数组? 两个条件

具有 length 属性

length 属性大于该对象的最大索引

比如:

  var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3};
  var result = Array.prototype.map.call(arrayLike, function(s) {
    return s.toUpperCase();
  });//["A", "B", "C"]

几乎所有的数组方法都是通用的(forEach,slice,map ...) 除了 concat。

因为 concat 在连接时,会检查其参数的 [[Class]] 属性。

一些方法,比如 join,仅仅读取他们被调用的对象的长度和数值属性。 另外,像 reverse 一样,要求对象的数值属性和长度属性是可变的;因此,这些方法不能在像 String 这样的对象上被调用,String不允许它的长度属性和synthesized的数值属性被设置。

  function namesColumn() {
    return ["Names"].concat(arguments);
  }
  namesColumn("alice", "arale");//["Names", {0: "alice", 1: "arale"}]

  //解决办法:应先使用 slice 将 arguments 转为数组
  function namesColumn() {
    return ["Names"].concat([].slice.call(arguments));
  }
二、数组优先使用 for 循环,而不是 for in 循环。

for in 更多的是用于 遍历对象,但是 它也会去检查 对象的原型。

如果浏览器支持 for of (ES6)的话,最好是使用它,它不会去遍历原型。

三、迭代优于循环

一个原因是,迭代可以消除没必要的 终止条件任何数组索引

比如:

  for (var i = 0; n = players.length; i < n; i++) {
    players[i].score++;
  }

  //使用迭代
  players.forEach(function(p){
    p.score++;
  });

例1: 对数组每一个元素操作后生成一个新的数组

  //获得所有输入框去除多余空格后的值
  var trimmed = input.map(function(s) {
    return s.trim()
  })

例2: 获取价格在特定区间的列表

  listings.filter(function(listing) {
    return listing.price >= min && listing.price <= max
  })

当然这都是 ES5 的方法,我们也可以自己写一个。

  function takeWhile(a, pred) {
    var result = []
    for (var i = 0; n = a.length; i < n; i++) {
      if (!pred(a[i], i)) {
       break
      }
      result[i] = a[i]
    }
    return result
  }

  var prefix = takeWhile([1, 2, 4, 8, 16, 32], function(n) {
    return n < 10
  }) // [1, 2, 4, 8]

把它加在 Array 上

  Array.prototype.takeWhile = function(pred) {
    var result = []
    for (var i = 0; n = this.length; i < n; i++) {
      if (!pred(this[i], i)) {
        break
      }
      result[i] = this[i]
    }
    return result
  }

  [1, 2, 4, 8, 16, 32].takeWhile(function(n) {
    return n < 10
  }) // [1, 2, 4, 8]

循环仅一点优于迭代: 控制流操作 如 break 和 continue

ES5 中 只有 some 和 every 可以提前终止循环, 但设计他们的本意不是用来提前终止循环。

// some 一旦回调产生了一个真值,则立即返回,不会执行其余的元素
[1, 10, 100].some(function(x) { return x > 5 }) //true
[1, 10, 100].some(function(x) { return x < 0 }) //false
// every 相反, 一旦产生假值,则立即返回,不会执行其余元素
[1, 2, 3, 4, 5].every(function(x) { return x > 0 }) //true
[1, 2, 3, 4, 5].every(function(x) { return x < 3 }) //false

这种行为可以用来实现 forEach 提前终止循环的变种时派上用场

  function takeWhile(a, pred) {
    var result = [];
    a.every(function(x, i) {
      if (!pred(x)) {
        return false //break
      }
      result[i] = x;
      return true; //continue
    })
    return result
  }
四、数组方法分类
1. Mutator 方法

这些方法可以改变数组自身

pop : 移除数组的最后一个元素,返回值是被删除的元素。

push : 在数组的末尾添加一个或者多个元素,返回值是新的数组的长度。

reverse : 颠倒数组中元素的顺序,原先第一个元素现在变成最后一个,同样原先的最后一个元素变成了现在的第一个,也就是数组的索引发生了变化。

shift : 删除数组的第一个元素,返回值是删除的元素

sort : 对数组中的元素进行排序

splice : 添加或删除数组中的一个或多个元素。

unshift : (将废弃)添加一个或者多个元素在数组的开头,返回值是新的数组的长度。

2. Accessor 方法

这些方法不改变数组自身

concat : 返回一个包含此数组和其他数组和/或值的结合的新数组

indexOf : 返回第一个与给定参数相等的数组元素的索引,没有找到则返回-1

join : 将所有的数组元素连接成一个字符串

lastIndexOf : 返回在数组中搜索到的与给定参数相等的元素的最后(最大)索引

slice : 返回数组中的一段。

toString : 返回代表该数组及其元素的字符,重写Object.toString 过程.

valueOf : 重写Object.valueOf过程。

3. 循环(迭代) 方法

filter : 对数组中的每一个元素调用参数中指定的过滤函数,并将对于过滤函数返回值为true的那些数组元素集合为新的数组返回。

forEach : 对数组的每一个元素依次调用参数中指定的函数。

every : 如果数组中每一个元素都满足参数中提供的测试函数,则返回真

map : 创建一个新数组,新数组中含有,分别对于原来数组的每一个元素调用一个给定函数的结果

some : 如果数组中至少有一个元素满足参数函数的测试,则返回true。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85980.html

相关文章

  • 你不知道js技巧

    摘要:所谓的高级,其实就是讲了一些我们平常用不到或许用了不知道,但是非常实在的东西。比如如果你想检测里面的属性值的话,基本上是不可能的。要知道,我们是有情怀的淫。 JS进阶 说起这个应该算是老生常谈了吧。所谓的高级,其实就是讲了一些我们平常用不到(或许用了不知道),但是非常实在的东西。算是熟练掌握js的一个必经road吧。 检测函数类型 其实检测函数的类型应该算是js的一个痛点,因为js是一...

    edagarli 评论0 收藏0
  • 【读书笔记】你不知道JavaScript--内置类型

    摘要:有种内置类型,分别是除对象之外,其他统称为基本类型。另一个需要注意的是数组确切地说,数组也是的一个子类型我们可以通过下面的方法检查变量是不是数组处理未声明的变量时,会返回这是因为有一个特殊的安全防范机制。 js有7种内置类型,分别是undefined null boolean string number symbol object除对象之 Object 外,其他统称为基本类型。符号 ...

    Integ 评论0 收藏0
  • 你不知道JavaScript

    摘要:第二章值的数组不需要预设数组大小,可以直接向数组添加任何类型的值,如果形成了稀疏数组,那么未赋值的部分将会是。某些不是数组的对象,如果其有属性,就是类数组,例如元素列表,,通常用这个将其转化为数组,而为我们提供了一种新途径。 从名字上看可能会觉得JS应该和Java是有很紧密的联系的吧,实际上它们是两种完全不同的语言,JS是ECMAScript的浏览器规范,是一种弱类型的语言,不同于Ja...

    2i18ns 评论0 收藏0
  • 笔记-你不知道JS-对象

    摘要:内置对象,在中,它们实际上只是一些内置函数。这些内置函数可以当作构造函数,使用调用,产生新对象。在必要时语言会自动把字符串字面量转换成一个对象,也就是说你并不需要显式创建一个对象。属性操作符要求属性名满足标识符的命名规范。 1 如何定义 // 声明形式,大部分情况下使用声明形式 let obj ={ a:2, b:3 }; // 构造形式 let obj= = new Obje...

    senntyou 评论0 收藏0
  • ES6和Babel你不知道事儿

    摘要:版本截图当然,搜狗浏览器市场份额也不低,官方最新版本是,内核版本是,为之一惊。上面代码的和分别是什么含义呢如果是下面的配置有何不可呢首先来明确一个概念是一系列的集合。比如做移动端开发不需要考虑之类的端产品线只考虑指定的浏览器等。 因babel的版本从5升级到6有很多改动,比如babel本身不再提供任何transform的工作,都需要借助插件来完成,本文的所有讨论都是建立在babel 6...

    nidaye 评论0 收藏0

发表评论

0条评论

yintaolaowanzi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<