Underscore.js first函数无法处理arguments对象问题求助
为什么我的Underscore.js first函数复刻版不支持arguments对象?
原代码未通过测试的核心原因
你写的原代码里,用Array.isArray(array)来判断输入是否为数组,但arguments对象并不是真正的数组——它是一个「类数组对象」,Array.isArray(arguments)会返回false。所以当测试用例传入arguments对象时,你的代码直接触发了!Array.isArray(array)的判断,返回了空数组,自然通不过测试。
解决方案的原理
解决方案里新增的Object.prototype.toString.call(array) === "[object Arguments]"是关键:
Object.prototype.toString是判断对象类型的可靠方法,对arguments对象调用时,会返回标准的"[object Arguments]"字符串,能准确识别出arguments类数组。- 把这个判断和
Array.isArray(array)做或运算,就能让函数同时接受数组和arguments对象作为输入。
额外优化指导
- 统一处理类数组:除了arguments,DOM元素集合(比如
document.querySelectorAll的返回值)也是常见的类数组,你可以用Array.from()把类数组直接转成数组,这样后续逻辑不用区分数组和类数组,代码更简洁:
_.first = function (array, n) { // 先统一转换:数组/arguments转成数组,其他情况返回空数组 const targetArr = (Array.isArray(array) || Object.prototype.toString.call(array) === "[object Arguments]") ? Array.from(array) : []; if (isNaN(n) || n == null || n <= 0) { // 注意处理空数组的情况,避免返回[undefined] return targetArr.length ? [targetArr[0]] : []; } // 用数组的slice方法替代手动循环,更简洁且自动处理n大于数组长度的情况 return targetArr.slice(0, n); };
- 简化判断逻辑:
n == null已经覆盖了n为undefined或null的场景,不用额外单独判断。 - 边界情况处理:原代码在输入空数组且n无效时,会返回
[undefined],上面的优化代码里增加了targetArr.length的判断,避免这种不合理的返回值。
内容的提问来源于stack exchange,提问作者Detla888
相关产品推荐
相关产品推荐

