【问题标题】:Override function in JavaScript [duplicate]JavaScript中的覆盖函数[重复]
【发布时间】:2012-07-17 12:53:07
【问题描述】:

可能重复:
Calling base method using JavaScript prototype

我想继承将覆盖 javascript 中的函数的对象。

从我要调用的方法到基本方法。 在这种情况下,我从Person 继承对象reader,现在我想覆盖函数getName,这意味着在阅读器中我首先要调用Person 上的函数,然后进行一些更改。

<script>
    /* Class Person. */
    function Person(name) {
        this.name = name;
    }
    Person.prototype.getName = function() {
        return this.name;
    }

    var reader = new Person('John Smith');
    reader.getName = function() {
        // call to base function of Person, is it possible?
        return('Hello reader');
    }
    alert(reader.getName());
</script>

【问题讨论】:

    标签: javascript prototype


    【解决方案1】:

    由于您正确地覆盖了对象本身而不是其原型上的函数,因此您仍然可以使用您的对象调用原型函数。

    reader.getName = function() {
        var baseName = Person.prototype.getName.call(this);
        ...
    }
    

    【讨论】:

    • 如果 ES5 可用,请使用 Object.getPrototypeOf( this ).getName.call( this ); 使其更加动态化。
    • 我会使用 Person.prototype.getName.apply(this, arguments) 这样您就不会丢失任何参数。除非您特别不想传递参数。
    【解决方案2】:

    这是一种方法:

    function Person(name) {
    this.name = name;
    }
    Person.prototype.getName = function(){
    return this.name;
    }
    
    var reader = new Person('John Smith');
    reader.oldGetName = reader.getName;
    reader.getName = function() {
    //call to base function of Person , is it possible ?
        return this.oldGetName();
    }
    alert(reader.getName());​
    

    http://jsfiddle.net/fXWfh/

    【讨论】:

    • 文森特的回答似乎比这更简洁——可能是更好的方法......
    【解决方案3】:

    我使用 John Resig 的这项技术来获得继承和方法覆盖。它甚至允许您通过调用 this._super() 来访问被覆盖的方法。

    http://ejohn.org/blog/simple-javascript-inheritance/

    【讨论】:

      【解决方案4】:

      Vincent 回答了您的直接问题,但如果您想建立一个真正的继承层次结构,您可以在其中进一步扩展 Reader,您可以这样做。

      创建你的person类:

      function Person(name) {
          this.name = name;
      }
      
      Person.prototype.getName = function(){
          alert('Person getName called for ' + this.name);
          return this.name;
      }
      

      同时创建一个 Reader 类:

      function Reader(name) {
          // Calls the person constructor with `this` as its context
          Person.call(this, name);
      }
      
      // Make our prototype from Person.prototype so we inherit Person's methods
      Reader.prototype = Object.create(Person.prototype);
      
      // Override Persons's getName
      Reader.prototype.getName = function() {
          alert('READER getName called for ' + this.name);
          // Call the original version of getName that we overrode.
          Person.prototype.getName.call(this);
          return 'Something';
      }
      Reader.prototype.constructor = Reader;
      

      现在我们可以重复类似的过程来扩展 Reader,比如 VoraciousReader:

      function VoraciousReader(name) {
          // Call the Reader constructor which will then call the Person constructor
          Reader.call(this, name);
      }
      
      // Inherit Reader's methods (which will also inherit Person's methods)
      VoraciousReader.prototype = Object.create(Reader.prototype);
      VoraciousReader.prototype.constructor = VoraciousReader;
       // define our own methods for VoraciousReader
      //VoraciousReader.prototype.someMethod = ... etc.
      

      小提琴: http://jsfiddle.net/7BJNA/1/

      Object.create:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create

      Object.create(arg) 正在创建一个新对象,其原型是作为参数传入的对象。

      编辑 自从这个原始答案以来已经有好几年了,现在 Javascript 支持 class 关键字,如果您来自 Java 或 C++ 之类的语言,该关键字可以正常工作。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

      【讨论】:

      • 这应该是选择的答案,它很清楚并准确地显示了 javascript 中的虚拟继承如何使用原型,这在许多其他答案中都是模糊的
      猜你喜欢
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 2023-03-04
      • 2010-10-30
      • 1970-01-01
      • 2014-11-20
      • 2021-04-17
      • 2015-09-26
      相关资源
      最近更新 更多