浅谈数组API——push方法的一些你不知道的小众知识

587 阅读2分钟

「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」。


前言

在实际项目中,相信大家用得最多的原生api应该非数组和对象莫属了吧,但是对于它们官方api,好像我们却很少有真正去了解,那今天我就结合自己的知识,分享一下自己对数组的认识吧

数组API

关于数组的api,请问大家都知道哪些?(我觉得这个问题都不是问题,网上随便一找就有)

这里放上MDN的传送门

slicespliceindexOfunshiftshiftpoppushsortreverseconcatjoin

但是网上基本上对数组api的提问都是,哪些api会改变数组本身,哪些api不会改变数组本身,这些基本都是八股的东西了,今天我想聊一点比较稀奇古怪的东西

关于数组的push方法

push 方法具有通用性。该方法和call()、apply()一起使用时,可应用在类似数组的对象上。通常来讲,push会在数组最尾端加入数据,即入队和进栈

但是你有没有想过,数组的push操作,具体是怎么添加数据的呢?

一点小疑问

但push真的只能在数组尾端添加数据嘛?来看一个案例先

var obj = {
  "2": "a",
  "3": "b",
  "length": 2,
  "push": Array.prototype.push
}
obj.push("c");
obj.push("d");

两次push之后,obj 会的值会是什么呢?先思考一下,答案马上揭晓

var obj = {
  "2": "c",
  "3": "d",
  "length": 4,
  "push": Array.prototype.push
}

Anything was so amazing !!!

push的实现原理

push方法根据length属性来决定从哪里开始插入给定的值。如果length不能被转换成一个数值,则插入的元素索引为0。但当length不存在的时,将会创建它

唯一的原生类数组(array-like)对象是 Strings,尽管如此,它们并不适用该方法,因为字符串是不可改变的。

所以说,push会根据对象length属性的值去确定插入的位置,转化成代码就是:

Array.prototype.push = function (target) {
    obj[obj.length] = target;
    obj["length"]++;
}

MDN关于Array.push的解释

结语

就如同上文提到的,应该很少同学回去关注push方式具体是怎么实现的吧。我觉得,我们不应该被大众带偏了,网上通篇说哪些api会修改数组本身,就死死盯着这个问题。我觉得解决一个问题应该是去了解这个问题的本质,从问题本身出发,以后遇到类似的便可以迎刃而解