bind、call、apply 区别
call、apply 和 bind 都是 JavaScript 中用来改变函数执行上下文(this 值)的函数,它们之间的主要区别如下:
- call 和 apply 的第一个参数是要设置为新执行上下文的对象,第二个参数及以后的参数是要传递给函数的参数列表。而 bind 的第一个参数是要设置为新执行上下文的对象,后面的参数是原函数的参数列表。bind 返回一个新的函数,这个新函数会在调用时再将后面的参数传递给原函数。
- call 和 apply 都会立即执行函数,并且它们的返回值是函数的执行结果。而 bind 不会立即执行函数,而是返回一个新的函数,需要手动调用这个新函数才会执行原函数。
- call 和 apply 可以接受不定数量的参数,将这些参数打包成一个数组传递给原函数。而 bind 只接受原函数的参数列表,不会将其打包成数组。
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 实现柯⾥化
柯里化(Currying)是计算机科学中的一种技术,其功能是将接受多个参数的函数变换成能接收单一参数(即原函数的第一个参数)的函数,并返回一个新的函数,这个新函数能接受余下的参数并返回结果。
例:
假设我们有一个函数,它接受两个参数并返回它们的和:
function add(a, b) {
return a + b;
}
我们可以使用柯里化将这个函数转换为只接受一个参数的函数,并返回一个新的函数,该新函数接受第二个参数并返回结果:
function curryAdd(a) {
return function(b) {
return a + b;
}
}
现在,我们可以像这样使用柯里化的函数:
const add5 = curryAdd(5); // 返回一个新函数,该函数接受一个参数并返回 5 + 参数值
console.log(add5(3)); // 输出 8
bind函数
Function 实例的 bind() 方法创建一个新函数,当调用该新函数时,它会调用原始函数并将其 this 关键字设置为给定的值,同时,还可以传入一系列指定的参数,这些参数会插入到调用新函数时传入的参数的前面
/**
* 手写bind方法
* 1. 定义myBind方法
* 2. 返回绑定this的新函数
* 3. 合并绑定和新传入的参数
* */
// 1. 定义myBind方法
Function.prototype.myBind = function (thisArg,...args){
return (...reArgs)=>{
// 2. 返回绑定this的新函数
return this.call(thisArg,...args,...reArgs)
}
}
// ------------- 测试代码 -------------
const person = {
name: "itheima",
};
function func(numA, numB, numC, numD) {
console.log(this);//Object
console.log(numA, numB, numC, numD);//1,2,3,4
return numA + numB + numC + numD;
}
const bindFunc = func.myBind(person, 1, 2);
const res = bindFunc(3, 4);
console.log("返回值:", res);//返回值: 10
call函数
call() 函数在 JavaScript 中的作用是改变函数执行时的上下文(this 值),并立即执行该函数。它接受两个参数:第一个参数是要设置为新执行上下文的对象,第二个参数及以后的参数是要传递给函数的参数列表。
/**
* 手写call方法
* 1. 定义myCall方法
* 2. 设置this并调用原函数
* 3. 接收剩余参数并返回结果
* 4. 使用Symbol调优
* */
// 1. 定义myCall方法
// 3. 接收剩余参数并返回结果
Function.prototype.myCall = function (thisArg, ...args) {
// 2. 设置this并调用原函数
// 给thisArg加一个一定和原属性不重名的新属性(方法)
// 4. 使用Symbol调优
const key = Symbol('key')
// thisArg.key
thisArg[key] = this
const res = thisArg[key](...args)
delete thisArg[key]
return res
}
// ------------- 测试代码 -------------
const food = {
name: '西兰花炒蛋'
}
function func2(numA, numB, numC) {
console.log(this)//object
console.log(numA, numB, numC)//2,4,6
return numA + numB + numC
}
const res2 = func2.myCall(food, 2, 4, 6)
console.log('res2:', res2)//res2:12
// ------------- 测试Symbol -------------
// 调用Symbol内置函数,可以传入字符串作为标记
// 返回一个唯一的值
// const s1 = Symbol()
// const s2 = Symbol()
// console.log(s1 === s2)
// const s3 = Symbol('itheima')
// const s4 = Symbol('itheima')
// console.log(s3 === s4)
apply函数
apply() 函数在 JavaScript 中的作用是改变函数执行时的上下文(this 值),并立即执行该函数。它接受两个参数:第一个参数是要设置为新执行上下文的对象,第二个参数是一个数组或类数组对象,其中的每个元素都将作为单独的参数传递给函数
//1-定义一个apply函数
//2-设置this调用原函数
//3-接收剩余参数并返回结果
Function.prototype.myApply = function (thisArg,args) {
const key = Symbol('key')
thisArg[key] = this
const res = thisArg[key](...args)
delete thisArg[key]
return res
};
// ------------- 测试代码 -------------
const food = {
name: "西兰花炒蛋",
};
function func2(numA, numB) {
console.log(this);//object
console.log(numA, numB);//4,6
return numA + numB;
}
const res2 = func2.myApply(food, [4, 6]);
console.log("res2:", res2);//res2:10