Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Naming a dynamically created javascript type [duplicate]

I'm trying to create a function Vector that takes a number n and returns a type Vector[n]:

let Vector = n => {
    const result = function(...vals) {
        this._data = Array(n).fill(0).map((_, i) => vals[i] || 0)
        Object.assign(this, this._data.reduce((a, c, i) => ({ ...a, ['v' + i]: c }), {}));
    }
    result.prototype.add = function(v) {
        return new result(...this._data.map((x, i) => x + v._data[i]));
    }
    return result;
}

And it works just fine:

 let Vec2 = Vector(2);
 let v1 = new Vec2(0, 1);
 let v2 = v1.add(new Vec2(1, 2))
 console.log(v2);

The logged value looks like this:

 result {_data: Array(2), v0: 1, v1: 3}

It's all working as intended, except that the name of the type is 'result'. I'd rather name it 'Vector2' in this case. How could I do this?

I tried to to create a dynamic name by replacing result with this['Vector' + n] but that resulted in this:

 Vector.(anonymous function) {_data: Array(2), v0: 1, v1: 3}

I also tried assigning result.name and result.prototype.name but neither worked as intended.

Is it possible to rename a dynamically created type in Javascript?

like image 289
H. Saleh Avatar asked May 13 '26 11:05

H. Saleh


1 Answers

Using new Function() or eval() and enclosing your logic in a template string works.

Check this answer for more information on dynamic function names.

let Vector = n => {
  const name = 'Vec' + n;
  return new Function(`return function ${name}(...vals) {
    this._data = Array(${n}).fill(0).map((_, i) => vals[i] || 0)
    Object.assign(this, this._data.reduce((a, c, i) => ({ ...a, ['v' + i]: c }), {}));
    this.add = function(v) {
      return new ${name}(...this._data.map((x, i) => x + v._data[i]));
    }
  }`)()
}

const Vec2 = Vector(2);
const Vec3 = Vector(3);

const vec2 = new Vec2(0, 1);
const vec3 = new Vec3(0, 1, 2);

console.log(vec2 instanceof Vec2);
console.log(vec3 instanceof Vec3);
console.log(Vec2.name, Vec3.name);
console.log(vec2.add(new Vec2(1, 2)));
console.log(vec3.add(new Vec3(1, 2, 3)));
like image 193
jo_va Avatar answered May 15 '26 00:05

jo_va



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!