Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(javascript) invoke es6 getter using "call"

I'm trying to create a (class) instance that copies the behavior of another class, but using itself as the state context (this). Normal functions work fine (like the setValue function in the example below), but getters do not work. Here is a simple example:

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);

The above code explodes on the last line with the error:

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)

How can I make something like this work?

like image 457
joniba Avatar asked Oct 15 '25 15:10

joniba


1 Answers

Recall that property getters for class ends in its prototype

So to access the method, you may want to get it from its prototype:

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

Then you can call the getter on your two instance:

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
like image 155
grodzi Avatar answered Oct 18 '25 03:10

grodzi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!