理解 Array.prototype.slice.apply

1. 首先,我们都理解在js中改变this引用有三种方法,call(), apply(), bind();

2. bind方法是改变函数内this引用,简单不再描述;

3. 至于 call() 和 apply() 两个方法,区别在于,前者是不定长的入参,后者是一个数组;下边重点说apply方法使用;

原理

我们知道js中存在一种类数组对象,比如 {0:1,length:1}   
或者 DOM 对象,或者 arguments 对象;

数组只是一种特殊的对象,数组的特殊性体现在,它的键默认是按次序排列的整数(0,1,2...),所以数组不用为每个元素指定键名,而对象的每个成员都必须指定键名。

所以 JavaScript中的数组也可以看成是这样的对象

   var array = [1, 2, 3];
   var obj = {
      0: 1,
      1: 2,
      2: 3,
      length:3
   }

注意了,这个length属性很重要,有了length就可以像数组一样遍历这个对象了。

再来实现一个简单的slice方法,

function slice(start, end) {
    var array = [];
    start = start ? start : 0;
    end = end ? end : this.length;

    for (var i = start, j = 0; i < end; i++, j++) {
        array[j] = this[i];
    }

    return array;
}

举例:Array.prototype.slice.apply({0:1,length:1});

通过apply,将slice方法中的this指向该对象,遍历生成新的数组对象。

注意点:

1.  使用apply 时要注意:apply或call 只是切换了函数内部 this 的调用,但是执行的方法依然是原始对象上的方法, 即使你在
Array.prototype.slice.call(obj)的 obj 上 覆盖了slice 方法 ,依然会执行 Array 上的 slice 方法;

2.  由于apply方法(或者call方法)也可以绑定函数执行时所在的对象,但是会立即执行函数,因此不得不把绑定语句写在一个函数体内。建议使用函数改变this指向时使用 bind 方法。

3.

bind方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。

element.addEventListener(‘click‘, o.m.bind(o));

上面代码表示,click事件绑定bind方法生成的一个匿名函数。这样会导致无法取消绑定,所以,下面的代码是无效的。

element.removeEventListener(‘click‘, o.m.bind(o));

正确的方法是写成下面这样:

var listener = o.m.bind(o);
element.addEventListener(‘click‘, listener);
//  ...
element.removeEventListener(‘click‘, listener);
时间: 2024-11-06 04:05:39

理解 Array.prototype.slice.apply的相关文章

理解Array.prototype.slice.call(arguments)

在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在js里Array是一个类 slice是此类里的一个方法 ,那么使用此方法应该Array.prototype.slice这么去用 slice从字面上的意思很容易理解就是截取(当然你不是英肓的话) 这方法如何使用呢? arrayObj.slice(start, [end]) 很显然是截取数组的一部分.

(转)Array.prototype.slice.call自解

很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一直是半懂不懂的.昨天晚上看了mootools的源码,google了一下,终于彻底明白了. call方法的作用就不用多说了,Array.prototype.slice.call(arguments,0)就类似于arguments.slice(0),但因为arguments不是真正的Array,所以它没

【js】一些小技巧(1),关于Array.prototype.push,Array.prototype.slice的用法

阅读源码的时候会看到这样操作: 1.Array.prototype.push的介绍 var push = Array.prototype.push; push.apply(args, arguments); 为什么会用push.apply,而不是直接push呢? //push.apply var a = [1,2,3] , b = [4,5,6],push = Array.prototype.push; push.apply(a,b) ; console.log(a)  // [1, 2, 3,

Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)

Array.prototype.push.apply(a,b) 时常看到在操作数组的时候有这样的写法: var a = [1,2,3]; var b = [4,5,6]; a.push.apply(a, b); console.log(a) //[1,2,3,4,5,6] 其实这样的写法等价于: var a = [1,2,3]; var b = [4,5,6]; Array.prototype.push.apply(a, b); console.log(a) //[1,2,3,4,5,6] 这样

伪数组转为数组 Array.prototype.slice.call(arguments)

我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换) 1 var a={length:2,0:'first',1:'second'}; 2 Array.prototype.slice.call(a);// ["first", "second"] 3 4 var a={length:2}; 5

Array.prototype.slice &amp;&amp; Array.prototype.splice 用法阐述

目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, 其中元素的类型必须是相同的, 这个每个元素的索引地址才能被计算出来, 索引通常是数字,用来计算元素之间存储位置的偏移量. 结构如下: javascript数组 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glob

浅谈Array.prototype.slice.call(arguments,0)

在谈论这个问题之前 我们先了解下call的用法及作用 对象.方法.call(obj[,arg1[, arg2[,   [,.argN]]]]]):调用一个对象的一个方法,以另一个对象替换当前对象. 1 function Personal(a){ 2 3 this.name = a; 4 5 this.say = function(){ 6 7 alert(a) 8 } 9 10 } 11 12 function Man(a){ 13 14 this.sex = "maie"; 15 P

转对象(含length属性)成数组Array.prototype.slice.call(arguments)

我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换) 如: 1 var a={length:2,0:'first',1:'second'}; 2 Array.prototype.slice.call(a);// ["first", "second"] 3 4 var a={length:2}

javascript:Array.prototype.slice.call(arguments)

我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换) 如: 1 var a={length:2,0:'first',1:'second'}; 2 Array.prototype.slice.call(a);// ["first", "second"] 3 4 var a={length:2}