深入理解JS原型及其扩展

来源:互联网 发布:非结构化数据的处理 编辑:程序博客网 时间:2024/05/18 12:43

相信各位一定看到过Array.prototype.slice.call(arguments,1);这样的写法。(我是清楚的记得在看函数柯里化的时候遇到的,这儿我们不讨论它)

先查slice的定义:


上面的写法和我们看到MDN的例子看起来有很大的差别,其实殊途同归。

首先,简单向大家提及一下call,apply,bind的区别:

apply:(...).apply(context,[...args]);  //绑定this之后,立即执行改变上下文之后的函数,获取结果。参数以数组形式传递

call:(...).call(context,arg1,arg2...) 绑定this之后,立即执行改变上下文呢之后的函数,获取结果。参数按函数定义的顺序排列。

bind: (...).bind(context),返回一个绑定了this之后的函数,也就说 需要手动调用。
其次,假如我们自己想在某个对象的原型对象上扩展一个方法,这儿我们以Array举例:

Array.prototype.isAllNumber=function(){  return this.every(x=>typeof x==“number”);  }

//判断一个数组里面是否全部是数字。

根据刚才call的知识点可知道:

var array=new Array(1,2,3,4,5);

array.isAllNumber() //返回true,因为原型上已经定义了这样的方法。

接下来就是,既然isAllNumber是一个函数,函数就可以调用,关键在于怎样调用。

如果直接Array.prototype.isAllNumber() 肯定是会错误的,因为在这里面this是什么呢,我们不得而知。

但是 根据call的使用场景,我们可以手动为其指定this指向。

那么 稍作修改Array.prototype.isAllNumber.call([1,2,3,4,5,6]),因为这个函数没有参数,所以只需要指定this即可。

这样跟使用new 申明数组,再调用数组的方法本质即相同了。那么我们明白了Array.prototype.slice.call(arguments,1);

其实它的意思就是[...arguments].slice(1);//  "...“是ES6的扩展运算符,arguments并不是一个真正的数组,使用这样的操作,它就变成了一个真正的数组。

于是知道这样的使用方法之后,我们便可以将一些实用的原型方法当静态方法实用了,ES5还为我们定义了以下7个方法:分别是 every,some,map,forEach,filter,reduce,reduceRight方法,具体的函数参数及用法大家可以参考MDN。

原创粉丝点击