Array.prototype.push.apply(a,b)

时常看到在操作数组的时候有这样的写法:

var a = [1,2,3];
var b = [4,5,6]; a.push.apply(a, b); console.log(a) //[1,2,3,4,5,6] 其实这样的写法等价于:
var a = [1,2,3];
var b = [4,5,6]; Array.prototype.push.apply(a, b); console.log(a) //[1,2,3,4,5,6]

这样写法等价的原因是因为在实例上寻找属性的时候,现在这个实例自己身上找,如果找不到,就根据内部指针__proto__随着原型链往上找,直到找到这个属性。

在这里就是寻找push方法,两种写法最后找到的都是Array构造函数对应的prototype的原生方法push。所以说两种写法是等价的。

但是为什么要使用a.push.apply(a,b);这种写法呢?为什么不直接使用push()?

如果直接push:

var a = [1,2,3];
var b = [4,5,6]; a.push(b); console.log(a) //[1, 2, 3, Array(3)]
 

这样就看出来区别了,原生push方法接受的参数是一个参数列表,它不会自动把数组扩展成参数列表,使用apply的写法可以将数组型参数扩展成参数列表,这样合并两个数组就可以直接传数组参数了。

但是合并数组为什么不直接使用Array.prototype.concat()呢?

因为concat不会改变原数组,concat会返回新数组,而上面apply这种写法直接改变数组a。

同理,Math.max和Math.min也可以使用apply这种写法来传入数组参数。

比如这样:

Math.max.apply(null,a)
 

这样就可以很方便的传入数组参数了。

Array.prototype.slice.call(arguments)

类似的还有这样的写法,MDN解释slice方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。

所以可以使用slice将函数的参数变成一个数组,然后就可以当做数组来操作了。

 

Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)的更多相关文章

  1. Function.prototype.call.apply()方法

    在看uncurrying化函数时候,碰到了Function.prototype.call.apply()的用法: 先说说uncurrying()函数: Function.prototype.uncur ...

  2. Array,prototype.concat.apply与[].conat.apply.

    一直都知道JS数组Array内置对象有一个concat方法,但是也没怎么研究过,今天偶然就看了看 concat是连接一个或多个数组 返回的是连接后数组的一个副本 var oldArr=[]; var ...

  3. JavaScript,通过分析Array.prototype.push重新认识Array

    在阅读ECMAScript的文档的时候,有注意到它说,数组的push方法其实不仅限于在数组中使用,专门留作通用方法.难道是说,在一些类数组的地方也可以使用?而哪些是和数组非常相像的呢,大家或许一下子就 ...

  4. js中Array.prototype.push.call的用法

    var arr = [] Array.prototype.push.call(arr,"a","b","c") <==> []. ...

  5. 详解 Array.prototype.slice.call(arguments)

    首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...

  6. js基础进阶--关于Array.prototype.slice.call(arguments) 的思考

    欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...

  7. 理解Array.prototype.slice.call(arguments)

    在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在 ...

  8. 解析 Array.prototype.slice.call(arguments,0)

    Array.prototype.slice.call(arguments,0) 经常会看到这段代码用来处理函数的参数 网上很多复制粘帖说:Array.prototype.slice.call(argu ...

  9. js Array.prototype.slice.call(arguments,0) 理解

    Array.prototype.slice.call(arguments,0) 经常会看到这段代码用来处理函数的参数 网上很多复制粘帖说:Array.prototype.slice.call(argu ...

随机推荐

  1. C++后台服务崩溃堆栈日志

    C++后台服务崩溃堆栈日志 C/C++后台服务运行过程中总会出现一些不容易重现的崩溃故障,由于重现频率低,同时运行在服务器上,导致无法调试,此外服务直接崩溃,常规日志无法截获到有用信息,这时如果能够保 ...

  2. $inject

    function breadcrumb($parse, store) { } // 为了压缩 breadcrumb.$inject = ['$parse', 'breadcrumbStore']

  3. [LeetCode&Python] Problem 458. Poor Pigs

    There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. Th ...

  4. 初见 fultter for MAC

    第一步:下载flutter https://flutter.io/docs/development/tools/sdk/archive?tab=macos#macos 第二步:(development ...

  5. 《DSP using MATLAB》Problem 7.5

  6. HTTP进阶学习笔记

    代理 HTTP的代理服务器既是Web服务器,又是Web客户端.使用代理可以"接触"到所有流过的HTTP流量,代理可以对其进行监视和修改.常见的就是对儿童过滤一些"成人&q ...

  7. 如何用原生js开发一个Chrome扩展程序

    原文地址:How to Build a Simple Chrome Extension in Vanilla JavaScript 开发一个Chrome扩展程序非常简单,只需要使用原生的js就可以完成 ...

  8. The query below helps you to locate tables without a primary key:

    SELECT tables.table_schema, tables.table_name, tables.table_rows FROM information_schema.tables LEFT ...

  9. debian删除i386的包

    sudo apt-get remove --purge `dpkg --get-selections | grep i386 | awk '{print $1}'`; sudo dpkg --remo ...

  10. 利用 Chrome 原生功能截图网页全图

    打开你想截图的网页了,然后按下 F12(macOS 是 option + command + i)调出开发者工具,接着按「Ctrl + Shift + P」(macOS 是 command + Shi ...