首先要说明[].slice.call()Array.prototype.slice.call() 有什么区别?

[].slice === Array.prototype.slice
true

[]为创建数组,当[].slice的时候,自然会去找原型链

[].__proto__.slice === Array.prototype.slice
true

Array.prototype.slice是定义的方法,可以被重写

[].silce是使用定义的方法

  1. 自身的属性不同(因为原型与[]的区别)
Object.getOwnPropertyNames(Array.prototype)
(37) ["length", "constructor", "concat", "pop", "push", "shift", "unshift", "slice", "splice", "includes", "indexOf", "keys", "entries", "forEach", "filter", "map", "every", "some", "reduce", "reduceRight", "toString", "toLocaleString", "join", "reverse", "sort", "lastIndexOf", "copyWithin", "find", "findIndex", "fill", "remove", "removeFirstIf", "removeIf", "repeat", "last", "lastDef", "clone"] Object.getOwnPropertyNames([])
["length"]

所以在本质上[]和Array.prototype没有本质区别,但是调用上是有区别的,但是根据专业检测,[]要更快一点

在MDN上 slice的解释是

slice()方法返回一个从开始到结束(不包括结束)选择的数组的一部分进行浅拷贝到一个新的数组对象,并且原对象不会被修改

var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"] console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"] console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]

参数有两个slice(begin,end)

begin :

  • 如果没有参数那就从0开始
  • 有就从索引处来时(第一位为0)
  • 如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素 (包含最后一个元素)

end :

  • 如果没有参数,默认取到数组末尾
  • 如果大于数组长度,取到数组末尾
  • slice(1,4) 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)
  • 如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取
var a = [1,2,3,4,5,6,7,8];
a.slice(3,-2)
(3) [4, 5, 6]

返回值

一个含有提取元素的新数组

slice 不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。

  • 如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

  • 对于字符串、数字及布尔值来说(不是 StringNumber 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

如果向两个数组任一中添加了新元素,则另一个不会受到影响。

以上大致是MDN上面对slice的专业解释

slice 这个方法在不接受任何参数的时候会返回 this 本身

arguments 是属于函数内部的变量,其值是函数参数列表,一个类数组对象,是具有长度属性的,却并不是数组,不具备slice()这个方法,那就意味着 arguments.slice() 行不通

这里可以改变this的call出现了,假如我用call将arguments把this给slice会发生什么?

slice会得到具有长度属性的对象,就实现了对象转数组的

function list() {
return Array.prototype.slice.call(arguments);
}
console.log(list(1, 2, 3));

一定有人会问,为什么将arguments的call给slice就可以变成数组?内部到底发生了什么

我们可以实现一个自己的slice(),就明白了

Myslice()

Array.prototype.Myslice = function (begin,end){

  var start = begin || 0;   //判断begin时候存在 不存在给0 这里判断可以加强
var len = this; //获取this.length 这里得到了call进来的对象 start = (start >= 0) ? start : Math.max(0, len + start); //判断参数是不是是不是大于1,负数情况下的begin取值
end = (typeof end == 'number') ? Math.min(end, len) : len; //判断end是不是大于this.length的长度
if(end<0){
end = end + len //判断负值的情况
}
var result = new Array(); for (let i = 0; i < end.length; i++) {
result.push(this[i])
}
return result;
}
function list() {
return Array.prototype.Myslice.call(arguments);
}
console.log(list(1, 2, 3));

相信看到这里就明白为什么Array.prototype.slice.call 是如何将对象变成数组的~~~

最后贴上JavaScript sclie的源码

Array.prototype.slice = function(begin, end) {
end = typeof end !== 'undefined' ? end : this.length if (Object.prototype.toString.call(this) === '[object Array]') {
return _slice.call(this, begin, end)
} var i,
cloned = [],
size,
len = this.length var start = begin || 0
start = start >= 0 ? start : Math.max(0, len + start) var upTo = typeof end == 'number' ? Math.min(end, len) : len
if (end < 0) {
upTo = len + end
} 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
} function list() {
return Array.prototype.slice.call(arguments)
}
console.log(list(1, 2, 3))

文章为个人总结,若有错误,请指出

[].slice.call的理解的更多相关文章

  1. Array.prototype.slice.call()的理解

    最近在看廖雪峰的JS课程,浏览器中的操作DOM的那一章,有这样一道题. JavaScript Swift HTML ANSI C CSS DirectX <!-- HTML结构 --> & ...

  2. [转] 对Array.prototype.slice.call()方法的理解

    在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢? 1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规 ...

  3. 对Array.prototype.slice.call()方法的理解

    在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢? 1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规 ...

  4. 对Array.prototype.slice.call()方法的理解在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢?

    1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 指倒数第 ...

  5. Array.prototype.slice.call()方法的理解

    1.基础1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 指倒数第二 ...

  6. Go语言中slice使用注意事项

    Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一 ...

  7. JavaScript中的Array.prototype.slice.call()方法学习

    JavaScript中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). 但有一个例外 ...

  8. golang学习笔记 ---slice

    Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一 ...

  9. JavaScript中的数组Array方法

    push(),pop()方法 push(),pop()方法也叫栈方法,push()可以理解成,向末尾推入,而pop()恰好相反,可以理解成从末尾移除(取得). var nums=[1,2,3,4]; ...

随机推荐

  1. Vue2.0中的系统指令

    v-on注册事件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  2. Thinkphp中在本地测试很好,在服务器上出错,有可能是因为debug缓存的问题

    define('APP_DEBUG',false); 这个设置从true改为false后,一定要清空缓存,否则会出错.

  3. 并发包CallableAndFuture

    /** * * @描述: Callable Future * * 程序运行一个线程,线程运行结束后,我们可以获取另一个线程的结果 * * @作者: Wnj . * @创建时间: 2017年5月16日 ...

  4. 针对通过 SSH 连接到 Azure Linux VM 时发生的失败、错误或被拒绝问题进行故障排除

    尝试连接到 Linux 虚拟机 (VM) 时,有多种原因可能会导致安全外壳 (SSH) 错误.SSH 连接失败或被拒绝. 本文帮助用户找出原因并更正问题. 可以使用 Azure 门户.Azure CL ...

  5. Java 调用 Rest api 设置经典 Linux 虚拟机的实例启停

    现象描述 用户可以通过 Rest API 设置经典 Linux 虚拟机实例的启停.在调用该 API 时需要通过 Azure Active Directory(下文简称 AAD) 获取 Token,但是 ...

  6. Linux ->> UBuntu 14.04 LTE下安装Hadoop 1.2.1(伪分布模式)

    Hadoop的运行模式可分为单机模式.伪分布模式和分布模式. 首先无论哪种模式都需要安装JDK的,这一步之前的随笔Ubuntu 14.04 LTE下安装JDK 1.8中已经做了.这里就不多说了. 其次 ...

  7. ns2.35-classifier.cc

    line143:recv() /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Copyri ...

  8. Hibernate缓存策略

    Hibernate的一级缓存又称为Session缓存,其适用范围是在当前的会话之中,其生命周期和Session相同,随着Session的销毁,一级缓存也会随之销毁.一级缓存是不能取消的,Hiberna ...

  9. tftp传输可执行程序问题

    昨天搭建了板子从nfs系统启动,这样只要在开发机上编写程序编译,就可以在板子上测试运行了,编写了hello world 程序,用arm编译器编译,在主板上运行,提示出错:什么exception ((什 ...

  10. poj2312 Battle City 【暴力 或 优先队列+BFS 或 BFS】

    题意:M行N列的矩阵.Y:起点,T:终点.S.R不能走,走B花费2,走E花费1.求Y到T的最短时间. 三种解法.♪(^∇^*) //解法一:暴力 //157MS #include<cstdio& ...