JS进阶 - apply , call, bind 用法和区别
程序员文章站
2022-07-14 14:27:40
...
JS中最常见的 apply
, call
, bind
用法和区别
三者区别
1. 调用的区别
apply
和 call
会立即调用
而 bind
不会立即调用,而是返回一个函数
2. 传递参数的区别
- 三个方法的第一个参数都是
要指向的对象
因为这3个方法都是用于修改this的指向。或者是绑定新的参数 - 而且
apply
。接收的第二个参数是一个数组,没有第三个参数了 -
call
和bind
从第二个参数开始 可以接收N个参数,并没有限制
实例演示
文字不太好理解。附上代码那就差不多了
apply 示例
- 无参,只修改this指向
var Jioho = {
id: 1,
name: 'Jioho',
say: function () {
console.log(`Hello I'm ${this.name}.`)
}
}
var Laiching = {
id: 2,
name: 'Laiching',
}
Jioho.say.apply(Laiching); // Hello I'm Laiching.
- 有参,也是修改this指向
var Jioho = {
id: 1,
name: 'Jioho',
home:'DongGuang'
say: function (sex, age) {
console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
console.log(this);
}
}
var Laiching = {
id: 2,
name: 'Laiching',
home:'DongGuang'
}
Jioho.say.apply(Laiching, ['girl', 3]); // Hello I'm Laiching.I'm a girl.I'm 3 years old.
注意传参地方,传的是一个数组
['girl',3]
.
注意看第12行。在Jioho对象中是没有定义home
这个属性的。而 Laiching 的对象中有这个属性。 用了apply或者其他后。home也会带上,可以注意观察 第 7 行的打印结果
call 示例
- 无参,只修改this指向
var Jioho = {
id: 1,
name: 'Jioho',
say: function () {
console.log(`Hello I'm ${this.name}.`);
console.log(this)
}
}
var Laiching = {
id: 2,
name: 'Laiching',
home:'DongGuang'
}
Jioho.say.call(Laiching); // Hello I'm Laiching.
- 有参,也是修改this指向
var Jioho = {
id: 1,
name: 'Jioho',
say: function (sex, age) {
console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
console.log(this)
}
}
var Laiching = {
id: 2,
name: 'Laiching',
home:'DongGuang'
}
Jioho.say.call(Laiching, 'girl', 3); // Hello I'm Laiching.I'm a girl.I'm 3 years old.
Jioho.say.call(Laiching, ...['girl', 3]); // Hello I'm Laiching.I'm a girl.I'm 3 years old.
call 和 apply 用法其实都类似,都把 home 属性给带上了。也改变了this指向。只是传的参数不一样
call 接收的是一长串的参数,当然也可以用 es6 的解构来实现参数传一长串属性。
bind 示例
- 无参,只修改this指向
var Jioho = {
id: 1,
name: 'Jioho',
say: function () {
console.log(`Hello I'm ${this.name}.`);
console.log(this)
}
}
var Laiching = {
id: 2,
name: 'Laiching',
home:'DongGuang'
}
Jioho.say.bind(Laiching);
// ƒ(sex, age) {
// console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
// console.log(this);
// }
- 有参,修改this指向。传入参数。返回新的函数
var Jioho = {
id: 1,
name: 'Jioho',
say: function (sex, age) {
console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
console.log(this);
}
}
var Laiching = {
id: 2,
name: 'Laiching',
age: 100
}
var Laiching_obj = Jioho.say.bind(Laiching);
console.log(Laiching_obj);
// ƒ(sex, age) {
// console.log(`Hello I'm ${this.name}.I'm a ${sex}.I'm ${age} years old.`)
// console.log(this);
// }
Laiching_obj('girl', 10); // Hello I'm Laiching.I'm a girl.I'm 10 years old.
bind 和 call 传递参数的方法是一致的,唯一不同的就是把函数直接返回回来,而并不执行
bind 是用于实现蹦床函数
的核心要点。
传送门 : 蹦床函数实现
总结
每个方法存在肯定有他的道理。优化传参步骤和修改this指向,用法实在太多,可以在实际使用中慢慢积累经验.
三个函数的基础作用都是修改 this 的指向
问题。或者为对象添加新的属性
更进阶的用法呢?
// 现在有一个 f 方法。接收3个参数
function f(param1,param2,param3){
// do somthing
}
// 而你的参数都在一个数组中
var params = [1,2,4];
// 这时候为了传参方便。就可以使用apply了
f.apply(null,params);
// 而 es6 新出的语法也可以代替 apply了。效果都是一样的
f(...params);
JS 博大精深。我就不一一举例了。了解了区别后,就全靠自己摸索了
上一篇: this指向的深入解析