В классах 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;
}
}
Вы не можете сделать это, как вы просили.
Однако, если вы уже используете 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;
}
}
});
Вы на самом деле не можете. Вы должны вернуться к настройке прототипа:
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); }
}
side
переменной класса по конструкции?this.side = new vec3()
private static readonly
. Если вы не используете typscript, вы не будете иметьprivate
и , если вы уже не используете ESNext также неreadonly
(хотя это может быть сделано с соответствующими изменениями дескрипторов).