Define a static class variable on javascript - javascript

I'm starting using the new way of OO in javascript by following this tutorial. This new way of OO of javascript follows the ES6 specification.
Follows a sample of my code:
class SomeClass{
static SomeFunction(data){
this.data = data;
}
}
What I want is to make the variable this.data static.
Is any way that I could do that?

Because the new class keyword is just syntatic sugar you can do
SomeClass.staticVariableName = value;
Put this outside of the class, if you put it in the constructor, then it will only be initialized when you create at least 1 instance.
Side note: if this is a client side code, then I just want to warn you that you shouldn't authenticate people client side, because it's terribly insecure.

Related

How to add properties functions to objects from another class in Java?

In Javascript we can define an object like this 👇
let obj={
property1:67,
func1: function (){
//Some code
}
}
Now if we want add a new property to obj I can just add a new property like this
obj.property2=733; //some value or function
Now I want to do the same thing in Java also.
I have a class Test 👇
public class Test{
int property1=67;
public void func1(){
//Some code
}
}
Now is it possible to do like the same thing like statement #2 in Java also?
Edit:
From the answers I got to know that we can use a Map for properties.
Now I want to know for methods.
Thanks
So I did a research and as I can see this is not simple.
In java you can not do that, actually, you can if you provide your own custom class loading, which is really a bad idea because then even if you change the class you want you must reload all classes that interact with this class.
Check this article to understand more about class loaders.
Of course, there are some other ways as:
ASM an all-purpose Java bytecode manipulation and analysis framework.
Javassist a library for editing bytecodes in Java
AspectJ aspect-oriented extension to the Java, mostly used to clean modularization of crosscutting concerns

Access Singleton from anywhere

In my game, I've created a list of gameObjects (instances of other classes such as Player) in my Main that I can loop through and render in one function, rather than rendering them all individually. This is my render function;
this.gameObjects = [];
addObj(obj){
this.gameObjects.push(obj);
}
render(){
this.gameObjects.forEach(obj => obj.render());
}
This works no problem if I want to add another gameObject using my main class like this;
let main = new Main();
let player = new Player(10, 30, 10, 10, 'red');
main.addObject(player);
main.start();
However, I want to add another gameObject, called Projectile within my Player class. The problem is my Player class doesn't have access to Main's addObj function.
My idea was to create a singleton, that holds a list of game objects, like this;
class Repository{
constructor(){
if(this.instance){
return this.instance;
}
this.list = [];
this.instance = this;
}
get obj(){...}
addObj(obj){...}
}
The tl:dr of the question is;
Is this the best way to go forward?
How would I access this singleton? By importing it everywhere I needed it?
Create a global variable with an instance? How would I do this?
Am I over thinking this? Should I just pass main in to each class and access its methods that way?
Using a singleton might complicate unit tests, and add a hidden state to the information flow of the application. It's not that the pattern is inherently flawed, but there's a right and wrong way to use this pattern, and if you don't intend to spend the time and understand the pattern, you're probably better off not using it. Your plan for the Singleton will work, it's just not the most robust solution.
Notice that JS is a functional language. You don't need to pass main to each class, you can just pass the addObject function. That way when you change context (for example in unit tests or if you'll recycle the code for other projects) you'll be able to just switched the passed function, and keep all of your code.

Can I control how the class is being created in ES6?

In Python3 I can use magic function __new__, which executes before class initialization. This helps me control whether new instance will be created or we will use some instance from cache.
Just a little simplified example:
class Something:
def __new__(..., someArgument):
# was a class with someArgument initialized somewhere before?
# is yes, then:
return CACHE[someArgument]
# if no, then:
CACHE[someArgument] = Something(someArgument)
return CACHE[someArgument]
So, can I the same in ES6? Or how can I control class initializing in other way?
This question is not a duplicate of this one, because I'm asking whether I can find some functionality in JS, while the topic above contains a duscussion about this functionality.
As Justinas commented, you can look up about Javascript Factory.
A Javascript Factory define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Some places you can look it up:
Factory Method Design Pattern
Factory Functions with ES6
Calling Javascript Factory Method
I Hope it helped!
You can use factory function:
class Test {
}
function getInstance() {
if (!Test._instance) {
Test._instance = new Test();
}
return Test._instance;
}
No, when a (non-derived) constructor is invoked with new (or super()) then an object is already instantiated before any custom code runs1. However, JS lets you overwrite the result value of the expression by returning an object from the constructor. You can write
const CACHE = new Map();
class Something {
constructor(someArgument) {
if (CACHE.has(someArgument)) return CACHE.get(someArgument);
// ^^^^^^
CACHE.set(someArgument, this);
// initialise `this`
}
}
That said, a factory function (or even static method) - as suggested by the other answers - is usually a more sensible solution. You'd put the cache handling code only in the constructor if you absolutely needed to enforce this.
1: it could be intercepted by the construct trap of a proxy, but you normally would not use that.

Define static class properties in JavaScript

What is the best practice way to define static class private properties in JavaScript ES6 in Node.js?
I have the following Log class:
'use strict';
const moment = require('moment');
const LOG_DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
module.exports = class {
static debug(txt) {
console.log(`${moment().utc().format(LOG_DATE_FORMAT)} [debug] ${txt}`);
}
static info(txt) {
console.info(`${moment().utc().format(LOG_DATE_FORMAT)} [info] ${txt}`);
}
static warn(txt) {
console.warn(`${moment().utc().format(LOG_DATE_FORMAT)} [warn] ${txt}`);
}
static error(txt) {
console.error(`${moment().utc().format(LOG_DATE_FORMAT)} [error] ${txt}`);
}
};
Is defining moment and DATE_FORMAT outside of the module.exports and thus class definition the correct way of doing this?
Yes, it's an acceptable way of doing things. Since you want to define some variables that you share among all your static methods, you have basically four choices:
Define them as statics on the class also so you can reference them using the class name as a prefix. This has the benefit or drawback (depending upon what you want) that it makes them publicly accessible on your exported class.
Define them as module level variables as you've done. This makes them accessible by all the static methods, but keeps their use private to your module.
Redefine them separately inside of each method.
Define them as globals.
Option #3 seems like a lot of repetition and certainly wouldn't be very DRY.
Option #4 does not seem like a good way to go since there's no reason to make these globals (you pretty much never want to use globals with node.js anyway).
So, it comes down to option #1 or #2 and which to choose totally depends upon whether you want their values to be accessible outside the module or not. If you want them exported also, then make them static properties on your class and refer to them with the class prefix. If you only want to use them inside the module, then what you have done is perfect.

Typescript - implementing an interface without implementing the interfaces parents

I currently have the following interfaces defined in a project
interface foo {
fooProperty: number;
fooFunction(): void;
}
interface bar extends foo {
barProperty: string;
barFunction(): void;
}
Now I want to define a class like
class myBar implements bar {
public barProperty: string ="bar";
public barFunction() {
// do dosmething
}
}
However I don't want to have to implement foo's functions and properties too, as these are already defined in an existing JS class which the interfaces define.
Essentially what I'm trying to do is create a typescript class that is extended from a 3rd party JS library for which I have "d.ts" files that describe the implementation, but which is NOT in typescript in it's source form.
In order to use a particular function in the 3rd party library, I have to create a custom class that derives from a class they provide in JS, but which I then override using "prototype", however I need to do this using typescript.
Update 1
It seems that folks reading this are not quite getting what I'm trying to achieve here, so let me elaborate a bit more.
In the project I'm working on we use a 3rd party JS lib, lets call this "thirdLib.js"
Within "thirdLib.js" there is functionality, that in order to use it, requires me to extend a JS style class provided as part of "thirdLib.js" like so:
function myClass(){
thirdlib.thirdclass.call(this);
}
thirdLib.utilities.extendclass(myClass, thirdLib.thirdClass);
myClass.prototype.overriddenFunc = function(){
// Do custom function here
}
The "extendClass" method in "thirdlib" copys the constructor of the class I'm deriving from into my constructor or so I'm lead to believe.
Which is then used later on, elsewhere in "thirdlib.js" EG:
var myStuff = new thirdLib();
var theClass = new myClass();
myStuff.registerSomething(theClass);
myStuff.doAThing();
At the point where I call "doAThing", thirdLib.js has the new JS class registered with it, and that class has ALL the original functionality as present in "thirdClass" but with MY customisations added to it.
All I have for "thirdLib.js" is the JavaScript code (Minified) and a set of Typescript definition files (Which I've written myself, as none where provided with the lib), and I need to be able to create "myClass()" using normal Typescript functionality, while still extending and consuming everything that's in the original JS class, and while being able to add my functionality to the TS class and have that override the functionality in the base JS class when I do.
Update April 2022
For those who are wondering, about 6 months after my last comment I moved on from the company I was doing this project for, and so I never got to see it through to a resolution, since I don't have the code or access to it anymore, I doubt very much it will ever be resolved. For those who are interested, the "Custom Drawing Handler" I was trying to implement, was a custom drawing class for a (Then Commercial, now it's OSS) 3rd party JS library called "MXGraph"
If I got your problem right you could just have your class myBar extend the class myFoo, hence inheriting the given implementation and fulfilling the criteria defined in the interface.

Categories