题目来自于掘金一位分享者的分享 , 我经实验认证写篇文章记之

var obj={'2' : 3,'3' : 4,'length' : 2,'splice' : Array.prototype.splice,'push'   : Array.prototype.push
}
obj.push(1);
obj.push(2);
console.log(obj);
复制代码

请在下方评论区输入你认为的答案吧! 然后在看后面的答案解析吧 。

答案与解析 :

{ '2': 1,'3': 2,length: 4,splice: [Function: splice],push: [Function: push]
}
复制代码

我们其实知道,在JS的世界观中,一切皆对象,Array也是对象,所以像obj这样的类Array对象是可以转化为Array对象的,比如下面这个例子:

var obj = {'0' : 1,'1' : 2,'2' : 3,length : 3
}
//es5写法
var arr1 = [].slice.call(obj);
//es6写法
var arr2 = Array.from(obj);
console.log(arr1,arr2);
复制代码

结果是:

[ 1, 2, 3 ] [ 1, 2, 3 ]
复制代码

这时候arr1arr2都是已经转为了Array对象,这是我们按部就班的写obj对象时,一切看上去都很好,但是如果我们调皮一下,把obj改为:

var obj = {'1' : 2,'2' : 3,'3' : 4,length : 3
}
复制代码

结果就开始调皮了:

[ <1 empty item>, 2, 3 ] [ undefined, 2, 3 ]
复制代码

不管是<1 empty item>还是undefined ,我们可以看出,把类Array对象转为数组的时候,转换过程会根据length属性和元素下标值来生成转换后的数组中元素,超出length范围的下标对应元素会被删除,而在length范围内下标不存在的元素会被赋值为空或undefined。转换为数组对象后,一切行为就和数组行为一致了,也即Array原型上的方法都可以正常使用了。

那如果我们不转换obj为Array,而是直接让obj继承Array原型上的方法呢?这也就引出本篇博文的标题:类Array对象中是否该直接使用Array原型的方法?其实答案是明了的,正如我们答案所示的那样令人意外,在类Array对象中直接使用Array原型方法显然是容易出错的写法。那我们接下来讨论,为什么答案是如此的,要想知道为什么我们需要追根溯源,我找到了Array.prototype.push方法的源代码,如下:

function ArrayPush () {  var n = TO_UNIT32(this.length);  var m = %_ArgumentsLength();  for (var i = 0; i < m; i++) { // 逐个复制元素this[i + n ] = %_Arguments(i);}  this.length = n + m; // 修改数组的lengthreturn this.length;
}
复制代码

关键就在这句this[i + n ] = %_Arguments(i);n=this.lengthi表示第i个参数,也就是说,元素的添加是和length属性有关的,push的下一位是下标为length的元素位置,本题中length=2 ,自然push的两个值会覆盖掉下标为23的元素位置

觉得本文对你有帮助,可以关注我的微信公众号!感谢关注!

转载于:https://juejin.im/post/5cac99c9f265da03b917fa70

类Array对象中是否该直接使用Array的原型方法?相关推荐

  1. 类与对象(中) 构造函数和析构函数

    目录 一.类的6个默认成员函数 二.构造函数 2.1定义 2.2特性 1. 函数名和类名相同: 2. 没有返回值: 3.对象实例化的时候编译器自动调用: 4.可以函数重载. 2.3 无参的构造函数和全 ...

  2. 《C++类和对象中的static、友元以及内存管理 总结》

    学习完前面有关类和对象的基础知识,这里再对其中的某些容易出现的错误及经常性会遇到的问题进行阐述,加深对类和对象的理解是学好C++的基础. 文章目录 1.再次谈及构造函数 2.static成员 3.友元 ...

  3. 2021小白Python学习记录Day7 面向对象基础(上) (定义类和对象、__init__传参、self、魔术方法)

    目录 一.定义类和对象 1.定义类 2.创建一个对象 2.1 创建一个实例对象并调用实例方法 2.2 创建另一个实例对象: 2.3 添加实例属性 二.__init__(self) 1. __init_ ...

  4. 【c++师傅领进门,修行靠个人】第五篇:C++类和对象中的一些小细节

    面向对象的总结 1 初始化列表 2 如何突破封装 3 了解静态成员 4 类也能套娃 5 面向对象总结 1 初始化列表 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成 ...

  5. 【类和对象(中)】六大默认成员函数

    文章目录 前言 一.

  6. js内置对象中Math绝对值和三个取整方法

    1.Math绝对值 Math.abs() 函数返回数字的绝对值. Math.abs('-1'); // 1 Math.abs(-2); // 2 Math.abs(null); // 0 Math.a ...

  7. 详解Javascript中的Array对象

    本文地址:http://luopq.com/2016/04/01/Array-in-Javascript/,转载请注明 在上一篇文章中,我们详细介绍了Object对象.在这一篇文章中,我们来说说Arr ...

  8. 类与对象练习题(三)---Array/Person类

    在刚开始学习c++的时候刷了很多基础题,这些基础题比较适合初学C++的码友,所以在学完就立即进行了整理,一是为了让初学C++的码友有所参考,二也是为了复习一下所学过知识. 但因为当时在整理时,时间有点 ...

  9. JavaScript中的Array对象

    1.创建Array对象 创建Array对象的语法 var 数组名 = new Array(); 定义数组之后.就须要向数组中加入元素.格式例如以下 数组名[<下标>]=值: 2.Array ...

最新文章

  1. php中怎么过滤器_PHP 过滤器(Filter)
  2. 【DDS】基于FPGA的DDS研究与设计
  3. eureka实例相关配置
  4. python 英语分词_Python英文文本分词(无空格)模块wordninja的使用实例
  5. 编译原理预测分析程序
  6. linux升级openssl需要先卸载吗,在Linux系统上升级OpenSSL的方法
  7. 5-7激活层-BN层-FC层-损失层
  8. javascript中的错误处理机制
  9. WSL离线安装到任意目录
  10. drawroundrect java_java – fillRoundRect看似无法正确呈现的问题
  11. 中望cad自定义快捷键命令_中望CAD快捷键全集
  12. 2021-04-28
  13. http工作原理和机制
  14. 第二章 让你的kali系统变得更好用
  15. 手把手教你使用python的zipfile模块巧解word批量生成问题
  16. win10解决安装.NET Framework 3.5安装不上,错误代码:0x800F081F,解决办法:超级管用。
  17. 小白Nvidia TK1 Jetpack安装/重装系统详细步骤(小车第一步)
  18. 笔记 09-集合(HashSet HashMap TreeMap) 练习
  19. 创建一个8*8的国际象棋棋盘(黑块为0,白块为1)
  20. 企业微信审批页面HTML,企业微信审批模板调用示例及注意事项

热门文章

  1. AI杂谈(2)请教支持向量机用于图像分类
  2. vue的v-model绑定对象属性时,更新不及时,不能修改
  3. 利用 PicGo 实现 MarkDown 自动上传图片
  4. CSS精粹之布局技巧
  5. react-生命周期
  6. php 100万数据,关于批量插入数据之我见(100万级别的数据,mysql)
  7. activiti 7中文文档_如何阅读文档-以Pandas库为例
  8. java 程序打包成jar_Java程序打包成jar包
  9. C语言-输入一个正整数,输出它的所有质数因子
  10. typora插入代码设置_一篇文章教会你如何在Markdown文档中插入数学公式