Локальные временные переменные для методов с современными классами JavaScript ES6

1

В классах javascript старого стиля вы можете использовать IIFE для определения некоторых временных переменных для методов, которые предварительно выделены и, следовательно, не должны вызывать new все вызовы метода.

// constructor
var MyClass = function(x,y,z){ this.pos=new vec3(x,y,z); } 

// method
MyClass.prototype.vec_combine = ( function( a,b,c, up,fw) {
    var side = new vec3(); // allocated at construction, not at invocation
    return function vec_combine( a,b,c, up,fw) { 
       cross_product( up,fw, side ); // side is perpendicular to up,fw
       side.normalize();
       this.pos.x = fw.x*a + up.x*b + side.x*c;
       this.pos.y = fw.y*a + up.y*b + side.y*c;
       this.pos.z = fw.z*a + up.z*b + side.z*c; 
    }
}() );

Как вы можете сделать это с помощью современных ES6-классов?

class MyClass{
  constructor(x,y,z){ this.pos=new vec3(x,y,z); } 

  // method
  vec_combine( a,b,c, up,fw) {
    var side = new vec3(); // I don't want do "new" each invocation
    cross_product( up,fw, side ); // side is perpendicular to up,fw
    side.normalize();
       this.pos.x = fw.x*a + up.x*b + side.x*c;
       this.pos.y = fw.y*a + up.y*b + side.y*c;
       this.pos.z = fw.z*a + up.z*b + side.z*c; 
  }
}
  • 0
    Почему бы не сделать side переменной класса по конструкции? this.side = new vec3()
  • 1
    Прежде всего, ничто не мешает вам использовать свой верхний путь в ES6. То, что я лично сделал бы, это использовать машинописный текст и поместил бы это как private static readonly . Если вы не используете typscript, вы не будете иметь private и , если вы уже не используете ESNext также не readonly (хотя это может быть сделано с соответствующими изменениями дескрипторов).
Показать ещё 1 комментарий
Теги:
es6-class
iife

2 ответа

1

Вы не можете сделать это, как вы просили.

Однако, если вы уже используете ES6, вы, вероятно, используете модули. Вы можете просто иметь переменную в модуле, который не экспортируется.

// Not exported
var side = new vec3(); // I don't want do "new" each invocation

export class MyClass{
  constructor(x,y,z){ this.pos=new vec3(x,y,z); } 

  // method
  vec_combine( a,b,c, up,fw) {
    cross_product( up,fw, side ); // side is perpendicular to up,fw
    side.normalize();
    this.pos.x = fw.x*a + up.x*b + side.x*c;
    this.pos.y = fw.y*a + up.y*b + side.y*c;
    this.pos.z = fw.z*a + up.z*b + side.z*c; 
  }
}

Если вы не используете модули, вы можете поместить весь класс в IIFE

const MyClass =  (() => {
  var side = new vec3(); // I don't want do "new" each invocation

  return class {
    constructor(x,y,z){ this.pos=new vec3(x,y,z); } 

    vec_combine( a,b,c, up,fw) {
      cross_product( up,fw, side ); // side is perpendicular to up,fw
      side.normalize();
      this.pos.x = fw.x*a + up.x*b + side.x*c;
      this.pos.y = fw.y*a + up.y*b + side.y*c;
      this.pos.z = fw.z*a + up.z*b + side.z*c; 
    }
  }

});

  • 0
    Хорошая вещь в IIFE заключается в том, что определение временной переменной является локальным, что делает код намного более читабельным и обслуживаемым.
0

Вы на самом деле не можете. Вы должны вернуться к настройке прототипа:

class Test { }

Test.prototype.test  = (s => () => console.log(s))("hi");

new Test().test()

Чтобы немного это украсить, вы можете переписать методы с помощью небольшого помощника:

const init = (cl, name, ...args) => cl.prototype[name] = cl.prototype[name](...args);

Используется как:

class Test {
 test(s) {
   return function() {
     console.log(s);
   }
 }
}

init(Test, "test", "hi");
new Test().test();

Однако в большинстве случаев должно быть достаточно, чтобы обладать переменной локально всем классом:

const Test = (s => {
   return class {
     test(){ console.log(s); }
   };
})("hi");

Или же:

let Test;
{
   const s = "hi";

   Test = class {
      test() { console.log(s);
   };
}

... Или вы просто положили его в верхнюю область и надеетесь, что все последуют за правилом "не использовать символы подчеркивания":

const _s = "hi";

class Test {
  test() { console.log(_s); }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню