JS Function: apply vs call vs bind

hiveer

Function 构造函数中有三个方法可以改变函数实例中的this,今天面试的时候被问到了,懵逼了!今天专门研究了下,发现了一篇不错的文章,半翻译,半理解写在这里。

原文

https://medium.com/@leonardob...

Function.prototype.call()

call允许你调用一个函数,并且在首个参数传入this。然后函数的参数一个一个以逗号分隔,依次传入。
例子:

function greeting(text1, text2) {
  console.log(`${text1} ${this.name}, ${text2}`);
}

let customer1 = { name: 'Leo', email: 'leo@gmail.com' };
let customer2 = { name: 'Nat', email: 'nat@hotmail.com' };

greeting.call(customer1, 'Hello', 'good morning!'); 
// > Hello Leo, good morning!
greeting.call(customer2, 'Hello', 'good afternoon!'); 
// > Hello Nat, good afternoon!

Function.prototype.apply()

这个方法跟call的功能很类似,但是实现方式不太一样。依然是第一个参数传入this,但是被调用的函数的参数会以数组的形式作为apply方法的第二个参数传入。
例子:

function greeting(text1, text2) {
  console.log(`${text1} ${this.name}, ${text2}`);
}

let customer1 = { name: 'Leo', email: 'leo@gmail.com' };
let customer2 = { name: 'Nat', email: 'nat@hotmail.com' };

greeting.apply(customer1, ['Hello', 'How are you?']); 
// > Hello Leo, How are you?
greeting.apply(customer2, ['Hello', 'How are you?']);
// > Hello Natm How are you?

Function.prototype.bind()

这个方法跟callapply很不一样,它不是去调用一个函数,而是根据已有的函数创造了一个新的函数,这个新的函数的this可以在bind参数传入。也就是说新造函数无论什么时候执行,它的this都是固定的。

函数定义:

Function.prototype.bind = function(context) {
  var fn = this;
  return function() {
    fn.apply(context, arguments);
  };
};

这段代码是bind函数的定义,从var fn = this可以知道,fn指向了调用bind函数的函数对象。然后在bind的返回函数fn.apply(context, arguments)可以看出,哪个函数调用了bind,那么bind就把这个函数的this改变为context

例子:

function greeting(text) {
  console.log(`${text} ${this.name}`);
}

let customer1 = { name: 'Leo', email: 'leo@gmail.com' };
let customer2 = { name: 'Nat', email: 'nat@hotmail.com' };

let helloLeo = greeting.bind(customer1);
let helloNat = greeting.bind(customer2);

helloLeo('Hello'); 
// Hello Leo
helloNat('Hello'); 
// Hello Nat

希望能帮助到你!

阅读 423

目前靠RoR养活,希望被JS包养

0 声望
0 粉丝
0 条评论
你知道吗?

目前靠RoR养活,希望被JS包养

0 声望
0 粉丝
宣传栏