Tian Jiale's Blog

JavaScript 中 call()、apply()、bind() 的用法差异

对象中 this 指向问题

var name = '小王',
  age = 17;
var persion = {
  name: '小王',
  myAge: this.age,
  introduce() {
    console.log('我叫' + this.name + ',我今年' + this.age);
  },
};
person.myAge;
// 17
persion.introduce();
// 我叫小王,我今年undefined

在该样例中,persion 的属性 myAge 设置的时候为 this.age,即将 window.age 赋值给 objAge,此时 this 指向 window。introduce 执行时,this 指向 persion 对象,所以 this.age 为 undefined。

一般函数中 this 的指向

var name = '小钱';
function sayName() {
  console.log(this.name);
}

此时函数中的 this 指向的是全局对象 this。

call()、apply()、bind()的简单应用

var name = '小王',
  age = 17;
var persion = {
  name: '小王',
  myAge: this.age,
  introduce() {
    console.log('我叫' + this.name + ',我今年' + this.age);
  },
};
var persion2 = {
  name: '小钱',
  age: 18,
};
persion.introduce.call(persion2);
// 我叫小钱,我今年18
persion.introduce.apply(persion2);
// 我叫小钱,我今年18
persion.introduce.bind(persion2)();
// 我叫小钱,我今年18

由此例可以看出,call()、apply()、bind()都可以改变 this 的指向为指定对象。其中如果没有传入参数,那么将 Global 对象作为参数传入。

另外可见 bind 返回的是一个新的函数,但该函数执行之后三个方法此时并无差异。

call()、apply()、bind()传参

var name = '小王',
  age = 17;
var persion = {
  name: '小王',
  myAge: this.age,
  introduce(toPersion = '同学', from = '河北') {
    console.log(toPersion + '你好,我叫' + this.name + '来自' + from + ',我今年' + this.age);
  },
};
var persion2 = {
  name: '小钱',
  age: 18,
};
persion.introduce.call(persion2, '小齐', '北京');
// 小齐你好,我叫小钱来自北京,我今年18
persion.introduce.apply(persion2, ['小齐', '北京']);
// 小齐你好,我叫小钱来自北京,我今年18
persion.introduce.bind(persion2, '小齐', '北京')();
// 小齐你好,我叫小钱来自北京,我今年18

从此例可以看出 call()、bind()、 apply()这三个函数的第一个参数都是 this 的指向对象,但传参时 call()和 bind()都是向后依次添加参数,而 apply 是传入数组。