Javascript之bind,call,apply方法的使用场景和区别
之前的文章里有写到上述三种方法的实现,这次就来对比下这三种方法。
| 入参 | 语法 | 出参 |
---|
call | n个参数,第一个参数为原函数的this指向,其余参数依次传入原函数中进行调用 | function.call(thisArg, arg1, arg2, …) | 函数执行结果 | apply | 最多两个参数,第一个参数为原来函数的this指向,第二个参数是类数组或数组对象,解构后传入原函数进行调用 | func.apply(thisArg, [argsArray]) | 函数执行结果 | bind | n个参数,bind中的第一个参数为原来函数的this指向,其余参数依次传入原函数中进行调用 | function.bind(thisArg[, arg1[, arg2[, …]]]) | 一个新函数 |
这三者进行对比一般说的都是call和apply进行对比,bind和call进行对比。具体仔细看看上表写的东西哈。
相同点就是三者都修改了原函数的this指向,为什么这么做呢?按照我的理解来回答就是,共享方法节省内存
大家想一想,假如没有这种修改this指向的办法,而我们又想要打印一些变量的某些属性,是不是就得这么写了:
const teacher = {
name:'三上you亚',
age:'18'
}
function demo(){
console.log(teacher.name)
}
或者这么搞
const teacher = {
name:'三上you亚',
age:'18',
consoleName(){
console.log(this.name)
}
}
teacher.consoleName()
很麻烦的好不好,而且每个变量我都这么搞是不是占用很多内存
优化一下啦,就成了,那干脆就这么写:
function test(params){
console.log(params.name)
}
const teacher = {
name:'三上you亚',
age:'18'
}
test(teacher)
ok,这样确实简化了一些,但是我TM每次写一个项目还得创建test这个方法,项目多了这也很烦躁啊。干脆就加到原型上完事了,当然,而且加的话,肯定是加到Function上面啊,总不能加到Object的原型上吧,你能想象会有Object.prototype.[‘打印一些XX属性’]这样的方法吗
喏,这样就好理解了吧。
接下来说一下常见的一个例子:类数组对象使用slice方法
[].slice.call(arguments)
我们都知道啊,类数组对象跟数组不是一回事,只有length属性并且参数的key是从0开始,这两点跟Array一样,其他的方法并不具备,slice方法当然也就没有了。
但在函数中我们拿到arguments后常常需要做一些处理,这时候将他转换成一个数组会更方便一些。
而slice方法的实现则是按照key进行取值的,这个可以用到arguments上,如果我们slice时不填参数则会把arguments里面的value输出到一个数组中去,这样也就实现一个类数组对象转成一个数组对象的目的啦,是不是很奇妙呢
|