Your observations are correct. C++ is a complicated beast, and the new
keyword was used to distinguish between something that needed delete
later and something that would be automatically reclaimed. In Java and C#, they dropped the delete
keyword because the garbage collector would take care of it for you.
The problem then is why did they keep the new
keyword? Without talking to the people who wrote the language it's kind of difficult to answer. My best guesses are listed below:
- It was semantically correct. If you were familiar with C++, you knew that the
new
keyword creates an object on the heap. So, why change expected behavior?
- It calls attention to the fact that you are instantiating an object rather than calling a method. With Microsoft code style recommendations, method names start with capital letters so there can be confusion.
Ruby is somewhere in between Python and Java/C# in it's use of new
. Basically you instantiate an object like this:
f = Foo.new()
It's not a keyword, it's a static method for the class. What that means is that if you want a singleton, you can override the default implementation of new()
to return the same instance every time. It's not necessarily recommended, but it's possible.
Encapsulation is really tricky, and probably not worth the effort in JavaScript. A method that works, and does everything you would wish (private fields, access to the superclass and private methods) would be this (probably very ugly and improvable) solution:
function SomeClass() {
var parent = SomeSuperClass(),
somePrivateVar;
return Object.create(parent, {
somePrivateVar: {
get: function() {
return somePrivateVar;
},
set: function(value) {
somePrivateVar = value;
}
},
doSomething: {
value: function(data) {
someHelperFunction.call(this, data);
}
}
});
}
function someHelperFunction(data) {
this.someMethod(data);
}
This sort of works, allows you to have private fields and methods and inheritance as one would expect it. However, I don't like it - but I like it the best of all possibilities you have in pure JavaScript.
If I had to start a new project with a lot of JavaScript, I probably would have a closer look at TypeScript. It improves JavaScript where necessary (IMHO), gives you static typing, inheritance, encapsulation and everything.. But is just JavaScript, after all.
Now, is it worth it? I think there are two important things to consider. Encapsulation probably helps you at development time, but certainly doesn't at runtime. I think you have to decide; Either no encapsulation and better performance, or encapsulation, not-so-beautiful code, probably a better design but some overhead at runtime.
Best Answer
Those aren't static methods they are on the prototype. Instances of foo would be able to call static methods by just doing this.statics.method. True statics would be applied to just foo itself. It is also cleaner than putting logic in the constructor to handle statics.
The framework that we write in allows statics this way, it is a nice way to keep enums and constants. It also gets around problems that happen when instance sharing is not needed and non primatives are placed on prototype, which for some reason happens all of the time on SO. Problems arise during inheritance though since static methods defined this way won't be inherited. The inheritance problem mostly arises after due to parent classes having methods that do
this.class.statics.staticFn
if the class is inherited from those methods won't work but that can easily be fixed.update
Having to invoke a function to get at the statics and having logic in the constructor to have it handle and know about it having statics is bad in my opinion. The user has to know that the statics need to be accesses by invoking a function and the constructor needs to know that it has statics and to handle the case where the new operator is not used.
Problems can arise when instances don't know that they are modifying statics. In this case lets replace the name statics with config.