这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战;
基本介绍
call、apply、bind是Function上的三个方法,他们都是在给定的作用域中调用函数。先来看一下他们的基本语法。如下:
function.call(thisArg, arg1, arg2, ...)
function.apply(thisArg, [param1,param2,...])
function.bind(thisArg, param1, param2, ...)
相同点和不同点
-
相同点
- 都可以改变函数function的
this指向
- 都可以改变函数function的
-
不同点
-
call和apply的区别是,他们的传参写法不同。
-
call的第2个参数是第2个至第N个都是给function的传参。
-
apply的第二个参数
只能是数组。
-
-
bind和他们的区别是,他在改变this指向时不是立即执行,call和apply是立刻执行的。
-
call
- call()使用示例:
let a = {
name: '芒果A',
getName: function(msg) {
return msg + this.name;
}
}
let b = {
name: '芒果B'
}
console.log(a.getName('hello~')); // hello~芒果A
// 这里我们是 让b对象直接使用a对象里的getName函数方法
console.log(a.getName.call(b, 'hi~')); // hi~芒果B
- 手动实现
Function.prototype.call = function (context, ...args) {
// 第一步:context这是可选的参数,不传默认window
var context = context || window;
// 第二步:给context创建一个fn属性,来指定上下文
context.fn = this;
// 第三步:通过执行 eval 来执行 context.fn 这个函数
var result = eval('context.fn(...args)');
delete context.fn
// 第四步:返回result
return result;
}
这段代码实现可以结合上边实例简单理解一下,加深印象。
apply
apply()使用示例:
const numbers = [15, 16, 12, 13, 17];
// 这里是通过apply来获取数组中的最大值。
const max = Math.max.apply(null, numbers);
console.log(max); // 最大值:17
// 这里是通过apply来获取数组中的最小值。
const min = Math.min.apply(null, numbers);
console.log(min); // 最大值:12
关于apply()手动实现,通过文章开头介绍的基本理解,我们知道apply的手动实现和call的手动实现是基本一致的,只不过是传参不同罢了。
所以小伙伴们可以仿照上边的call的手动实现,自己实现一个apply()方法。
bind
- bind()使用示例
this.name = '🥭'
let obj = {
name: '中文名-芒果',
getName: function() {
return this.name;
}
}
obj.getName() // 中文名-芒果
let obj1 = obj.getName;
obj1(); // 🥭
// 这里obj1 借用了 obj的getName函数方法
obj1.bind(obj)(); // 中文名-芒果
- 手动实现 关于bind手动实现,我们要明确一点
他是需要通过返回一个函数的方式将结果返回,之后再通过执行这个结果,得到想要的执行效果。
Function.prototype.bind = function (context, ...args) {
if (typeof this !== "function") {
throw new Error("this must be a function");
}
var self = this;
var fbound = function () {
self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
// 将 this.prototype 上面的属性挂到 fbound 的原型上面
if(this.prototype) {
fbound.prototype = Object.create(this.prototype);
}
return fbound;1
}
MDN关于bind讲解,感觉这里介绍的很详细,不明白的小伙伴可以来这里再学习一番。
总结
前端漫漫长途,我们都在路上,希望可以和小伙伴们一起交流,一起进步。持续更新ing.....