在写js时我们会经常使用apply、call、bind快速完成一些重复性大的计算和操作。
apply函数可以传递两个参数,第一参数是改变原有函数的this指针,使其指向第一个参数,第二个参数用来传递一个数组,数组的内容是要传递的变量,可以把理解apply函数为一些语言的继承,但与继承不同,废话少说上代码:
let mydata = {
user_name: '张三',
user_age: 18
}
function UserLoad() {
this.user_name = '';
this.user_age = 0;
this.user_ico = '1.jpg';
}
UserLoad.apply(mydata);
console.log(mydata.user_ico);
console.log(mydata);
返回结果为:

此时我们可以看到mydata虽然顺利的继承到了UserLoad函数的user_ico属性,但同时我们发现原有的user_name和user_age被UserLoad的默认属性给覆盖掉,这就是与继承最大的区别.
解决方法:尽量避免接收apply指向的对象存在与函数相同的属性,若想传参可以使用apply的第二个参数进行传参
let mydata = {
user_name: '张三',
user_age: 18
}
function UserLoad(pwd, ico) {
this.user_ico = ico || '1.jpg';
this.user_pwd = pwd || '';
console.log(`用户名:${this.user_name} 密码:${this.user_pwd} 年龄:${this.user_age} 头像文件: ${this.user_ico}`);
}
UserLoad.apply(mydata, ['123456', 'ico.jpg']);
结果:

这样我们就可以实现使用apply继承部分属性并传参的操作
注意的是apply执行时会立即执行函数。
call与apply类似,只不过传参的方式由数组改为了多个变量:
let mydata = {
user_name: '张三',
user_age: 18
}
function UserLoad(pwd, ico) {
this.user_ico = ico || '1.jpg';
this.user_pwd = pwd || '';
console.log(`用户名:${this.user_name} 密码:${this.user_pwd} 年龄:${this.user_age} 头像文件: ${this.user_ico}`);
}
UserLoad.call(mydata, '123456', 'ico.jpg');
结果:

同样也是在使用call函数的时候函数体会立即执行。
bind与call和apply最大的区别在于使用bind函数进行拷贝时,函数不会执行,但会返回一个可执行的函数:
let mydata = {
user_name: '张三',
user_age: 18
}
function UserLoad(pwd, ico) {
this.user_ico = ico || '1.jpg';
this.user_pwd = pwd || '';
console.log(`用户名:${this.user_name} 密码:${this.user_pwd} 年龄:${this.user_age} 头像文件: ${this.user_ico}`);
}
let newfun = UserLoad.bind(mydata, '123456', 'ico.jpg'); //返回一个可执行函数
newfun();
newfun函数的执行结果:

总结:
通过apply和call我们可以实现对目标函数属性和方法的继承,且会立即执行函数。
通过bind可以实现对目标函数的拷贝,不会执行函数,并返回一个全新的函数对象。
JavaScript中apply、call与bind的使用与区别
本文详细介绍了JavaScript中apply、call和bind三个方法的使用,重点在于它们如何改变函数调用的上下文(this)以及参数传递方式。通过示例展示了apply用于对象属性继承和参数传递,但可能导致原有属性被覆盖的问题。call与apply类似,但参数传递方式改为逐个传递。bind则返回一个新的函数,保留了原函数的上下文,但不会立即执行。总结了三者在函数调用和上下文绑定上的差异及其应用场景。
634

被折叠的 条评论
为什么被折叠?



