调用影子原型方法的更简单/更好的方法

Simpler / better way to call shadowed prototype method?

本文关键字:方法 更好 更简单 影子 调用 原型      更新时间:2023-09-26

我正在用JavaScript编写对象层次结构,当我在对象中对对象的父对象上的方法进行阴影处理时,我想调用该方法。

例如:

var Base = function Base(msg) {
  this.msg = msg;
}
Base.prototype.log = function(){
  console.log("base log: " + this.msg);
}
var Sub = function Sub(msg) {
  Base.call(this, msg);
}
Sub.prototype = Object.create(Base.prototype);
Sub.prototype.log = function() {
  console.log("sub log");
  this.__proto__.__proto__.log.call(this); // This works but __proto__
  Object.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this); // This works but is verbose
  super.log(); // This doesn't work
}
var sub = new Sub('hi');
sub.log();

请看Sub.prototype.log函数底部的三行——有更好的方法来完成我要做的事情吗?

第二行是我能想到的最好的一行,但非常冗长!

super没有定义,显然它不起作用。

你可能想试试:

Sub.prototype.log = function() {
  console.log("sub log");
  Base.prototype.log.call(this);
}

另一种方法是使用以下方法来继承类:

function extend(Child, Parent) {
    var F = function() { };
    F.prototype = Parent.prototype;
    Child.prototype = new F();    
    // better to make it static (better practice in OOP world) 
    // e.g. Child.super = ...,
    // but in your case:
    Child.prototype.super = Parent.prototype;      
}

这里有一个例子:

// ..
extend(Sub, Base);
Sub.prototype.log = function() {
  console.log("sub log");
  this.super.log.call(this);
}

ES6:的情况下

class Base {
  constructor(msg) {
    this.msg = msg;
  }
  log(){
    console.log("base log: " + this.msg);
  }
}
class Sub extends Base {
  constructor(msg) {
    super(msg);
  }
  log() {
    console.log("sub log");
    super.log();
  }
}
var sub = new Sub('hi');
sub.log();

如果您想保留原始方法而不使用名称Base,您可以在更改它之前使用闭包捕获它。

(function() {
   var superLog = Sub.prototype.log;
   Sub.prototype.log = function() {
       console.log("sub log");
       superLog();
   };
})();

这样就不依赖于如何从Base继承。

附带说明:您要查找的术语是"覆盖"基本方法。