概述

今天在看书的时候看到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. codeforces 1041A Heist

    electronic a.电子的 heist v.抢劫 in ascending order 升序 indice n.标记 device n.装置设备 staff n.职员 in arbitrary ...

  2. Microsoft DQS sqlException 0x80131904 - SetDataQualitySessionPhaseTwo

    遇到这个问题的原因可以从报错信息看出来,大概率是.net framework的问题 可以尝试如下解决途径 1. regenerate .net Assemble for DQS 2. 如果步骤一无法解 ...

  3. LAMP架构

    LAMP(linux,apache,mysql,php)是linux系统下常用的网站架构模型,用来运行PHP网站.(这得apache是httpd服务),这些服务可以安装同意主机上,也可以安装不同主机上 ...

  4. CSS 表单

    输入框前有图片 老板让你实现在输入框前有图片的功能.老板觉得用图片代替文字更有说服力. 要实现这样的功能很简单,它的原理是将图片放在内边距内. 代码 1 2 3 4 5 6 7 8 9 10 11 1 ...

  5. centos7-内核版本降级

    1. 查看内核版本参考命令: [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) [roo ...

  6. day37 异步回调和协程

    异步回调 """ 异步任务使用场景 爬虫 1.从目标站点下载网页数据 本质就是HTML格式字符串 2.用re从字符串中提取出你需要的数据 ""&quo ...

  7. 20165315 2017-2018-2《Java程序设计》课程总结

    20165315 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:我期望的师生关系 预备作业2:C语言基础调查和java学习展望 预备作业3:Linux安 ...

  8. MySQL 树节点递归遍历所以子节点

    DELIMITER $$ DROP FUNCTION IF EXISTS `getChildList`$$ CREATE FUNCTION `getChildList`(rootId INT) RET ...

  9. Mysql数据库 (JTree应用)

    package com.databases.jtree; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt ...

  10. golang环境 centos 7

    https://blog.csdn.net/ggq89/article/details/82682171  Linux下Go的安装.配置 .升级和卸载 https://blog.csdn.net/we ...