[].slice.call的理解
首先要说明[].slice.call()与Array.prototype.slice.call() 有什么区别?
[].slice === Array.prototype.slice
true
[]为创建数组,当[].slice的时候,自然会去找原型链
[].__proto__.slice === Array.prototype.slice
true
Array.prototype.slice是定义的方法,可以被重写
[].silce是使用定义的方法
- 自身的属性不同(因为原型与[]的区别)
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
会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。对于字符串、数字及布尔值来说(不是
String
、Number
或者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的理解的更多相关文章
- Array.prototype.slice.call()的理解
最近在看廖雪峰的JS课程,浏览器中的操作DOM的那一章,有这样一道题. JavaScript Swift HTML ANSI C CSS DirectX <!-- HTML结构 --> & ...
- [转] 对Array.prototype.slice.call()方法的理解
在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢? 1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规 ...
- 对Array.prototype.slice.call()方法的理解
在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢? 1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规 ...
- 对Array.prototype.slice.call()方法的理解在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢?
1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 指倒数第 ...
- Array.prototype.slice.call()方法的理解
1.基础1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 指倒数第二 ...
- Go语言中slice使用注意事项
Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一 ...
- JavaScript中的Array.prototype.slice.call()方法学习
JavaScript中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). 但有一个例外 ...
- golang学习笔记 ---slice
Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一 ...
- JavaScript中的数组Array方法
push(),pop()方法 push(),pop()方法也叫栈方法,push()可以理解成,向末尾推入,而pop()恰好相反,可以理解成从末尾移除(取得). var nums=[1,2,3,4]; ...
随机推荐
- 调用Linux的busybox,通过linux命令来获取AndRoidIP
//根据busybox获取本地Mac public static String getLocalMacAddressFromBusybox(){ String result = "" ...
- 爬虫入门之Scrapy框架基础rule与LinkExtractors(十一)
1 parse()方法的工作机制: 1. 因为使用的yield,而不是return.parse函数将会被当做一个生成器使用.scrapy会逐一获取parse方法中生成的结果,并判断该结果是一个什么样的 ...
- Topshelf Configuration z
Topshelf Configuration While the Quickstart gives you enough to get going, there are many more featu ...
- QT的动图加载
http://blog.csdn.net/u011619422/article/details/47342403
- c++ nested class 嵌套类。
c++ primer 658页 嵌套类最常用于定义执行类,
- .NET控件命名规范
一.基本数据类型前缀 数据类型 数据类型简写 Array arr Boolean bln Byte byt Char chr DateTime dtm Decima ...
- 分布式链路跟踪系统架构SkyWalking和zipkin和pinpoint
Net和Java基于zipkin的全链路追踪 https://www.cnblogs.com/zhangs1986/p/8966051.html 在各大厂分布式链路跟踪系统架构对比 中已经介绍了几大框 ...
- 不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller
摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中“不规矩”的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧,调整一下思维便能重用 ...
- 通过ajax获取一个多位数,当容器显示在屏幕可视区时,让数字以滚动的形式显示
{ "data": "268" } json数据 <!DOCTYPE html> <html> <head lang=&quo ...
- python 时间和时间戳的转化
时间戳与时间之间的转换,需要一个中间过程,即将先将时间或时间戳先转为时间元组! 1.时间转时间戳: import datetime, time s = datetime.datetime(2016,6 ...