bind、call、apply
区别
call和apply
call和apply都是为了解决改变this的指向。作?都是相同的,只是传参的?式不同。
第?个参数是一个对象,除此之外, call可以接收?个参数列表,apply只接受?个数组参数
let a = {
value: 1
}
function getValue(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])
bind
bind 和其他两个?法作?也是?致的,只是该?法会返回?个函数。并且我们可以通过 bind 实现柯?化
实现
思路:如果不传?第?个参数,那么默认为window
三个方法改变了 this 指向,让新的对象可以执?该函数。那么思路是否可以变成给新的对象添加?个函数,然后在执?完以后删除?
.bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
实现?个自己的bind函数
Function.prototype.myBind = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
var _this = this
var args = [...arguments].slice(1)
// 返回?个函数
return function F() {
// 因为返回了?个函数,我们可以 new F(),所以需要判断
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
.call()
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'foot';
}
console.log(new Food('cheese', 5).name);
实现?个自己的call函数
Function.prototype.myCall = function(context) {
var context = context || window
// 给 context 添加?个属性
// getValue.call(a, 'yck', '24') => a.fn = getValue
context.fn = this
// 将 context 后?的参数取出来
var args = [...arguments].slice(1)
// getValue.call(a, 'yck', '24') => a.fn('yck', '24')
var result = context.fn(...args)
// 删除 fn
delete context.fn
return result
}
.apply()
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
const numbers = [5, 6, 2, 3, 7]; const max = Math.max.apply(null, numbers); console.log(max); // expected output: 7 const min = Math.min.apply(null, numbers); console.log(min); // expected output: 2
实现一个自己的apply函数
Function.prototype.myApply = function(context) {
var context = context || window
context.fn = this
var result
// 需要判断是否存储第?个参数
// 如果存在,就将第?个参数展开
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}