Reusing class names in JavaScript - javascript

Is it in someway possible to reuse a class name that is defined in the Global objects list found here? (Like Number, String)
Lets say that I want to have my own String class. I can define it, and use it like this:
String.js
export default class String {
}
App.js
import String from './String'
let string = new String();
This actually works, but then
PHPStorm tells me: yeah you used a primitive object wrapper (thinking it's
the global object String).
Then ESLint tells me: Disallow Primitive Wrapper Instances (no-new-wrappers)
And lastly SonarQube tells me: The use of wrapper objects for primitive types is gratuitous, confusing and dangerous. Simple literals should be used instead.
So yeah is there a way to encapsulate my class so it doesn't get confused with the global String class?

import './String'
Function and class definitions are local to the module. You're importing the file, but not using anything from it.
That's why this:
let string = new String();
will use the global String—there is no String definition in the module scope.
Make sure you name the imports you need:
import String from './String'
Incidentally, this is one of multiple reasons why it is better practice to give your String class a unique name, like PhysicsString or StringMaterial or Thread. That way if you forget to import it somewhere, you won't accidentally be using the global definition.

Related

is there a way to import all keys inside a package with require?

I would like to know if there is a way to import all elements of a package/file without directly naming them
example:
//file1 - things.js
module.exports = {
thing1:{...},
thing2:{...},
thing3:{...}
}
//file2 runner.js
const things = require("./things")
console.log(things.thing1)
//in this case it imports the things.js and its elements and assigns the variable things,
//but that's not what I want
//I want it to import the native variables from the things.js file without having to pull each one individually
//---
//i know i can import the native variables by pulling them like this:
const { thing1, thing2 } = require("./things")
console.log(thing1, thing2)
//but this is not what I want either, what I want should look like the following example:
const {} = require("./things")
console.log(thing1, thing2, thing3)
//imporiting all native variables without having to define one by one
Short answer, no.
When using module.exports, you're effectively assigning a value to the return of require. That value can be any valid JavaScript value, in this particular case, an object. Presently, JavaScript does not have a mechanism for destructuring an object into all of its constituent keys, which is functionally what you're asking for.
In fact, JavaScript has no mechanism at all for implicit variable declaration, at least not in strict mode. If it doesn't appear in the source code, it's not there.
A hacky way around this could be something like this:
const thing = require('../thing.js');
for (const key in Object.keys(thing)) {
global[key] = thing[key]; // using "global" here instead of "window" for environment-agnostic code
}
This will force all of your exports to be available in the global scope, accessible as if they were declared. However, your editor/IDE will get very upset that it doesn't know where these variables came from, and this is horrific, unrecommendable practice.

Underscore sign change accessibility of variable

In angular I have two files
in the first file
private _test: BehaviorSubject<any> = new BehaviorSubject({});
In the second file
test$: Observable<Object> = this.test2;
when I change in first file .ts variable from _test to test I have an error
Property 'test' is private and only accessible within the class
In some article:
A convention has also developed regarding the use of _, which is frequently used to preface the name of an object's property or method that is private
Why using underscore sign project compiles without errors?
In typescript / Javascript ES6, getter are defined that way:
get test() : any {
return this._test;
}
because of that, you can't have both a property and a function with the same name.
This is also why, when generating getter/setter, your IDE will usually renamed the property with underscore (_).
You could rename the property to remove the underscore, changing it's visibility to public, and remove the function. in both case Your property will be accessible like that obj.test.

eval template string and class instances

During a code refactoring exercise, eval() was put into service to parse a template string and instantiate a class. The running code is linked to below.
eval(`let ${tempid} = new Accordian(${"[j]"})`)
Why does this string appear to need quotes around the object referenced by [j] to work?
My other question has to do with class instances, and whether they've been created?
So, the variable tempid is supposed to be a string extracted from a nodeList, but the error I'm getting seems to suggest otherwise, despite the fact the code runs which, to my mind, it wouldn't do unless it has actually instantiated a new class for each of the accordian objects extracted as unique from the markup.
Have two new class instances been created?
I'm getting the following errors:
'Accordian' is defined but never used. (no-unused-vars) eslint
'use strict' is unnecessary inside of modules. (strict) eslint
eval can be harmful. (no-eval) eslint
https://codesandbox.io/embed/eager-morning-9s5ti?fontsize=14
Why quotes?
"[j]" is the String inserted into the template string by ${ }. As far as I can tell, the whole ${"[j]"} part could just be replaced with [j].
"Accordian never used"
Your linter doesn't know what eval will do at runtime. Since you're only using Accordian in a string, it's not actually used in your code.
"eval can be harmful"
eval is evil. Depending on the value of the inserted tempid, the evaluated string could contain arbitrary (potentially harmful) code. You might wanna use tempid to set an attribute on some object instead, e.g. global[tempid] = new Accordian([j]). This would let the linter see the class' usage as well.

Difference between class and function blocks in React?

I was going through an article on Commonly faced problems with React and there i found this example.
class Numbers extends React.Component {
const arrayOfNumbers = _.range(1, 10);
// ...
}
It said "The code above is invalid because inside the body of a JavaScript class you don’t have the freedom of doing just about anything. You can only define methods and properties using limited syntax.
This is a bit confusing because the {} used in the class syntax looks like the plain-old block scope, but it’s not.
Inside a function-based component, you DO have the freedom of doing just about anything"
// Totally Okay:
const Number = (props) => {
const arrayOfNumbers = _.range(1, 10);
// ...
};
Can anyone explain to me why the above statement inside the class body is invalid ?? And what is that strange looking _. symbol ??
Can anyone explain to me why the above statement inside the class body is invalid ??
That's just the way the syntax for classes is. You can define functions in the body of the class, and they'll go on the prototype. If you want any instance variables, you do those in the constructor.
And what is that strange looking _. symbol ??
It's a variable named _. In this case, it's almost certainly a reference to the Lodash library, a commonly used library with utility functions.

Singleton in JavaScript with module.export and require?

I am trying to implement Singleton in JavaScript where I use Node.js module.export and require().
My issue is that module.export so far for me returns new object from a class.
If I make it so that all classes are only available requiring them from Singleton class and not require() - then would I guarantee that I will have one instance only?
Because if all Other classes import from Singleton - how should I import Singleton?
In php no matter how many instances of Singleton you have - each share static properties. So if you make the instance static then all Singleton's no matter in which files they are invoked have the same memory and perform the same action.
However I have no idea what is the case with JavaScript
I also have another approach - If I make let instance variable at the start of the file and check if its empty at the end and if it isn't I make another instance instance = new MyClass() and then module.export = instance. Would this give me the same result?
For example what I currently do
class MyClass {
//some logic here
}
module.export = new MyClass()
What I think of doing but no idea if it is good or it will work
if(!instance){
let instance = 1;
}
class MyClass {
//some logic here
}
if(instance === 1){
instance = new MyClass()
}
module.export = instance
Also to make matter more complicated I have seen several versions of implementations
Here -> https://www.sitepoint.com/javascript-design-patterns-singleton/
There are 3 examples -
1.Old JS ECMA 2015 way with functions
2.ECMA 2016 with object literal instead of class
3.With classes but again Object.freeze and const
Now..these versions make use of Object.freeze which I am not familiar with and const variables...which I am also not perfectly sure how they work.
To recap (TL;DR) - What I want to do is a way so that if I require a class in 10 files with require("MyClass") I won't get 10 instances but only 1.
Does my way work properly and are the examples in the link with Object.freeze() and the use of const good working examples?Do I need an anctual Singleton class to do the job? Because solutions so far don't include one. And If I need - how do I pass that Singleton around so it has only one instance?
Node.js modules are singletons by default.
All imports referring to the same file would refer to the same object in memory. You don't have to do anything special

Categories