• [].slice.call(arguments)原理解析


    转载:https://www.jianshu.com/p/f76011a705f6

    javascirpt的类数组对象可以像数组一样使用for循环遍历,但是却不能调用数组原型链的方法,为了让类数组对象可以像数组对象一样调用pushpop等方法,可以将类数组对象转成数组对象:

    将类数组对象转换成数组

    var args = []; 
    var obj = {0:"www",1:"jianshu",2:"com",length:3};
    for (var i = 0; i < obj.length; i++) { 
        args.push(obj[i]);
    }
    console.log(args);  //["www","jianshu","com"]
    //等价于以下的写法
    console.log([].slice.call(obj));  //["www","jianshu","com"]

    理解[].slice.call(arguments)的原理,需要明白:

    • slice()方法的作用
    • call()方法的作用
    • slice()方法的内部实现
    • Array.prototype.slice()
    console.log([1,2,3,4,5].slice(0,1)); //[1]
    console.log([1,2,3,4,5].slice(1,3)); //[2,3]
    console.log([1,2,3,4,5].slice(3)); //[4,5]
    console.log([1,2,3,4,5].slice()); //[1,2,3,4,5]

    数组的slice(start,end)方法,返回从start开始到end的子数组,如果startend都没有设置,则返回整个数组,这个过程不影响原数组。

    • Function.prototype.call()
    function func(name, price) {
      this.name = name;
      this.price = price;
    }
    var food = {name:"apple",price:10};
    func.call(food,"orange",15);
    console.log(food); // {name: "orange", price: 15}

    调用call方法传入的参数比原方法多一个参数,简单来说,call方法的作用就是:用call方法的第一个参数代替func方法内部的this,其他参数为原func方法的参数。

    • slice方法内部实现
      slice方法内部实现,V8源码第587行,其基本原理就类似我们上面开头写的for循环遍历原数组,根据start和end的值再复制一份到新数组并返回。所以当我们使用[].slice.call(arguments),slice方法内部的this就会被替换成arguments,并循环遍历arguments,复制到新数组返回,这样就得到了一个复制arguments类数组的数组对象。

    • 为了提高性能,减少一层对原型链的追溯,一般我们会采用以下的写法

    Array.prototype.slice.call(arguments)
  • 相关阅读:
    redis远程连接超时
    GNU LIBC源代码学习之strcmp
    计算最小生成树
    域名和空间的绑定问题
    Spring MVC 基于Method的映射规则(注解版)
    Spring MVC 基于URL的映射规则(注解版)
    手把手教你编写Logstash插件
    Ruby中如何识别13位的时间戳
    [logstash-input-http] 插件使用详解
    Java直接(堆外)内存使用详解
  • 原文地址:https://www.cnblogs.com/web-record/p/13071153.html
Copyright © 2020-2023  润新知