目录
- 实现call、apply 及 bind 函数
- 1. 实现call函数
- 2. 实现apply函数
- 3. 实现bind函数
实现call、apply 及 bind 函数
call、apply和bind函数都是用于改变函数中this指向的方法。它们的作用都是使函数能够在不同的对象上下文中运行。call方法和apply方法的作用类似,都是立即执行一个函数,并改变函数中this指向。bind方法和call、apply方法的作用也类似,都是改变函数中this指向。不同之处在于bind方法不会立即执行函数,而是返回一个新的函数,需要再次调用才能执行。
1. 实现call函数
call函数是JavaScript中的一个方法,它的作用是改变函数中this的指向,并立即执行该函数。call函数的作用是改变函数中this的指向,并且可以传递多个参数给函数。call函数的语法如下:
function.call(thisArg, arg1, arg2, ...)
其中,thisArg是指定的this值,arg1、arg2等是传递给函数的参数。如果需要传递多个参数,可以使用逗号分隔。
// 在全局作用域中定义自定义的myCall方法
Function.prototype.myCall = function (context) {// 判断调用对象if (typeof this !== 'function') {console.error('type error')}// 获取参数let args = [...arguments].slice(1),result = null// 判断 context 是否传入,如果未传入则设置为 windowcontext = context || window// 将调用函数设为对象的方法context.fn = this// 调用函数result = context.fn(...args)// 将属性删除delete context.fnreturn result
}
这段代码实现了一个自定义的call函数,它的作用和JavaScript内置的call函数类似,都是用来改变函数中this的指向。具体实现步骤如下:
- 判断调用对象是否为函数,如果不是则抛出错误。
- 使用展开运算符和slice函数获取传递给call函数的参数。
- 判断context是否传入,如果未传入则默认为window对象。
- 将当前函数设为context对象的一个属性。
- 调用context对象上的属性,并传入参数。
- 将context对象上的属性删除。
- 返回调用结果。
需要注意的是,在使用自定义的call函数时,需要确保传入的第一个参数是需要改变this指向的对象,后面的参数会作为函数调用时的参数传入。同时,为了避免修改context对象,我们需要在调用函数后将context对象上的属性删除。
下面是一个使用自定义的call函数的例子:
// 定义一个对象
let person = {name: '张三'
}// 定义一个函数
function sayHello(age) {console.log(`我叫${this.name},今年${age}岁。`)
}// 调用自定义的call函数
sayHello.myCall(person, 18) // 输出:我叫张三,今年18岁。
在这个例子中,我们定义了一个名为person的对象和一个名为sayHello的函数。使用自定义的call函数,将person对象作为第一个参数传入,改变sayHello函数中this的指向。同时,将18作为第二个参数传入,作为函数调用时的参数。最终输出了一句话,说明函数调用成功。
总结:通过实现自定义的call函数,我们可以更好地理解call函数的工作原理。call函数的作用是改变函数中this的指向,并立即执行该函数。我们可以将当前函数作为对象的一个属性来调用,从而改变函数中this的指向,使用apply函数获取传递给call函数的参数,并将它们传递给当前函数。最后删除对象上的属性。
2. 实现apply函数
apply是JavaScript中的一个函数方法,用于改变函数中this的指向,并立即执行该函数。apply函数和call函数的作用类似,不同之处在于apply函数的第二个参数是一个数组,这个数组中的元素会被作为参数传递给函数。apply函数和call函数的作用是一样的,只是传递参数的方式不同。apply函数的语法如下:
function.apply(thisArg, [argsArray])
其中,thisArg是需要改变this指向的对象,argsArray是一个数组,它的元素会作为函数调用时的参数传入。如果不需要传递参数,则可以传入一个空数组。
Function.prototype.myBind = function (context) {// 判断调用对象是否为函数if (typeof this !== 'function') {throw new TypeError('Error')}// 获取参数var args = [...arguments].slice(1),fn = thisreturn function Fn() {// 根据调用方式,传入不同绑定值return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))}
}
这段代码实现了一个自定义的myBind方法,用于改变函数中this的指向,并返回一个新的函数。myBind方法的作用和call、apply方法类似,不同之处在于它不会立即执行函数,而是返回一个新的函数,需要再次调用才能执行。
myBind方法的实现思路如下:
- 判断调用对象是否为函数,如果不是则抛出一个类型错误。
- 获取myBind方法传入的参数,其中第一个参数是需要改变this指向的对象,后面的参数是传递给函数的参数。
- 返回一个新的函数Fn,用于接收myBind方法调用时传入的参数。
- 在新的函数Fn中,根据调用方式,传入不同的绑定值,使用apply方法执行原函数fn,并将参数传递给原函数fn。
- 如果新函数Fn被当做构造函数使用,即通过new关键字调用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。
下面是一个使用自定义的myBind方法的例子:
Function.prototype.myBind = function (context) {// 判断调用对象是否为函数if (typeof this !== 'function') {throw new TypeError('Error')}// 获取参数var args = [...arguments].slice(1),fn = thisreturn function Fn() {// 根据调用方式,传入不同绑定值return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))}
}// 定义一个对象
let person = {name: '张三'
}// 定义一个函数
function sayHello(age) {console.log(`我叫${this.name},今年${age}岁。`)
}// 使用自定义的myBind方法改变函数中this的指向,并返回一个新函数
let newFn = sayHello.myBind(person, 18)// 调用新函数
newFn() // 输出:我叫张三,今年18岁。
在这个例子中,我们定义了一个名为person的对象和一个名为sayHello的函数。使用自定义的myBind方法,将person对象作为第一个参数传入,改变sayHello函数中this的指向。同时,将18作为第二个参数传入,作为函数调用时的参数。调用myBind方法返回一个新的函数newFn,然后调用新函数newFn,输出了一句话,说明函数调用成功。
需要注意的是,使用自定义的myBind方法时,如果第一个参数不是一个对象,会导致函数调用失败。另外,如果新函数Fn被当做构造函数使用,即通过new关键字调用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。
总结:myBind方法是用于改变函数中this指向的方法,并返回一个新的函数。myBind方法的实现思路是先判断调用对象是否为函数,然后获取myBind方法传入的参数,返回一个新的函数Fn,使用apply方法执行原函数fn,并将参数传递给原函数fn。如果新函数Fn被当做构造函数使用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。在使用自定义的myBind方法时,需要注意第一个参数必须是一个对象,否则会导致函数调用失败。
3. 实现bind函数
bind是JavaScript中的一个函数方法,用于改变函数中this的指向,并返回一个新的函数,新函数中的this指向被绑定的对象,并且可以传递多个参数给函数。不会立即执行原函数。bind函数和call、apply函数的作用类似,不同之处在于bind函数返回一个新的函数,不会立即执行原函数。
bind函数的语法如下:
function.bind(thisArg[, arg1[, arg2[, ...]]])
其中,thisArg是需要改变this指向的对象,arg1、arg2等是传递给函数的参数。如果不需要传递参数,则可以省略后面的参数。
Function.prototype.myBind = function (context) {// 判断调用对象是否为函数if (typeof this !== 'function') {throw new TypeError('Error')}// 获取参数var args = [...arguments].slice(1),fn = thisreturn function Fn() {// 根据调用方式,传入不同绑定值return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))}
}
这段代码实现了一个自定义的myBind方法,用于改变函数中this的指向,并返回一个新的函数。myBind方法的作用和call、apply方法类似,不同之处在于它不会立即执行函数,而是返回一个新的函数,需要再次调用才能执行。
myBind方法的实现思路如下:
- 判断调用对象是否为函数,如果不是则抛出一个类型错误。
- 获取myBind方法传入的参数,其中第一个参数是需要改变this指向的对象,后面的参数是传递给函数的参数。
- 返回一个新的函数Fn,用于接收myBind方法调用时传入的参数。
- 在新的函数Fn中,根据调用方式,传入不同的绑定值,使用apply方法执行原函数fn,并将参数传递给原函数fn。
- 如果新函数Fn被当做构造函数使用,即通过new关键字调用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。
下面是一个使用自定义的myBind方法的例子:
Function.prototype.myBind = function (context) {// 判断调用对象是否为函数if (typeof this !== 'function') {throw new TypeError('Error')}// 获取参数var args = [...arguments].slice(1),fn = thisreturn function Fn() {// 根据调用方式,传入不同绑定值return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments))}
}// 定义一个对象
let person = {name: '张三'
}// 定义一个函数
function sayHello(age) {console.log(`我叫${this.name},今年${age}岁。`)
}// 使用自定义的myBind方法改变函数中this的指向,并返回一个新函数
let newFn = sayHello.myBind(person, 18)// 调用新函数
newFn() // 输出:我叫张三,今年18岁。
在这个例子中,我们定义了一个名为person的对象和一个名为sayHello的函数。使用自定义的myBind方法,将person对象作为第一个参数传入,改变sayHello函数中this的指向。同时,将18作为第二个参数传入,作为函数调用时的参数。调用myBind方法返回一个新的函数newFn,然后调用新函数newFn,输出了一句话,说明函数调用成功。
需要注意的是,使用自定义的myBind方法时,如果第一个参数不是一个对象,会导致函数调用失败。另外,如果新函数Fn被当做构造函数使用,即通过new关键字调用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。
总结:myBind方法是用于改变函数中this指向的方法,并返回一个新的函数。myBind方法的实现思路是先判断调用对象是否为函数,然后获取myBind方法传入的参数,返回一个新函数Fn,使用apply方法执行原函数fn,并将参数传递给原函数fn。如果新函数Fn被当做构造函数使用,那么this指向新创建的对象,否则this指向myBind方法传入的第一个参数context。在使用自定义的myBind方法时,需要注意第一个参数必须是一个对象,否则会导致函数调用失败。
总结:
call、apply和bind函数是JavaScript中用于改变函数中this指向的方法。它们的作用都是改变函数中的this指向,使函数能够在不同的对象上下文中运行。
call和apply方法的作用类似,都是立即执行一个函数,并改变函数中this指向。不同之处在于传递参数的方式不同,call方法是将参数一个一个地传递给函数,而apply方法是将参数作为一个数组传递给函数。
bind方法和call、apply方法的作用也类似,都是改变函数中this指向。不同之处在于bind方法不会立即执行函数,而是返回一个新的函数,需要再次调用才能执行。
持续学习总结记录中,回顾一下上面的内容:
call、apply和bind函数都是用于改变函数中this指向的方法。它们的作用都是使函数能够在不同的对象上下文中运行。call方法和apply方法的作用类似,都是立即执行一个函数,并改变函数中this指向。bind方法和call、apply方法的作用也类似,都是改变函数中this指向。不同之处在于bind方法不会立即执行函数,而是返回一个新的函数,需要再次调用才能执行。