简介
我们都知道JavaScript函数的这些愚蠢的arguments
对象。
但为什么反对呢?不是阵列吗?
不,它不是,这就是为什么很多人称它为JavaScripts概念失败的原因:
(function () {
return arguments.slice(); // TypeError: arguments.slice is not a function
}());
意图
好的,这只是我想问的真实内容的介绍,但在问你需要更多信息之前:
在最后几天阅读不同的代码时,我在相当多的地方看到以下代码行时非常伤心。
args = Array.prototype.slice(arguments);
那么,它做了什么,只是将arguments
对象“转换”成一个包含所有原型和东西的数组。
我的解决方案
我想到的是以下内容:虽然JavaScript完全是关于原型设计的,但为什么我们不扩展arguments
对象的prototype
本身呢?我检查了一些网站上的现有脚本,但没有发现我打算找到的东西,最后我自己写了:
(function () {
var i, methods;
arguments.constructor.prototype = Array.prototype;
methods = ['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'slice', 'sort', 'splice', 'toString', 'unshift'];
for (i = 0; i < methods.length; i += 1) {
if (arguments.constructor.prototype.hasOwnProperty(methods[i]) === false) {
arguments.constructor.prototype[methods[i]] = Array.prototype[methods[i]];
}
}
}());
压缩后仅需260字节,并使用arguments
扩展prototype
对象的Array.prototype
。
所以最后我可以像处理“真实”数组一样处理arguments
个对象。
问题
在检查了最着名的JavaScript框架后,我完成了以下操作:none使用这样的构造并扩展arguments
对象的prototype
。
但为什么呢?有什么问题吗,我现在没想到?
答案 0 :(得分:5)
arguments
对象不是类型,它是通用Object
。为了扩展它的原型,你必须扩展Object
的原型,这通常不是一个好主意。
使用arguments
将Array.prototype.slice
转换为数组没有任何问题。
让我们说我要扩展arguments
原型:
arguments.constructor.prototype.foo = 'bar';
这里的问题是arguments.constructor
不是某个Argument
对象,它只是Object
。现在,如果我尝试做一些应该正常工作的事情,那就是fubar&#dd:
var someNewObject = {
someProperty: 'someValue'
};
for (var item in someNewObject) {
console.log(item); // logs someProperty AND foo, not good
}
您可以在行动here中看到这一点。
答案 1 :(得分:2)
通常,大多数人都不愿意改变ECMAScript / JavaScript本机对象。就个人而言,我喜欢你的方法(它聪明而有用);但是,当您将代码引入更大的项目时,会引入问题。当浏览器的Array(本机)对象的实现与标准不同并且其他代码库(如jQuery)处理具有某些期望的那些时,可能会产生意想不到的后果。但是,如果jQuery期望函数的参数属性(/ object)是某种类型并且它已被更改,例如通过代码,您可能会破坏广泛使用的库,如jQuery。
答案 2 :(得分:0)
有用吗? ; - )
如果是这样,我认为你已经实现了你想要的。但是,参数不是数组的一个原因可能是参数变量不是像普通变量那样四处传播。它只能在函数体内访问然后被删除。因此,当突然 一个数组时,我不知道会发生什么。
除此之外,聪明的解决方案!