Array.prototype.slice.call(arguments,0)含义

本文详细介绍了如何将具有length属性的类数组对象转换为标准数组的方法。通过使用Array构造函数和原型链上的slice方法,结合call函数改变作用域,可以轻松实现这一转换,适用于arguments对象和其他类似结构。

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

 

能将具有length属性的对象 转成数组

1、Array是构造函数

2、arguments是类数组对象(缺少很多数组的方法)

3、call让一个对象调用另一个对象的方法。你可以使用call()来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)

4、 slice从一个数组中切割,返回新的数组,不修改切割的数组

本质就是arguments这个对象使用了数组的slice这个方法,得到了参数构成的数组(也可以用apply)。slice大致内部实现

//使用prototype只是因为Array是构造函数

Array.prototype.slice.call([1,2,3,4,5],0)//  [1, 2, 3, 4, 5]

[].slice.call([1,2,3,4,5],1)// [2, 3, 4, 5]


//没有length的对象
var a={length:2, 0:'first', 1:'second'};
Array.prototype.slice.call(a);//  ["first", "second"]

var a={length:2, 0:'first', 1:'second'};
Array.prototype.slice.call(a,1);//  ["second"]

var a={0:'first', 1:'second'};
Array.prototype.slice.call(a,1);//  []

slice大致内部实现

Array.prototype.slice = function(start,end){
     var result = new Array();
     start = start || 0;
     end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键
     for(var i = start; i < end; i++){
          result.push(this[i]);
     }
     return result;
}

转成数组的通用函数

 

var toArray = function(s){
    try{
        return Array.prototype.slice.call(s);
    } catch(e){
            var arr = [];
            for(var i = 0,len = s.length; i < len; i++){
                   //arr.push(s[i]);
                   arr[i] = s[i]; //console.timeEnd测试以后比push快
            }
             return arr;
    }
}

 

<think>嗯,我现在需要解释一下Array.prototype.slice.call()这个方法的用途和原理。首先,用户可能对JavaScript中的数组和类似数组的对象不太熟悉,所以应该从基础开始讲起。 首先,slice()方法本身是数组的一个方法,用于截取数组的一部分,返回一个新数组,而不修改原数组。比如,arr.slice(1,3)会返回从索引1到3(不包括3)的元素。 但问题在于,类似数组的对象(比如arguments对象、DOM元素集合等)并不是真正的数组,它们没有slice方法。这时候,如果直接调用arguments.slice()会报错,因为arguments没有这个方法。 这时候,Array.prototype.slice.call(arguments)的作用就体现出来了。通过使用call方法,可以改变slice方法的this指向,让slice方法在类似数组的对象上运行。因为slice方法内部只依赖于数字索引和length属性,而类似数组的对象正好具备这些特性,所以这样就可以将这类对象转换为真正的数组。 举个例子,假设有一个类似数组的对象: var arrayLike = {0: 'a', 1: 'b', length: 2}; var arr = Array.prototype.slice.call(arrayLike); 这样,arr就会变成['a', 'b'],一个真正的数组。 需要注意的是,在ES6之后,更推荐使用Array.from()方法来转换类数组对象,或者使用展开运算符[...arrayLike],但这两种方法需要对象是可迭代的,而Array.prototype.slice.call()则不需要可迭代,只需要有length属性和索引即可。 此外,如果类数组对象的length属性不准确,或者索引不连续,可能会导致转换后的数组不符合预期。因此,使用时需要确保类数组对象的结构正确。 总结一下,Array.prototype.slice.call()的作用是将一个类数组对象转换为真正的数组,通过借用数组的slice方法,并利用call改变this指向来实现。这在ES5及之前的环境中非常常见,但在现代代码中可能更倾向于使用ES6的新方法。</think>好的,我来逐步解释 `Array.prototype.slice.call()` 的作用和原理: ### 1. **基础知识点** - **`slice()` 方法**:数组的 `slice()` 方法用于截取数组片段,返回新数组,例如: ```javascript const arr = [1, 2, 3, 4]; console.log(arr.slice(1, 3)); // 输出:[2, 3] ``` - **`call()` 方法**:用于改变函数执行时的 `this` 指向,例如: ```javascript function showName() { console.log(this.name); } const obj = { name: "John" }; showName.call(obj); // 输出:John ``` --- ### 2. **问题场景** 类数组对象(如 `arguments`、DOM元素集合)有数字索引和 `length` 属性,但**没有数组方法**: ```javascript function example() { console.log(arguments.slice()); // 报错!arguments 没有 slice 方法 } example(1, 2, 3); ``` --- ### 3. **解决方案** 通过 `Array.prototype.slice.call(类数组对象)`: ```javascript function example() { const argsArray = Array.prototype.slice.call(arguments); console.log(argsArray); // 输出真正的数组:[1, 2, 3] } example(1, 2, 3); ``` --- ### 4. **原理拆解** - **`Array.prototype.slice`**:获取数组原型的 `slice` 方法。 - **`.call(arguments)`**:让 `slice` 方法在 `arguments` 对象上执行,此时: - `slice` 的 `this` 指向 `arguments` 对象 - `slice` 根据 `this.length` 和数字索引生成新数组 --- ### 5. **现代替代方案**(ES6+) - **`Array.from()`**: ```javascript const argsArray = Array.from(arguments); ``` - **展开运算符**: ```javascript const argsArray = [...arguments]; ``` --- ### 6. **注意事项** - **必须满足两个条件**: 1. 对象有 `length` 属性 2. 有连续的数字索引(例如 `{0: 'a', 1: 'b', length: 2}`) - **不适用于稀疏结构**: ```javascript const bad = { 0: 'a', 2: 'c', length: 3 }; console.log(Array.prototype.slice.call(bad)); // 输出:['a', empty, 'c'] ``` --- ### 总结表格 | 方法 | 适用场景 | 兼容性 | 是否需要迭代器 | |-------------------------------|----------------------------|------------|----------------| | `Array.prototype.slice.call()` | 类数组对象转数组 | 全浏览器 | 否 | | `Array.from()` | 类数组/可迭代对象转数组 | ES6+ | 是(可选) | | `[...类数组]` | 可迭代的类数组对象转数组 | ES6+ | 是 | 通过这种机制,`Array.prototype.slice.call()` 成为了早期 JavaScript 中将类数组对象转换为标准数组的标准做法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值