(javascript) вызовет es6 getter используя "call" - PullRequest
2 голосов
/ 13 апреля 2020

Я пытаюсь создать (класс) экземпляр, который копирует поведение другого класса, но использует себя как контекст состояния (это). Нормальные функции работают нормально (как функция setValue в примере ниже), но геттеры не работают. Вот простой пример:

const should = require('chai').should();

class One {
    setValue(val) {
        this._val = val;
    }

    get val() {
        return this._val;
    }
}

class Two {
    constructor(one) {
        this.one = one;
    }

    setValue(val) {
        this.one.setValue.call(this, val);
    }

    get val() {
        this.one.val.call(this);
    }
}

let one = new One();
let two = new Two(one);
one.setValue(1);
two.setValue(2);
one.val.should.equal(1);
two.val.should.equal(2);

Приведенный выше код взрывается в последней строке с ошибкой:

TypeError: this.one.val.call is not a function
    at Two.get val [as val] (C:\all\code\node-tests\invoke_getter.js:23:22)
    at Object.<anonymous> (C:\all\code\node-tests\invoke_getter.js:32:5)

Как я могу заставить что-то подобное работать?

1 Ответ

1 голос
/ 13 апреля 2020

Вспомните, что методы получения свойств для класса заканчиваются на его прототипе

Таким образом, чтобы получить доступ к методу, вы можете получить его из прототипа:

const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this.one), 'val')

Затем вы можете вызвать геттер на вашем two экземпляре:

class One {
  setValue(val) {
    this._val = val
  }

  get val() {
    return this._val
  }
}

class Two {
  constructor(one) {
    this.one = one
  }

  setValue(val) {
    this.one.setValue.call(this, val)
  }

  get val () {
    const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this.one), 'val')
    return desc.get.call(this)
  }
}

const one = new One()
const two = new Two(one)
one.setValue(1)
console.log(two.val) // undefined (since _val does not exist on two yet)
two.setValue(2)
console.log(two.val) // 2
two._val = 3
console.log(two.val) // 3
...