最近在恶补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. Javascript学习记录——原生JS实现旋转木马特效

    昨天学习到了JS特效部分,然后老师讲了旋转木马特效的实现,如上图.不过只是讲了通过点击箭头实现图片的切换,对于点击图片本身以及二者联动却是没有讲解. 本着一颗追求完美的心,今天花费了一个中午终于将整个 ...

  2. 【已解决】WinPhone模拟器报错:模拟器没法确定来宾虚拟机通信的主机ID地址。某些功能已被禁用

    先看警告 再看错误信息 计算机管理打不开就==>Win+R ==>compmgmt.msc 发现,dnt在管理员权限组里面,也在Hyper-V权限组里面 看看Hyper-V的驱动有木有被禁 ...

  3. OpenCASCADE Camera

    OpenCASCADE Camera eryar@163.com Abstract. OpenCASCADE introduce a new class Graphic3d_Camera for th ...

  4. WPF textblock加入超链接

    <TextBlock Grid.Row=" Margin="75,0,0,0"> <Hyperlink Name="BlogHl" ...

  5. JavaScript 开发技巧 || 返回有效值

    <script type="text/javascript">var objOne = undefined || "" || null || 1 | ...

  6. Web APi之过滤器执行过程原理解析【二】(十一)

    前言 上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要.这一节我们简单将讲述在Action方法上.控制器上.全局上以及授 ...

  7. PopupWindow底部弹出

    说明:从屏幕底部弹出PopupWindow,有弹出隐藏动画效果.背景设置透明度. 效果图如下: 1.MainActivity.java   显示popwindow,宽高跟屏幕大小一样,设置一个透明度背 ...

  8. Objective-C中的单例模式

    ​    ​单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过<漫谈设计模式>了解 ...

  9. [Keras] Install and environment setting

    Documentation: https://keras.io/ 1. 利用anaconda 管理python库是明智的选择. conda update conda conda update anac ...

  10. 使用Windows EFS(怎么给文件夹加密)进行文件加密

    和Windows BitLocker一样,Encrypting File System(EFS,加密文件系统)是Windows内置的一套基于公共密钥的加密机制,可以加密NTFS分区上的文件和文件夹,能 ...