JavaScript中,函数call,apply,bind方法的使用总结

前言

当你看到这篇文章,那你多少是因为遇到了对call,apply,bind有疑问的地方,也许你只是对这些方法一知半解的用,并没有真正搞懂他使用的原理,本篇文章尽量以通俗的方式理清楚逻辑

原理简介

首先我们要搞清楚,为什么所有的函数都可以像类似对象的点后缀的形式去引用一些公共的方法,诸如这些

let test = function(){console.log(123)}
test.toString() // "function(){console.log(123)}" 打印字符串
test.name // 'test' 返回函数命名
......

本质上,函数也是对象,每个函数都是一个function类型的实例,而且都与其他引用类型一样具有属性和方法

this对象

在函数内部,提供了一个特殊的对象:this,它是决定你能否正确理解函数call,apply,bind的关键点。this,可以理解成是一个指针,它指向函数执行的时候的环境对象(讲通俗点,就是它会指向你的函数是在哪里执行的),举个JavaScript高级程序设计里面的一个小例子

window.color = 'red'
var o = {color: 'blue'}
function sayColor(){ alert(this.color)}
sayColor(); // 'red'
o.sayColor = sayColor
o.sayColor() // 'blue'

上面的sayColor函数它是在全局作用域中定义的,它引用了this对象,但是此时this的指向不能确定,因为在函数调用之前,this并没有指向函数调用的作用域,this的指向只有在最终调用的时候才能确定,直至在全局作用域中调用时,this引用的是全局Windows对象,讲通俗点,此时的this.color = window.color,于是返回red,。如果把这个函数赋值给对象o并且调用他,那么此时this.color =o.color,于是返回blue

call,apply,bind的使用

call,apply方法

每个函数都包含了两个方法:call,apply,这两个方法都是基于this指向来完成的。apply方法接受两个参数,一个是在其中运行的函数作用域,另外一个是参数数组,你甚至可以直接传一个Array实例也是没有问题的。上代码

function sum(num1,num2){
    return num1+ num2
}
var obj = {
    num1:10,
    num2:20
}

假如我有个需求,现在我需要计算obj里面的num1,和num2相加的值,当然你第一反应可能是直接在函数里面定义一个方法嘛,然后把数值传进去,也行。但是呢,作为一个程序员,我懒嘿嘿。如果我可以借用别人已有的方法白嫖一波,那岂不是在这里插入图片描述
这个时候就是apply帮你搞定了

sum.apply(obj,[obj.num1,obj.num2]) // 30

call方法也是一样的用法,只是参数格式不同而已,第一个参数还是this值作用域,第二个是其余的参数是直接传递,换句话讲,使用call方法时候,必须把传递给函数的参数逐个列出来。具体用哪个,就看你实际场景哪个合适用哪个咯

sum.call(obj,obj.num1,obj.num2)

说来说去,其实就是做了同一件事,call和apply相当于扩充了函数调用的作用域。这样的话,对象不再需要与方法有任何紧密的耦合关系了,讲通俗点,谁有好的方法,你可以拿来借用一下。比如数组的合并,我第一篇文章有讲过,感兴趣的也可以看看JavaScript数组的合并

bind 方法

ES5还定义了一个方法:bind,这个方法原理和call,apply是一样的,不同点是这个方法是返回一个函数的实例给你,你需要自己调用它,它只接受一个参数,传一个函数的作用域即可。this值是绑定在传给bind函数的值上的,比如

window.color = 'red'
var obj = {color: 'blue'}
function getColor(){
console.log(this.color)
}
var myfun = getColor.bind(obj)
myfun() // blue

总结

学习是一个需要输出的过程,我刚接触的时候也是用的一知半解,不敢说很熟练,经过思考的输出后,工作中就会很有意识的利用到它们

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐