call-apply-与-bind-实例详解

52次阅读

共计 2239 个字符,预计需要花费 6 分钟才能阅读完成。

call() , apply() 与 bind() 详解

我们知道可以用 call(), apply()bind() 这三个函数都是用来完成函数调用,并且设置 this 指向。call()apply() 是 ECMAScript3 标准引入,而 bind() 函数则是在 ECMAScript 5 引入。这边文章会用几个小例子来回忆一下他们之间有什么不一样。

用法

call()apply() 会立即调用函数,而bind() 只会返回一个函数引用,当后面真正调用返回的函数的时候,函数里面的 this 将会指向给 bind() 函数传入的参数,并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项,所以 bind()函数非常适合在事件回调的时候修改this 指向,有React 经验的朋友应该会有更深的感受。

call()

var dist = 'Beijing';

function greet(name, hometown) {var word =  `Welcome ${name} from ${hometown} to ${this.dist}!`
  console.log(word);
}

var obj1 = {dist: 'Chengdu'};

greet.call(obj1, "Tom", "Dallas");  // Welcome Tom from Dallas to Chengdu!

greet("Jerry", "Houston"); // Welcome Jerry from Houston to Beijing!

因为 greet.call(obj) 传入了obj1 作为第一个参数,所以在 greet()函数执行时, this指向 obj1。其余的参数就将作为参数传给 greet() 函数。
当没有使用 call() 而直接调用 greet() 时, this指向 window对象.

apply()

var dist = 'Beijing';

function greet(name, hometown) {var word =  `Welcome ${name} from ${hometown} to ${this.dist}!`
  console.log(word);
}

var obj1 = {dist: 'Chengdu'};

var args = ["Tom", "Dallas"];
greet.apply(obj1, args);  // Welcome Tom from Dallas to Chengdu!

greet("Jerry", "Houston"); // Welcome Jerry from Houston to Beijing!

apply()函数和 call() 函数非常的相似,第一个参数都用来设置目标函数运行时的 this 指向。唯一的区别就是 apply()的第二个参数接受一个数组,其他表现则一样。

bind()

var dist = 'Beijing';

function greet(name, hometown) {var word = `Welcome ${name} from ${hometown} to ${this.dist}!`;
    console.log(word);
}

var obj1 = {dist: 'Chengdu',};

var obj2 = {dist: 'Chongqing',};

var greet1 = greet.bind(obj1, 'Tom', 'Dallas');
var greet2 = greet.bind(obj2, 'Spike', 'San Antonio');

greet('Jerry', 'Houston');

greet1();
setTimeout(function() {greet2();
}, 1000);

这个例子会更加复杂一点,输出结果如下:


  Welcome Jerry from Houston to Beijing!
  Welcome Tom,Dallas from undefined to Chengdu!
  Welcome Spike,San Antonio from undefined to Chongqing!

在上面例子中,bind()函数并不会立即执行目标函数,而是返回了一个函数的拷贝,但 this 会指向 bind() 的第一个参数,其余传给 bind() 的参数都会按顺序传给返回的函数。我们就可以异步调用这个函数返回值了。但是需要注意的是,bind()方法返回的函数拷贝在使用 new 操作时,第一个参数是会被忽略的。

那么新的问题又来了,如果在调用返回的函数拷贝的时候,又传入了新的参数,会发生什么呢,只有再写一个例子试试了。

var obj1 = {dist: 'Chengdu',};

function greet(name, hometown) {console.log(Array.prototype.slice.call(arguments));
    var word = `Welcome ${name} from ${hometown} to ${this.dist}!`;
    console.log(word);
}

var greet1 = greet.bind(obj1, 'Tom', 'Dallas');

greet1('Jerry', 'Houston');

输出的结果为:


["Tom", "Dallas", "Jerry", "Houston"]
Welcome Tom from Dallas to Chengdu!

结果证明两个地方传入的参数都会被传给目标函数,函数拷贝调用时传入的参数会追加在 bind() 函数调用时传入的参数后面。

以上就是所有关于 call(), apply()bind() 三个函数的实例了。大家有什么疑问建议留言讨论。

本文始发于 bbwho.com 站点

正文完
 0