Array.prototype.slice.call引发的思考
概述
今天在看书的时候看到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引发的思考的更多相关文章
- js基础进阶--关于Array.prototype.slice.call(arguments) 的思考
欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...
- 由[].slice.call()引发的思考
由[].slice.call()引发的思考 经常看到大家用[].slice.call()或者Array.prototype.slice.call(): 我一直是一知半解的,今天算是基本弄清楚了, ...
- 【javascript 技巧】Array.prototype.slice的妙用
Array.prototype.slice的妙用 开门见山,关于Array 的slice的用法可以参考这里 http://www.w3school.com.cn/js/jsref_slice_arra ...
- Array.prototype.slice.call(arguments)
Array.prototype.slice.call(arguments)能够将具有length属性的对象转化为数组, 可以理解为将arguments转化成一个数组对象,让它具有slice方法 如: ...
- IE下Array.prototype.slice.call(params,0)
i8 不支持 Array.prototype.slice.call(params,0) params可以是 HTMLCollection.类数组.string字符串
- (转)Array.prototype.slice.call自解
很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一 ...
- 详解 Array.prototype.slice.call(arguments)
首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...
- Array.prototype.slice && Array.prototype.splice 用法阐述
目的 对于这两个数组操作接口,由于不理解, 往往被误用, 或者不知道如何使用.本文尝试给出容易理解的阐述. 数组 什么是数组? 数组是一个基本的数据结构, 是一个在内存中依照线性方式组织元素的方式, ...
- Array.prototype.slice.call(document.querySelectorAll('a'), 0)
Array.prototype.slice.call(document.querySelectorAll('a'), 0)的作用就是将一个DOM NodeList 转换成一个数组. slice()方法 ...
随机推荐
- Hadoop 学习之Docker
docker环境的配置请参考:http://www.cnblogs.com/frankliu/p/8052673.html hadoop-docker安装地址参考:https://hub.docker ...
- Linux下chkconfig命令介绍
一.引论 chkconfig命令检查.设置系统的各种服务.这是Red Hat公司遵循GPL规则所开发的程序,它可查询操作系统在每一个执行等级中会执行哪些系统服务, 其中包括各类常驻服务.谨记chkco ...
- 爬虫 1 requests 、beautifulsoup
1.requests 1.method 提交方式:post.get.put.delete.options.head.patch 2.url 访问地址 3.params 在url中传递的参数,GET p ...
- oracle中文乱码的解决方法
select userenv('language') from dual; NLS_LANG AMERICAN_AMERICA.AL32UTF8
- chrome.debugger
官网: https://chromedevtools.github.io/devtools-protocol/ https://developer.chrome.com/extensions/debu ...
- 166. Fraction to Recurring Decimal (Math)
Given two integers representing the numerator and denominator of a fraction, return the fraction in ...
- [leetcode]265. Paint House II粉刷房子(K色可选)
There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...
- canvas(三) star- demo
/** * Created by xianrongbin on 2017/3/8. * 本例子使用渐变画出 璀璨星空 */ var dom = document.getElementById('clo ...
- PHP请求ws出现的问题
在SOAPUI中的请求如下: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/&qu ...
- ES6 Iterator
不同数据集合怎么用统一的方式读取 可以用for...of循环了