Как переопределить функцию JS getter & setter, используя прототип наследования? - PullRequest
0 голосов
/ 01 мая 2020

Необходимо знать, как переопределить геттеры и сеттеры путем расширения с использованием наследования прототипов

Ниже приведен пример для понимания проблемы

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

Помощь приветствуется.

1 Ответ

0 голосов
/ 02 мая 2020

Добро пожаловать в stackoverflow;)

В Javascript у вас есть другой способ обработки "наследования". Как вы сказали, ваша реализация не работает из-за переназначения proto .

1. Переопределение прототипа
Обычно считается плохой практикой для доступа к прототипу с использованием __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

Дополнительные сведения о javascript наследовании

...