javascript - 请问这句语句var args=[].slice.call(arguments,1)是什么意思?
黄舟
黄舟 2017-04-11 10:55:32
[JavaScript讨论组]
黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回复(3)
黄舟

首先你要具备如下知识:

  • []是什么?

  • [].slice.call是什么?

  • arguments是什么?

我们逐一来看:

[]是什么?

[]是js语法中创建一个新数组的意思,看如下代码:

var a = [];
var b = new Array();

这两种写法并无二致。

[].slice.call是什么?

首先你知道[]是一个数组,那么[].slice是它的一个方法,是一个函数。
它的作用是返回数组中的某一段,看如下代码:

var a = [1, 2, 3, 4, 5];
var b = a.slice(2);
// b是a从2号位开始的片段
// 也就是[3, 4, 5]

在js中,函数本身也是一种对象,也是具有属性和方法的,call就是其中之一。
它的第一个参数,是指定函数执行时的this指针,后面的参数,就是函数执行的参数。
具体的不展开讲,你可以查阅MDN: Function.prototype.call()
看如下代码:

var a = function (n) {
    console.log(this, n);
}
var b = {};

a(1); // log出Window对象, 1
a.call(b, 2); // log出b对象, 2

所以说[].slice.call(arguments, 1)实际上相当于(并不一定等同于):

arguments.slice(1);

arguments是什么

arguments可以看做一个数组。每一个js函数内部都有arguments,它代表传入的参数数组。
看如下代码:

function a() {
    console.log(arguments);
}

a(1, 2, 3); // log出[1, 2, 3]

现在你应该明白了,[].slice.call(arguments, 1)返回的是arguments数组从1号位开始的片段。
看如下代码:

function a() {
    var args = [].slice.call(arguments, 1);
    console.log(args);
}

a('haha', 1, 2, 3, 4, 5); // log出[1, 2, 3, 4, 5]

a('run', '-g', '-b'); // log出['-g', '-b']

就是这样,喵。

天蓬老师

arguments不是一个真正的数组,虽然很像!

那如果我们想获取arguments里除了第一项以外的其他所有选项怎么办?

如果是数组的话,直接数组.slice(0, 1)搞定,所以你好想让arguments也能像数组那样使用slice方法对吧?于是

var args=[].slice.call(arguments,1);

就等于,把数组的slice方法,搬到arguments上,并调用,传入参数为1

关于call的应用,看这里

巴扎黑

楼上两位说的都很好,我再来补充一点,为什么用Array.prototype.slice而不是用split,splice或者别的api?
这里贴一段slice的polyfill就一目了然了。

(function () {
  'use strict';
  var _slice = Array.prototype.slice;

  try {
    // Can't be used with DOM elements in IE < 9
    _slice.call(document.documentElement);
  } catch (e) { // Fails in IE < 9
    // This will work for genuine arrays, array-like objects, 
    // NamedNodeMap (attributes, entities, notations),
    // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
    // and will not fail on other DOM objects (as do DOM elements in IE < 9)
    Array.prototype.slice = function(begin, end) {
      // IE < 9 gets unhappy with an undefined end argument
      end = (typeof end !== 'undefined') ? end : this.length;

      // For native Array objects, we use the native slice function
      if (Object.prototype.toString.call(this) === '[object Array]'){
        return _slice.call(this, begin, end); 
      }

      // For array like object we handle it ourselves.
      var i, cloned = [],
        size, len = this.length;

      // Handle negative value for "begin"
      var start = begin || 0;
      start = (start >= 0) ? start : Math.max(0, len + start);

      // Handle negative value for "end"
      var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
      if (end < 0) {
        upTo = len + end;
      }

      // Actual expected size of the slice
      size = upTo - start;

      if (size > 0) {
        cloned = new Array(size);
        if (this.charAt) {
          for (i = 0; i < size; i++) {
            cloned[i] = this.charAt(start + i);
          }
        } else {
          for (i = 0; i < size; i++) {
            cloned[i] = this[start + i];
          }
        }
      }

      return cloned;
    };
  }
}());
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号