我们都知道,在javaScript中定义的函数最外层中如果有this对象,则this就指向函数调用者,例如:
const student = { name: '赵六', address: '杭州', greeting: function() { console.log(`我叫 ${this.name},来自 ${this.address}`); }, }; student.greeting();
我叫 赵六,来自 杭州
这里的greeting方法中有this对象,调用者为student对象,则打印的内容就是student中的数据。
问题:当在定义一个student1对象时,实现和student.greeting()同样功能,打印数据,是否还需要重新定义一个方法,如:
const student1 = { name: '张三', address: '北京', greeting: function() { console.log(`我叫 ${this.name},来自 ${this.address}`); }, };
其实没有必要,这里就可以使用 call() apply() 或 bind()方法,通过改变this的指向来复用student的greeting方法,使用如下:
const student1 = { name: '张三', address: '北京', }; student.greeting.call(student1); student.greeting.apply(student1); student.greeting.bind(student1)();
我叫 张三,来自 北京
我叫 张三,来自 北京
我叫 张三,来自 北京
这里就可以看到,call() apply() 和 bind()方法的共同点就是改变this的指向,只不过bind()方法的使用和call、apply不太一样
上面讲述了call() apply() 和 bind()的共同点,下面看下这个三个方法的不同点,重点在参数传递上,如下:
修改student方法:
const student = { name: '赵六', address: '杭州', greeting: function(age, grade) { console.log(`我叫 ${this.name},来自 ${this.address}, 今年 ${age} 岁, 读${grade}年级`); }, };
调用方法:
student.greeting.call(student1, 12, 5); student.greeting.apply(student1, [9, 3]); student.greeting.bind(student1, 10, 4)(); student.greeting.bind(student1, [10, 4])();
我叫 张三,来自 北京, 今年 12 岁, 读5年级
我叫 张三,来自 北京, 今年 9 岁, 读3年级
我叫 张三,来自 北京, 今年 10 岁, 读4年级
我叫 张三,来自 北京, 今年 10,4 岁, 读undefined年级
从上面结果可以看到
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数不尽相同:
call的参数是从第二个参数依次传入;
apply的所有参数都必须放在一个数组中传入;
bind除了返回是函数以外,它 的参数和call 一摸一样。