【问题标题】:How to override the JS getter & setter function using prototypal inheritance?如何使用原型继承覆盖 JS getter & setter 函数?
【发布时间】:2020-08-16 07:42:06
【问题描述】:

需要知道如何通过使用原型继承来覆盖 getter 和 setter

以下是理解问题的示例

function A() {
    this._loading = "Welcome";
}

Object.defineProperty(A.prototype, 'loading', {
    get() {
        return this._loading+" from A";
    },
    set(value) {
        this._loading = value;
    }
});

function B() {}
Object.defineProperty(B.prototype, 'loading', {
    get() {
        return this._loading+" from B";
    },
    set(value) {
        this._loading = value;
    }
});

var a=new A();
var b=new B();

b.__proto__=a; // Not sure if this is wrong. This assigns the whole prototype of A to B so that B is submerged

我的预期结果是 b.loading 应该返回我 来自 B 的欢迎

而是它的回归 来自 A 的欢迎

感谢您的帮助。

【问题讨论】:

    标签: javascript object inheritance prototype getter-setter


    【解决方案1】:

    欢迎来到 stackoverflow ;)

    在 Javascript 中,您有不同的方式来处理“继承”。 正如您所说,由于 proto 重新分配,您的实现无法正常工作。

    1.覆盖原型
    通常it is considered bad practices 使用__proto__ 访问原型。在您的情况下,您正在重新分配 B 的整个原型,因此它将替换所有原型。

    // Here you are overriding the prototype of "b"
    b.__proto__=a;
    
    // It refers to the prototype of a, so it the equivalent of calling a.loading
    b.loading
    

    2。从其他原型继承 - ES5

    function B() {
      // Call the constructor of A giving the "B.this" context
      A.call(this)
    }
    // Inherits from prototype of A
    B.prototype = Object.create(A.prototype)
    Object.defineProperty(B.prototype, 'loading', {
        get() {
            return this._loading+" from B";
        }
    });
    
    // You won't need to instanciate A to inherits from it
    const b = new B();
    b.loading // "Welcome from B"
    

    3.更进一步
    在现实世界的场景中,您可能希望从 A 继承一些属性,并覆盖 B 中的其他属性。因为 B 继承自 A,您可以从 B.prototype 和 A.prototype 调用这两种方法。

    function A() {
      this._loading = "Welcome";
    }
    
    Object.defineProperty(A.prototype, "loadingA", {
        get: function loading() {
            return this._loading + " from A"
        }
    });
    
    Object.defineProperty(A.prototype, "loading", {
        get: function loading() {
            return this._loading + " from A"
        }
    });
    
    
    function B() {
      A.call(this)
    }
    B.prototype = Object.create(A.prototype)
    Object.defineProperty(B.prototype, 'loading', {
        get() {
            return this._loading+" from B";
        }
    });
    
    var b = new B()
    b.loading // Welcome from B
    b.loadingA // Welcome from A
    

    4.第二步 - ES6+
    您可能想使用 ES6 类语法糖,它不那么冗长且更易于理解;)

    class A {
      constructor() {
        this._loading = "Welcome"
      }
    
      get loading() {
        return this._loading + " from A"
      }
    }
    
    class B extends A {
      get loading() {
        return this._loading + " from B"
      }
    }
    
    b.loading // Welcome from B
    b.loadingA // Welcome from A
    

    Further readings on javascript inheritance

    【讨论】:

      猜你喜欢
      • 2011-03-11
      • 2013-11-11
      • 2011-03-21
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多