共同点
call(),apply(),bind()三个函数都是 Function 实例对象的属性, 也就是说存在于 Function.prototype 中.
作用都是设置函数体内对象的值, 即改变函数运行时的上下文.
第一个参数都是运行函数的作用域, 即要指定的上下文.
区别
Function.prototype.call()
先来理解一下 call()的作用:
- var name = "banana";
- var fruits = {
- name: "apple"
- };
- function say() {
- console.log("I'm " + this.name);
- }
- say(); //I'm banana
此时调用 say()的上下文 (this) 是 Windows 对象, 所以输出的 name 为 "banana". 如果我想输出 name 为 "apple" 那该怎么办? call()可以解决这个问题:
say.call(fruits); //I'm apple
可以看出 call()能改变函数运行时的 this 指向.
apply(),bind()亦如此.
语法
Function.call(thisObj,[arg1[arg2[argN]]]);
参数
call()有两个参数, 一个 (thisObj) 是函数运行的作用域, 另一个 (arg) 是传给函数的参数, 传入的参数必须逐个列举出来.
例子
- function sum(num1, num2) {
- return num1 + num2;
- }
- function callSum(num1, num2) {
- return sum.call(this, num1, num2);
- }
- console.log(callSum(10, 10)); //20
- Function.prototype.apply()
apply()的作用与 call()完全相同.
语法
Function.apply(thisObj, [argArray]);
参数
apply()也有两个参数, 一个 (thisObj) 是函数运行的作用域, 另一个 (arg) 是传给函数的参数, 与'call()'不同的是传入的参数可以是 arguments 对象, 也可以是数组.
如果 argArray 不是一个有效的数组或者不是 arguments 对象, 那么将导致一个 TypeError.
例子
- function sum(num1, num2) {
- return num1 + num2;
- }
- function callSum1(num1, num2) {
- return sum.apply(this, arguments);
- }
- function callSum2(num1, num2) {
- return sum.apply(this, [num1, num2]);
- }
- console.log(callSum1(10, 10)); //20
- console.log(callSum2(10, 10)); //20
可以看出, call()和 apply()作用一样, 唯一的区别只是传入参数的形式不同. 接下来看一下 bind()函数.
Function.prototype.bind()
语法
Function.bind(thisObj, [arg1[arg2[argN]]])
参数
bind()传参数方式与 call()相同. 但它有一个返回值, MDN 上这样介绍:"返回由指定的 this 值和初始化参数改造的原函数拷贝."
例子
有时我们需要用到函数外的作用域, 这是我们一般会用_this, $this 等来存储外部函数对象, 如下:
- var foo = {
- num : 1,
- eventBind: function() {
- var $this = this;
- $('.class').on('click',function(event) {
- console.log($this.num); //1
- });
- }
- }
这样的做法没有问题, 不过我们可以使用 bind()更优雅的解决.
- var foo = {
- num : 1,
- eventBind: function() {
- $('.class').on('click',function(event) {
- console.log(this.num); //1
- }.bind(this));
- }
- }
call(),apply()和 bind()的主要区别是: call(),apply()改变上下文之后立即执行, 而 bind()只是返回一个函数, 不执行.
参考:
来源: http://www.jianshu.com/p/f67f4c68bcae