MST

星途 面试题库

面试题:JavaScript中bind、call与apply在复杂场景下的应用

假设有一个复杂的JavaScript对象继承体系,有多个父类和子类,每个类都有一些方法。现在需要在子类的某个方法中,根据不同的条件,使用bind、call或apply方法来调用父类的方法。请编写代码实现这个需求,并解释选择每种方法的原因。
49.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

代码实现

// 定义父类
function Parent() {
    this.value = 'parent value';
}

Parent.prototype.getParentValue = function() {
    return this.value;
};

// 定义子类
function Child() {
    this.value = 'child value';
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.getParentValueBasedOnCondition = function(condition) {
    const parentGetParentValue = Parent.prototype.getParentValue;

    if (condition === 'bind') {
        // 使用bind方法创建一个新函数,绑定this为子类实例
        const boundFunction = parentGetParentValue.bind(this);
        return boundFunction();
    } else if (condition === 'call') {
        // 使用call方法直接调用父类方法,并将this设置为子类实例
        return parentGetParentValue.call(this);
    } else if (condition === 'apply') {
        // 使用apply方法直接调用父类方法,并将this设置为子类实例
        return parentGetParentValue.apply(this);
    }
    return null;
};

选择每种方法的原因

  1. bind
    • 原因bind方法用于创建一个新的函数,这个新函数的this被绑定到指定的值。在子类方法中,如果希望保留父类方法的引用,并在后续某个时刻调用它,同时确保this指向子类实例,bind是一个很好的选择。例如,可能需要将父类方法作为回调函数传递给其他函数,此时bind可以预先设置好this的指向。
  2. call
    • 原因call方法用于调用一个函数,并将this设置为指定的值。当需要立即调用父类方法,并且参数是逐个传递的情况下,call非常方便。它允许直接在调用时指定this的值,并且可以紧接着传入参数列表(在这个例子中父类方法无参数,但如果有参数可以依次写在call的参数中)。
  3. apply
    • 原因apply方法和call类似,也是用于调用一个函数并设置this的值。不同之处在于apply接受一个数组作为参数列表。如果参数是以数组形式存在,使用apply会更合适。在这个例子中父类方法无参数,但如果有参数且参数存储在数组中,就可以使用apply来调用父类方法。

使用示例

const child = new Child();
console.log(child.getParentValueBasedOnCondition('bind'));
console.log(child.getParentValueBasedOnCondition('call'));
console.log(child.getParentValueBasedOnCondition('apply'));