【记面试遇到的坑】 对象使用数组的push方法后会发生什么?

本文探讨了一道面试题:对象使用数组的push方法后的结果。解释了由于对象被视为类数组,push方法会导致对象的键被隐式转换为字符串,从而覆盖原有键值。同时,push还会自动为对象添加length属性。这种问题在实际开发中不常见,但在面试中常出现,引发对JavaScript深入理解的讨论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

奇怪的面试题

最近碰到一道奇奇怪怪的面试题,对象使用数组的push方法后会发生什么?题目如下:

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

求最后打印出的的obj是什么?

答案是:

{
    '2':1
    '3':2,
    '4':3,
    'length':5,
    'splice':Array.prototype.splice,
    'push':Array.prototype.push
} 

原因是:
obj是有长度的,相当于类数组,调用数组的push方法,会在数组的最后添加一项。

  1. 第一次调用,相当于数组下标为2的那一项被赋值为1,下标为2,当做作为对象的key值的时候,会隐式调用toString方法转换为字符串2。这样则与obj本来的key"2"重复了,原来的key为2的value就会被覆盖掉。以此类推

  2. 第二次push的时候,数组下标为3的那一项被赋值为2.下标为3,隐式转换为字符串之后把之前的key覆盖掉 "3":4 =>"3":2

  3. 第三次push的时候,数组下标为4的那一项被赋值为3,下标为4 隐式转换为字符串后没有之前的key与它冲突,所以向原对象中添加 "4":3

至于长度为什么会变,这就涉及数组push方法的原理了
push方法大概是这样实现的

function my_push(x){
  this.length===undefined?this.length=0:this.length
  //自己的长度为索引赋值	
  this[this.length] = x
  //此处还需注意length会自动加一
   this.length++  
   return this.length;
}

现在我们来测试一下:

var obj = {
    '2':3,
    '3':4,
    'length':2,
    'splice':Array.prototype.splice,
    'push':Array.prototype.push
}
my_push.call(obj,1)
my_push.call(obj,2)
my_push.call(obj,3) 
console.log(obj)

结果是和上面一样的。

至于为什么要在my_push函数中添加这样的一句话
this.length===undefined?this.length=0:this.length

看下面的代码就知道了

let obj2 = {
    '2':3,
    '3':4,
    'len':2,
    'push':Array.prototype.push
}
obj2.push(1) //obj[0] = 1
obj2.push(2) //obj[1] = 2
obj2.push(5) //obj[2] = 5 

console.log(obj2); 

注意啊,这里是没有长度length的,结果输出为

  '0': 1,
  '1': 2,
  '2': 5,
  '3': 4,
  'len': 2,
  'push':Array.prototype.push
   length: 3

可以看到运行了执行push操作,自动为obj2添加了一个length的属性,并将属性值设置为了0,也就是说当length为undefined的时候,会自动添加一个length属性并初始化为0

这就是为什么要在my_push里添加这样一句话this.length===undefined?this.length=0:this.length

下面我们接着来测试一下

let obj2 = {
    '2':3,
    '3':4,
    'len':2,
    'push':Array.prototype.push
}
my_push.call(obj2,1)
my_push.call(obj2,2)
my_push.call(obj2,5)
console.log(obj2)

输出为:

  '0': 1,
  '1': 2,
  '2': 5,
  '3': 4,
  'len': 2,
  'push':Array.prototype.push
  length: 3

和前面的直接调用obj.push的输出结果是一样的。

后话

感觉面试都爱出一些奇奇怪怪的题,就是那种在真实开发不会用到的题,太卷了,太卷了,心累!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值