call,apply,bind

2 阅读1分钟

Function内置的实例方法,call,apply一般是用来改变执行上下文的,比如我们写了一个方法A,在A里面需要写相同的逻辑,这个时候就可以用call,apply来复用这些逻辑。

如下文:我们需要Food里面name的内容,明明直接在Food里面执行this.name=name就好了,但是我们用call去继承了Product的函数内容,这样就不需要重复写一遍了。

工作中,写一些基础类,公共的函数的时候就可以考虑使用他们。

function Product(name, price) {    this.name = name    this.price = price    this.discount = function() {        return this.price * 0.9    }} function Food(name, price) {    Product.call(this, name, price)      this.category = 'food'} const cheese = new Food('cheese', 5)console.log(cheese.discount())  // ✅ 输出: 4.5console.log(cheese.name)   

call和apply的共同特点就是:能够改变函数的执行上下文,将一个对象的方法交给另一个对象来执行,而且是立即被调用的。

区别在于:

call:

● 调用call的对象必须是一个函数,Function.call(obj,...args)

● 第一个是一个对象,后续函数的调用者都会指向这个对象,

● 从第二个参数开始,所有的参数都会映射到Function接收到的对象上面,如果传入的是数组的话,那么函数的第一个参数接收的是这个数组,后续都为undefied

 function Product(name, price) {    this.name = name    this.price = price    this.discount = function() {        return this.price * 0.9    }} function Food(name, price) {    Product.call(this, name, price)  // 借用 Product 的初始化逻辑    this.category = 'food'} const cheese = new Food('cheese', 5)console.log(cheese.discount())  // ✅ 输出: 4.5console.log(cheese.name)        // ✅ 输出: cheese

apply:

● 和call的基本一致,区别在于第二个参数,apply传入的是一个数组或类数组中

function test(a,b,c){    console.log(a,b,c)}Function.prototype.myApply = function (context,arr){    if (context === null || context === undefined) {        context = typeof window !== 'undefined' ? window : global    }    const key = Symbol()    context[key] = this    const result = context[key](...arr)    delete context[key]    return result}test.apply(null,[1,2,3]) // 1,2,3test.myApply(null,[1,2,3]) 

bind:

● 调用apply的对象必须是一个函数,Function.bind(obj,...args)

● call和apply是立即被执行的,而apply不一样,他是返回了一个函数,在被调用的时候才会进行执行。

function myBind(context,...boundArgs){    // 保存原函数    const originalFunction = this        // 返回新函数    return function(...callArgs) {        // 合并参数:bind 时传入的参数 + 调用时传入的参数        const allArgs = [...boundArgs, ...callArgs]                // 使用 apply 执行原函数        return originalFunction.apply(context, allArgs)    }}