重新实现Array.prototype.slice的JavaScript谜题未按预期工作

JavaScript puzzle to reimplement Array.prototype.slice not working as expected

本文关键字:JavaScript 工作 slice 新实现 实现 prototype Array      更新时间:2023-09-26

这不是面试用的,别担心:)

我很好奇为什么这两个函数的返回方式不同:

var redundantSlice1 = function() {
    return arguments[0].slice(Array.prototype.slice.call(arguments).slice(1).join())
};
var redundantSlice2 = function() {
    return arguments[0].slice(1,2)
};
redundantSlice1([1,2,3], 1, 2) // [1,2,3]
redundantSlice2([1,2,3], 1, 2) // [2]

redundantSlice2返回我期望的内容,但1,2是硬编码的,这是我试图避免的。

为什么第一个函数具有我所期望的1,2undefined

redundantSlice1中,.join( )默认情况下会将参数转换为以,为分隔符的字符串。因此,对于您的样品,声明

Array.prototype.slice.call( arguments ).slice( 1 ).join( )

实际上"1,2"不是你所期望的[ 1, 2 ]

除此之外,您只向.slice( )传递了一个参数。为了匹配redundantSlice2的行为,必须使用.apply( )

var redundantSlice1 = function() {
    var firstArg = arguments[ 0 ];
    return Array.prototype.slice.apply(
        firstArg,
        Array.prototype.slice.call( arguments, 1 )
    );
};

如果你想这样做,你可以传递一个数组或类似数组的对象,并获得相同的结果

var redundantSlice1 = function(array, begin, end) {
    return Array.prototype.slice.call(array, begin, end)
};

这将适用于传入的1、2或3个参数,与Array.slice的工作方式完全相同

如果你坚持对参数进行切片,并且对函数没有"正式参数"

var redundantSlice1 = function() {
    return Array.prototype.slice.apply(arguments[0], Array.prototype.slice.call(arguments, 1));
};