最近在恶补js知识的时候,总是会因为js强大的语法而感到震撼。因为以前对前端方面的疏忽,导致了一些理解的错误。因此痛改前非,下定决心,不管做什么事情,都要有专研的精神。

在介绍前,抛出一个问题:如何将多个数组合并为一个数组?

以下的分享会分为如下小节:

1.concat方法的基础介绍

2.从实例中感受concat方法

1.concat方法的基础介绍

  concat方法用于多个数组的合并。它将新数组的成员,添加到原数组的尾部,然后返回一个新数组,原数组不变。

console.log([].concat([1],[2],[3]));    // [1, 2, 3]
console.log([].concat([[1],[2],[3]]));    // [[1], [2], [3]]
console.log([].concat(4,[[5,6],[7]]));    // [4, [5, 6], [7]]

  上面代码中,第一个返回值是将一个空数组与三个数组[1],[2],[3]合并为一个数组,因此返回了[1, 2, 3]。第二个是将一个空数组与一个二维数组合并,二维数组的成员为[1],[2],[3],因此返回了[[1], [2], [3]],注意,返回的是二维数组。第三个例子同理。这里对概念的理解很重要,即将新数组的成员,添加到原数组的尾部。

  除了接受数组作为参数,concat也可以接受其他类型的值作为参数。它们会作为新的元素,添加数组尾部。

 console.log([].concat(1,2,3)); //[1,2,3];
 //等同于
 console.log([].concat(1,[2,3])); //[1,2,3];
 console.log([].concat([1],[2,3]));    //[1,2,3];

  这里虽然内容较少,看起来挺简单。但是真正理解起来真的不容易。

2.从实例中感受concat方法

  说完基础的知识,给大家看看我最近遇到的一个题目。原题是这样的。

  看例子就能明白是什么意思了。

  这道题目中,其中一个解决方案就是:

var flatten = function (arr){
  return [].concat.apply([],arr);
};

  这一段简单的函数就可以实现将数组中的元素合并的功能。但是当我在理解这个返回值的时候,出现了一个问题。

  问题:为什么使用apply方法和没有使用apply方法会有区别?

console.log([].concat.apply([],[[1],[2],[3]]));    //[1, 2, 3]
console.log([].concat([[1],[2],[3]]));    //[[1], [2], [3]]

  上面代码中,同样是在一个空数组中向尾部添加新数组,第一个返回的是[1,2,3]。第二个却是一个二维数组。

  经过一段时间的折腾,终于理解了其中不同的原因所在。

  首先,我们在空数组中调用实例方法concat的时候,是传入concat中的参数,在push到数组的末尾。

console.log([].concat(1,2,3));    //[1, 2, 3]
console.log([].concat([1],[2],[3]));    //[1, 2, 3]
console.log([].concat([[1],[2],[3]]));    //[[1], [2], [3]]
console.log([].concat([[[1],[2],[3]]]));    // [[[1], [2], [3]]]

  上面代码中,从单个元素,到一维数组,二维数组,三维数组逐渐变化的。

  在Javascript中call,apply,bind方法的详解与总结 文章中,有提到 apply方法的作用与call方法类似,也是改变某个函数中this指向(函数执行时所在的作用域),然后在指定的作用域中,调用该函数。同时也会立即执行该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数。

  apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined或者this,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,在调用时传入原函数。原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。

console.log([].concat([1],[2],[3])); //[1, 2, 3]
console.log([].concat([[1],[2],[3]]));    //[[1], [2], [3]]
console.log([].concat.apply([],[[1],[2],[3]]));    //[1, 2, 3]

  在上面代码中,上半段直接使用concat方法,将传入的参数合并到空数组中。下半段中,调用了String对象的实例方法apply,将concat()函数内部的this指向了[],并且在[]作用域下,传入调用concat需要的参数,并且以数组的方式传入。再看几个例子。

console.log([].concat([1,2,3]));    //[1, 2, 3]
console.log([].concat.apply([],[[1],[2],[3]]));//[1, 2, 3]

console.log([].concat([[1],[2],[3]]));//[[1], [2], [3]]
console.log([].concat.apply([],[[[1],[2],[3]]]));//[[1], [2], [3]]

console.log([].concat([[[1],[2],[3]]]));//[[[[1], [2], [3]]]]
console.log([].concat.apply([],[[[[1],[2],[3]]]]));//[[[1], [2], [3]]]

  

  总结:

    1.单独使用concat方法时,会将新数组的成员,添加到原数组的尾部,然后返回一个新数组,原数组不变;如果传入的其他类型的值,它们会作为新的元素,添加到数组末尾。

    2.数组元素合并的方法:

var flatten = function (arr){
    return [].concat.apply([],arr);
};
var flatten = function (array){
  return array.reduce(function(a,b){
    return a.concat(b);
  },[])
}

  如果对不理解apply方法,可以前往这篇文章:Javascript中call,apply,bind方法的详解与总结

  转载请注明出处:http://www.cnblogs.com/Uncle-Keith/p/5852721.html

javascript中concat方法深入理解的更多相关文章

  1. 对javascript中call()方法的理解

    call ( thisObj [, arg1 [, arg2 [,  [, argN] ] ] ]) call()方法:官方介绍是,调用一个对象的一个方法,以另一个对象替换当前对象. call()方法 ...

  2. JavaScript中的方法、方法引用和参数

    首先,我们来看一段代码,如果觉得不甚明白的,则本文会对你有益: var player = function (e) {             return (function f(m) {      ...

  3. JavaScript中Array方法总览

    title: JavaScript中Array方法总览 toc: true date: 2018-10-13 12:48:14 push(x) 将x添加到数组最后,可添加多个值,返回数组长度.改变原数 ...

  4. JavaScript中reduce()方法

    原文  http://aotu.io/notes/2016/04/15/2016-04-14-js-reduce/   JavaScript中reduce()方法不完全指南 reduce() 方法接收 ...

  5. 详解 JavaScript 中 splice() 方法

    splice() 方法是一个比较少用的方法,但是功能确实很好,并且在我们 coding 的时候,经常有需要 splice() 方法,先介绍一下该方法. 在 JavaScript 中 splice() ...

  6. JavaScript中的方法

    JavaScript中的方法 在JavaScript中,可以通过对象来调用对应的方法.在JavaScript中,有三个重要的window对象方法:用于显示警告信息的alert.用于显示确认信息的con ...

  7. 优雅的数组降维——Javascript中apply方法的妙用

    将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换.本文将从朴素的循环转换开始,逐一介绍三 ...

  8. javascript中apply()方法解析-简单易懂!

    今天看到了js的call与apply的异同,想着整理一下知识点,发现了一篇好文章,分享过来给大家,写的非常好! 参考: http://www.cnblogs.com/delin/archive/201 ...

  9. javascript中关于继承的理解

    首先,你要理解在javascript中,每当一个新函数创建时,都会生成一个prototype属性,我们管它叫做原型对象.看一个例子: function foo(){ this.name='qiangq ...

随机推荐

  1. 将数据从MySQL迁移到Oracle的注意事项

    将数据从MySQL迁移到Oracle的注意事项1.自动增长的数据类型处理MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值.ORACLE没有自动增长的数据类型,需要建立一个自动 ...

  2. JS原生第七篇 (帅哥)

    1.1 复习 offset   自己的 偏移 offsetWidth    得到自己的宽度 offsetHeight 构成 :   width  +   padding  +  border div ...

  3. Ado.Net Destination 用法

    Ado Net Destination Component 使用Ado net Connection manager,其Data Access Mode 只有一种, table or view,组件的 ...

  4. Sql Server系列:键和约束

    1 约束的类型 约束可以分为3大类:实体约束.域约束和参照完整性约束. 1.1 实体约束 实体约束都是关于比较行的,实体约束并不关心整体列中的数据,它只对特定行感兴趣. 1.2 域约束 域约束处理一个 ...

  5. ECMAScript

    在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...

  6. WPF MVVM下做发送短信小按钮

    最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录. 一.发送消息 没有调用公司的短信平台,只是模拟前台生成一串数字,将此串数字输出一 ...

  7. ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】

    到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性.这些特性包括如何针对IServiceProvider接口提供一个Service ...

  8. 应用程序框架实战三十:表现层及ASP.NET MVC介绍(一)

    本文将介绍表现层及ASP.NET MVC的一些要点,特别是ASP.NET MVC的一些抽象和封装技巧,如果你对MVC还不了解,可以参考<ASP.NET MVC4 高级编程>,作者Jon G ...

  9. 微软的坑:Url重写竟然会引起IIS内核模式缓存不工作

    万万没有想到!当初为了解决使用负载均衡时记录客户端IP地址的问题,在IIS URL Rewrite Module中增加了一条URL重写规则(详见迁入阿里云后遇到的Request.UserHostAdd ...

  10. 浅谈2D游戏设计模式2- WZ文件详解(UI.WZ)之MapLogin.img(1)

    玩过冒险岛的人都知道有一个WZ文件,那么这个WZ文件的内部是怎么样的呢,今天我就带大家一探究竟. 说实在的,我这是第一次接触WZ文件,但是却让我很震撼,为什么很震撼,因为这个居然是用VS2010写的! ...