好久没上SF,昨天上来看到一个问题,引起了我的兴趣。一番探索和研究后,有了此篇文章,也算是对该问题的解答。

let pretendArr = {0:0,1:1,2:2,length:3};
[].slice.call(pretendArr); //[0,1,2]

请看上面的例子
可能很多前端童鞋都很知道 Array.prototype.slice.call 可以用于将类数组对象转为数组,call 和 apply 的用法和作用网上一搜一大堆。
在这里主要是为了让 pretendArr 借用Array构造函数原型上的 slice 方法,并且改变 slice 方法里的 this 的指向。
所以这个问题其实不在于 call 或者 apply,关键在于 Array.prototype.slice 这个方法上。

slice这个方法是js原生方法,自然而然,我会想到去找找 es 的规范,看看这个方法是怎样定义,以及如何实现的。

以下是es对该方法定义的截图,图片看不清楚的童鞋可以看看链接

嫌英文字母太多的可以直接看以下我写的slice方法的伪代码:

Array.prototype.slice = (start, end) => {let O = ToObject(this)let A = new Array()let lenVal = O.lengthlet len = ToUnit32(lenVal)let relativeStart = ToInteger(start)let k, final, relativeEndif (relativeStart < 0) {k = max(len + relativeStart, 0)} else {k = min(relativeStart, len)}if (end === undefined) {relativeEnd = len} else {relativeEnd = ToInteger(end)}if (relativeEnd < 0) {final = max(len + relativeEnd, 0)} else {final = min(relativeEnd, len)}let n = 0while (k < final) {let Pk = ToString(k)let kPresent = O.hasOwnProperty(Pk)if (kPresent) {let kValue = O[Pk]Object.defineProperty(A, ToString(n), {value: kValue,writable: true,enumerable: true,configurable: true})}k++n++}return A
}

ToObject、ToUnit32、ToInteger、ToString
slice 方法不要求 this 必须是数组,因此类数组对象也可以调用该方法,在本例中入参 startend 均为 undefined,实际上是根据 类数组对象 的 length 属性,从0到length-1去把类数组对象对应的值取出来,放到前面声明的数组 A 里,最终再return A
因此,类数组对象的 length 属性很重要,并且该对象里的数序也很重要,都会影响到转换为数组的结果。如以下例子:

let pretendArrA = {0:0, 1:1, 2:2, length:2};
[].slice.call(pretendArrA); //[0,1]let pretendArrB = {0:0, 2:2, length:3};
[].slice.call(pretendArrB); //[0, undefined, 2]

第一次写文章,想到哪写到哪,写得有点乱,各位看官勿怪,如果对你有用,还请点个赞~

Array.prototype.slice.call 将伪数组转成真数组的原理是什么?相关推荐

  1. Array.prototype.slice.call()方法详解

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

  2. Array.prototype.slice.call(arguments,0); 上下调用模型

    var fn9 = (function () {var arr = {}; //缓存对象var counter = function (arr) { //计算函数//args也就是fn9(1, 2, ...

  3. Array.prototype.slice.call(arguments)对象转成数组

    转成数组的通用函数 1 var toArray = function(s){ 2 try{ 3 return Array.prototype.slice.call(s); 4 } catch(e){ ...

  4. [转载]Array.prototype.slice.call(arguments,1)原理

    Array.prototype.slice.call(arguments,1)该语句涉及两个知识点. arguments是一个关键字,代表当前参数,在javascript中虽然arguments表面上 ...

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

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

  6. Array.prototype.slice.call(arguments)

    Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与co ...

  7. slice,Array.prototype.slice,Array.protyotype.slice.call

    slice 特点:基于当前数组中的一或多个项创建一个新数组.[原数组不会被修改] 返回结果:返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象. 语法: arr.slice() ...

  8. Array.prototype.slice.apply(arguments)和[].slice.apply(arguments)解析

    我们知道,函数内部 arguments 是一个类数组对象,不是真正的数组,因此也无法使用数组的各种方法.想详细了解 argument 对象可以前往函数中的 arguments. (function f ...

  9. Array.prototype.slice Array.prototype.splice 用法阐述

    目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, ...

最新文章

  1. 【LeetCode】- Search Insert Position(查找插入的位置)
  2. 【JulyEdu-Python基础】第 8 课:Python第三方库
  3. ubuntu安装python3.6_如何在Ubuntu19.04上安装Python3.6?
  4. 计算机组成原理写一个运算器,计算机组成原理运算器的实现实验报告.doc
  5. 一篇文章了解数据库系统
  6. 运维小白linux基础知识总结
  7. 中央电视台的糖尿病案例解说 作者:倪海厦
  8. FinsTCP协议报文详细分析
  9. 【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)
  10. CenterNet代码解析-ctdet目标检测
  11. a = a + 1,a+=1, a++, ++a 区别在哪
  12. Django建立一个音乐网站(一)
  13. 关于使用iframe登录超时,登录页内嵌在原页面
  14. 关于UVM中的Sequence(一)
  15. 轻薄游戏本没性能?醒醒 外星人来了
  16. ThinkPHP内核新版抢单系统,招财宝自由宝区块系统源码带门票支付与激活码功能源代码全开源无加密
  17. k8s中GPU虚拟化工具gpu-manager的安装
  18. 固体微电子学与半导体物理学(八)
  19. 浏览器原理与渲染流程
  20. Fiddler下载安装 Mac版

热门文章

  1. 如何创建脱机数据库应用程序思路
  2. 作为前端,你需要了解的js构造函数和原型
  3. Webpack实战(二):基础配置入门 - webpack-dev-server的介绍与用法
  4. 6个很棒的PostCSS插件,让您成为一个CSS向导
  5. 引用参数与引用返回值
  6. 7-63 情人节 (15 分)(c++stl)
  7. R7-3 极坐标->直角坐标 (10 分)
  8. 因式分解 (10 分)
  9. PTA数据结构期末练习 - 单选题、判断题
  10. 鸿蒙系统9月11号上市吗,9月11日鸿蒙系统2.0要搭载华为全家桶来了,你期待吗?...