关于bind,call,apply的区别


bind,call,apply的区别

要想理解bind,call,apply的区别,我们先来理清楚this的概念

ES5中的this永远指向最后调用他的那个对象

Examp1:

1
2
3
4
5
6
const name = "out pear"
function sayName() {
var name = "inner pear"
console.log(this.name) // out pear
}
sayName()

sayName函数中打印出out pear的结果,是因为调用sayName的对象是window对象,所以其实是window.sayName(),那么最后一个调用sayName的对象就是window,在window下的name就是out pear

Examp2:

1
2
3
4
5
6
7
8
const name = "out pear"
let aaa = {
name: "inner pear",
sayName() {
console.log(this.name) // inner pear
}
}
aaa.sayName()

结果是inner pear,原因就是最后是aaa调用的sa yName函数

Examp3:

1
2
3
4
5
6
7
let name = "out pear"
let aaa = {
sayName() {
console.log(this.name) // undefined
}
}
aaa.sayName()

结果是undefined,因为this指向的是aaa这个对象,aaa对象中并没有声明name属性,而且因为指向了aaa对象,所以他不会向上的对象中去找name属性

Examp4:

1
2
3
4
5
6
7
8
9
var name = "out pear";
var aaa = {
name: 'inner pear',
sayName() {
console.log(this.name) // out pear
}
}
var f = aaa.sayName;
f()

结果是out pear,首先我们把aaa对象中的sayName函数赋值给了外部变量f,f是在window上执行sayName函数,所以实际上是window.f(),所以结果是out pear

关于this基本概念,差不多是这样

改变this指向

根据参考文章中,大致有以下几种方式可以改变this指向

  • Es6中的箭头函数

  • 保存this,赋值this,let _that = this

  • call,bind,apply

  • new 实例化一个对象

箭头函数

箭头函数的this始终指向函数定义时的this,也可以理解为,离他最近的那个对象的this上下文

bind,call,apply基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const a = {
name: 'a_name',
sayName() {
console.log(this.name)
}
}

const b = {
name: 'b_name'
}

a.sayName() // a_name
a.sayName.apply(b) // b_name
a.sayName.call(b) // b_name
a.sayName.bind(b)() // b_name

bind,call,apply都可以用于改变this的指向

这里他们分别将this指向到b,但是bind返回的是一个新的函数,你必须调用他,才会执行,而apply和call都会立即执行。

bind, call,apply在传参的情况下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const a = {
name: 'a_name',
sayName(param1,param2) {
console.log(this.name,param1,param2)
}
}

const b = {
name: 'b_name'
}

a.sayName(1,2) // a_name 1 2

a.sayName.apply(b,['apply_param1','apply_param2','apply_param3'])
// b_name apply_param1 apply_param2

a.sayName.call(b,['call_param1','call_param2','call_param3'],2)
// b_name ["apply_param1", "apply_param2", "apply_param3"] 2

a.sayName.bind(b,1,2,3)() // b_name 1 2

apply: 参数必须以数组的形式传入,数组中的每个下标对应一个参数

call: 参数可以以任何形式传入,用,分隔

bind: 除了返回是函数以外,它 的参数和 call 一样

参考文章:

我的微信公众号: 梨的前端小屋


文章作者: 梨啊梨
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 梨啊梨 !
  目录