JavaScript 中的行为委托是一种编程模式,它通过对象之间的原型链关系来共享属性和方法。相比传统的继承,行为委托更加灵活和可扩展,可以避免类层次结构的复杂性,并促进代码的重用和组合。
继承是一种将属性和方法从一个对象复制到另一个对象的方式,而行为委托则是通过关联两个对象的原型链来共享属性和方法。继承创建了一个类层次结构,而委托创建了一个对象之间的关联。
我们可以通过 Class
和 extends
关键字实现继承。(注意:继承一般是把公共行为封装好,供’后代’使用)
以下是继承的示例:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Fido');
dog.speak(); // 输出 'Fido barks.'
显式行为委托是通过将一个对象的属性或方法直接指向另一个对象来实现的。这可以使用 Object.create()
方法来创建一个新对象,并将其原型指向另一个对象。
const delegateObj = {
foo() {
console.log('foo');
}
};
const targetObj = Object.create(delegateObj);
targetObj.foo(); // 输出 'foo'
上面的代码中,我们创建了一个 delegateObj
对象,它有一个 foo
方法。然后,我们使用 Object.create()
方法创建了一个新对象 targetObj
,并将其原型指向 delegateObj
。这样,当我们调用 targetObj.foo()
时,它会在 delegateObj
中查找 foo
方法并执行。
隐式行为委托是通过对象之间的原型链关系来实现的。当一个对象无法找到属性或方法时,它会沿着原型链向上查找,直到找到对应的属性或方法或者到达原型链的末端。
const delegateObj = {
foo() {
console.log('foo');
}
};
const targetObj = Object.create({});
Object.setPrototypeOf(targetObj, delegateObj);
targetObj.foo(); // 输出 'foo'
上面的代码中,我们创建了一个 delegateObj
对象,它有一个 foo
方法。然后,我们创建了一个空对象 targetObj
,并使用 Object.setPrototypeOf()
方法将其原型设置为 delegateObj
。这样,当我们调用 targetObj.foo()
时,它会沿着原型链向上查找,在 delegateObj
中找到 foo
方法并执行。
行为委托是一种更灵活和可扩展的编程模式,相比传统的继承,它可以避免类层次结构的复杂性,并促进代码的重用和组合。通过委托,我们可以将不同对象之间的共享行为抽象出来,并将其复用于其他对象,从而提高代码的可维护性和可扩展性。
行为委托确实是一种强大的编程模式,可以使我们更好地组织和重用代码。在实际开发中,我们可以根据需要选择显式或隐式行为委托,并结合其他编程技巧来实现更加灵活和可维护的代码。同时继承也是非常不错的解决方案。