概述

今天在看书的时候看到Array.prototype.slice.call(arguments),有点看不懂,所以认真研究了一下,记录下来,供以后开发时参考,相信对其他人也有用。

call

每一个函数都有一个call方法,它可以接受很多参数,其中第一个是这个函数的上下文,后面的是函数的参数。比如:

function add(a, b) {
return a + b;
} add(3, 4); //7
add.call(null, 3, 4); //7
add.call(this, 3, 4); //7

如果call的第一个参数为null的时候,此时他的上下文会自动是函数的上下文。

事实上,函数调用的深层原理就是通过call方法调用的。

并且我们看到,call方法第一个参数后面的参数都会传递给前面的那个函数。

Array.prototype.slice.call(arguments)

上面的很好懂,但是如果call方法只接一个参数呢?这个上下文是怎么回事?应该把怎样的上下文传递进去?比如说下面的代码应该怎么理解?

function Haha() {
this.id = 2;
} function Yaya() {
Haha.call(this);
}

其实很简单,如果只有一个参数的情况,那么call前面那个函数里面应该有this,否则就相当于没有参数。这个时候就会给Yaya中的this绑定值

还有一种情况,不是绑定值,而是直接调用

Array.prototype.slice.call(arguments);

这个时候,就相当于使用arguments.slice(),即是用参数来调用这个函数,只不过只是相当于而已,因为这个参数里面没有call前面的方法。

函数借用

这是一种借用方法的形式。这里列举几个常见的:

对一个对象使用Object.prototype.toString.call,来判断这个对象的类型:

Object.prototype.toString.call([2, 3, 4]); //返回'[object Array]'

由于字符串没有join方法,所以用Array.prototype.join.call对字符串执行连接:

Array.prototype.join.call('foo', '-'); //返回'f-o-o'

由于字符串没有map方法,所以用Array.prototype.map.call对字符串的每一个字符执行操作:

Array.prototype.map.call('foo', (item) => {
return item.toUpperCase(item);
}).join(''); //返回FOO

Function.prototype.call.bind

如果我们嫌Array.prototype.slice.call()太长想要简写怎么办?如果按照下面的代码就会报错:

const aa = Array.prototype.slice.call;
aa([2, 3, 4]);

原因是传递给aa的是slice方法的call函数,它并没有被"绑定到"Array.prototype.slice。

这个时候就需要bind函数了,它的参数完全和call一样,只不过它是延迟执行的,只有在被用到的时候才执行,而call会立即执行这个函数。

const aa = Function.prototype.call.bind(Array.prototype.slice);
aa([2, 3, 4]);

上面的代码很好理解,call也是一个函数,它也有一个bind方法,这个bind方法把call的上下文绑定给Array.prototype.slice,而这个call是哪里来的?是Function.prototype里面定义的。

值得一提的是,bind函数兼容所有主流浏览器,并且兼容ie>=9,所以在移动端或者ie只兼容到9的网页里面可以毫不犹豫的使用。

Array.prototype.slice.call引发的思考的更多相关文章

  1. js基础进阶--关于Array.prototype.slice.call(arguments) 的思考

    欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...

  2. 由[].slice.call()引发的思考

    由[].slice.call()引发的思考   经常看到大家用[].slice.call()或者Array.prototype.slice.call():  我一直是一知半解的,今天算是基本弄清楚了, ...

  3. 【javascript 技巧】Array.prototype.slice的妙用

    Array.prototype.slice的妙用 开门见山,关于Array 的slice的用法可以参考这里 http://www.w3school.com.cn/js/jsref_slice_arra ...

  4. Array.prototype.slice.call(arguments)

    Array.prototype.slice.call(arguments)能够将具有length属性的对象转化为数组, 可以理解为将arguments转化成一个数组对象,让它具有slice方法 如: ...

  5. IE下Array.prototype.slice.call(params,0)

    i8 不支持 Array.prototype.slice.call(params,0) params可以是 HTMLCollection.类数组.string字符串

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

    很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一 ...

  7. 详解 Array.prototype.slice.call(arguments)

    首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...

  8. Array.prototype.slice && Array.prototype.splice 用法阐述

    目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, ...

  9. Array.prototype.slice.call(document.querySelectorAll('a'), 0)

    Array.prototype.slice.call(document.querySelectorAll('a'), 0)的作用就是将一个DOM NodeList 转换成一个数组. slice()方法 ...

随机推荐

  1. 离线部署 pm2 管理node程序

    在服务器不能联网的情况下: 在可以联网的机器上: npm install pm2 -g 全局安装pm2: 然后查看一下本地安装的默认路径: npm config get prefix, 在其  lib ...

  2. (转)Detect it Easy(壳侦测工具)使用方法介绍

    http://www.ucbug.com/jiaocheng/129805.html Detect it Easy是一个多功能的PE-DIY工具,主要用于壳侦测.功能正日益完善,是不可多得的破解利器! ...

  3. 如何使用Shiro

    一.架构 要学习如何使用Shiro必须先从它的架构谈起,作为一款安全框架Shiro的设计相当精妙.Shiro的应用不依赖任何容器,它也可以在JavaSE下使用.但是最常用的环境还是JavaEE.下面以 ...

  4. TCP/UDP 常用端口列表

    计算机之间依照互联网传输层TCP/IP协议不同的协议通信,都有不同的对应端口.所以,利用短信(datagram)的UDP,所采用的端口号码不一定和采用TCP的端口号码一样.以下为两种通信协议的端口列表 ...

  5. 原子性: Interlocked 类

    public class CounterNoLock:CountBase { private int _count; public int Count { get { return _count; } ...

  6. 深入JVM之类的加载过程

    类的加载—连接—初始化 加载:查找并加载类的字节码文件,从硬盘到内存. 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.la ...

  7. C++ 获取字符串中的所有汉字

    #include<iostream> using namespace std; int main() {    char str[20] = "cd大家好df";   ...

  8. SpringMCVC拦截器不拦截静态资源

    SpringMCVC拦截器不拦截静态资源 SpringMVC提供<mvc:resources>来设置静态资源,但是增加该设置如果采用通配符的方式增加拦截器的话仍然会被拦截器拦截,可采用如下 ...

  9. centos 7 安装pip

    1.首先检查centos 有没有安装python-pip 包, >>yum install python-pipnotice:NO package python-pip available ...

  10. Python开发——函数【作用域】

    变量的查找是由内向外的 # 全局变量 name = 'yuan' # 定义函数 def change1(): print(name) # yuan # 调用函数 change1() print(nam ...