如何使用原型继承覆盖 JS getter & setter 函数?

How to override the JS getter & setter function using prototypal inheritance?

需要知道如何通过使用原型继承来扩展来覆盖 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 应该 return 我 欢迎来自 B

取而代之的是 returning 欢迎来自 A

感谢帮助。

欢迎使用 Whosebug ;)

在 Javascript 中,您有不同的方式来处理 "inheritance"。 正如您所说,由于 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.[=17= 调用这两种方法]

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 语法糖,它不那么冗长也更容易理解 ;)

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