- call
- 用途:调用一个函数,并且改变函数的
this指向。 - 参数:第一个参数是
this的值,其余参数是要传递给函数的参数列表。
// 语法: function.call(thisArg, arg1, arg2, ...)
// 使用场景:当你有一组参数,并且想立即调用函数时使用
function sayHello() {
console.log(`Hello, ${this.name}`);
}
const person = { name: 'Bob' };
sayHello.call(person); // "Hello, Bob"
- 手撕
Function.prototype.myCall = function (obj, ...args) {
var obj = obj || window // 这里只能用var
const p = Symbol('p')
obj.p = this
const res = obj.p(...args)
delete obj.p
return res
}
- apply
- 用途:调用一个函数,并且改变函数的
this指向。 - 参数:第一个参数是
this的值,第二个参数是一个包含要传递给函数的参数的数组或类数组对象。
// 语法: function.apply(thisArg, [argsArray])
// 使用场景:当你有一个数组或类数组对象,并且想立即调用函数时使用
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum.apply(null, numbers)); // 6
- 手撕
Function.prototype.myApply = function (obj, ...args) {
var obj = obj || window
const p = Symbol('p')
obj.p = this
const res = obj.p(...args[0]) // 立即执行,和apply的区别!!!!!!!
delete obj.p
return res
}
- bind
- 用途:创建一个新的函数,该函数在被调用时,其
this值是特定的值,并且预设一些参数。 - 参数:第一个参数是
this的值,后续参数是预设的参数列表。
// 语法: const boundFunction = function.bind(thisArg, arg1, arg2, ...)
// 使用场景:当你想创建一个新的函数,并且稍后调用它,且this和部分参数是预设时使用
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // 42
- 手撕
Function.prototype.myBind = function (context) {
// 保存this,即原函数
var fn = this;
if (typeof fn !== 'function') {
throw new TypeError('Error');
}
// 获取除了第一个参数context外的所有参数
var args = Array.prototype.slice.call(arguments, 1);
// 返回一个新的函数
function boundFunc() {
// 获取调用返回函数时的参数
var bindArgs = Array.prototype.slice.call(arguments);
// 合并参数并调用原函数
return fn.apply(this instanceof boundFunc ? this : context, args.concat(bindArgs));
}
// 设置原型链,支持继承
boundFunc.prototype = Object.create(fn.prototype);
return boundFunc;
};
- 区别总结:
-
-
call和apply:
-
都是立即调用函数,并且改变该函数的
this指向。 -
区别:
call逐个传递参数。apply使用一个数组(或类数组对象)传递参数。
-
-
-
bind:
- 不会立即调用函数,而是返回一个新的函数。
- 返回的新函数在调用时,其
this值是特定的值,并且可以拥有预设的参数。
-