JavaScript中Object借用Array方法的原理与陷阱

作者:拾光

时间:2026-10-26

浏览:184

本文深入解析JavaScript中Object借用Array原型方法的原理。通过演示push、splice等方法在普通对象上的应用,揭示其模拟数组行为的机制。同时指出直接修改length属性不会自动清理元素这一潜在陷阱,并结合jQuery源码分析其内部实现逻辑,帮助开发者理解类数组对象的构建与局限。

文章目录
Array.prototype.push

Object借用Array方法的基本原理

Array.prototype.push方法用于向数组末尾添加元素,并自动更新length属性,最终返回更新后的数组长度。


如果尝试在普通Object对象上调用push方法,会发生什么?


观察以下代码示例,你会发现该对象表现得如同数组一般,其length属性也会随之自动更新。


具体实现代码如下:

 
var push = Array.prototype.push;
var obj = {};
push.call(obj, "hello"); // 返回值 1
// obj {"0":"hello", length:0}
push.call(obj, "world"); // 返回值 2
// obj {"0":"hello", "1":"world",length:2}

模拟数组行为的实现细节

Array.prototype.length Array.prototype.splice


将length属性和splice方法赋予Object对象。


观察下面的代码:这个对象看起来竟然像是一个数组?实际上并非如此,这很可能是调试工具在输出检查时产生的一种视觉假象。


我们使用instanceof运算符进行测试:obj instanceof Array //false


var obj = { length:0, splice:Array.prototype.splice};console.log( obj ); // 打印:[]



继续看下面的代码:

obj.push(0)//返回obj.length


1obj.push(1)//返回obj.length


2obj.splice(0, 1);//删除第一项 返回删除项


[0]obj.length // 1 splice删除一项的时候同样更新 length属性


这样obj的表现几乎和array一样了。不出意外slice,pop,shift,unshift什么的都可以正常工作在object中。


不过如果直接设置length,在数组中会删除大于length的下表的项, 但里的obj并不不会更新。



应用在哪?

jQuery中的类数组对象实现与陷阱

jQuery对象表现像一个array,其实他是一个对象。这种对象如何new出来呢?


实际jQuery把Array的方法借给Object,从而达到这个jQuery对象的效果,jQuery对象内部也直接使用push等Array的方法。


看看jQuery的部分源码 (注意加粗)


代码如下:

 
// Start with an empty selector
selector: "",
// The current version of jQuery being used
jquery: "1.7.1",
// The default length of a jQuery object is 0
length: 0,
...... 
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
sort: [].sort,
splice: [].splice

如果你要把Object玩成Array,那么可能潜在的问题length属性不会和“数组”项总和对应起来。


所以直接使用length设置长度不会得到支持。



看下面jquery代码,虽然length更新了,jquery的对象并没更新。(当然这并不是jquery的问题)


var jq = $('div') //假设我们在页面获取了40个


divjq.length // 40


jq.length = 0;jq// ? jq中仍然存放了40个dom对象 length属性不会和“数组”项总和对应起来。


Object使用array的方法还能正常工作,实在有些意想不到,可能实际应用远不止这些。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章