The problem is not about the "new" keyword in the "problematic aspect", but more in the practical approach.
I'm fighting a bit with my C# and JavaScript mindsets when defining classes (ES2015). In C# I use dependency injection to inject the dependencies in the class' constructor. In JavaScript, due to its prototypical nature, I learned there's no need for you to inject a dependency into the constructor; you can safely use import, because you can later mock the method later for Unit Testing.
Therefore many modules "just work" out of the box, without the need to instantiate them. (Node modules are examples)
I've been using TypeScript in my project. As you know, you can use Interfaces with it. What I’ve been doing as of now, is setting the interface as a property and then setting the class in question to it.
To better illustrate what I'm saying, imagine I have class A:
class A implements Letter {
hello(){
console.log("Hello World");
}
}
And its interface "Letter":
interface Letter {
hello(): void
}
Then I have a class "Book" which uses the approach I'm saying.
export class Book{
letter : Letter
constructor(){
this.letter = A;
}
Read(){
console.log("We're about to read this chapter!");
this.letter.hello();
}
}
And it can be used like this:
import {Book} from './book'
let book = new Book();
book.Read();
On the other hand, I have "BookVersionJs" who doesn't use any interface and implements it directly:
import {A} from './a.ts';
export class BookVersionJs{
Read(){
console.log("We're about to read this chapter!");
A.Hello();
}
}
Then we can use it like this:
import {BookVersionJs} from './BookVersionJs'
BookVersionJs.Read();
But I loose the "theoretical" loose coupling that the interfaces give me. Theoretical because JavaScript could overwrite them with a prototype.
There's a difference in practicality. Which should I aim for in TypeScript/JavaScript? Or is it a matter of opinion?
A.hello(), asAis a class, not an instance. You need to either donew A().hello()or make thehellomethod static. - Nitzan Tomer