Can you name an instance the same as its constructor name? - javascript

Can you name an instance the same as its constructor name?
var myFunc = new function myFunc(){};
?
As it seems, this replaces the Function Object with the new instance... which means this is a good Singleton.
I haven't seen anyone using this, so I guess, there are downsides to this that I am unaware of...
Any thoughts?

YES...
However, it does look weird that you're creating a named function but never refer to it by name.
The more common pattern(s) I've seen are
function MyClass(){
this.val = 5;
};
MyClass.prototype.getValue = function() {
return this.val;
}
MyClass = new MyClass();
But when people do that I wonder why they don't just use a literal object
var MyClass = {
val: 5,
getValue: function() {
return this.val;
}
}
And I would even prefer to use the module pattern here
var MyClass = (function(){
var val = 5;
return {
getValue: function() {
return val;
}
};
})();
Disclaimer
Now whether the singleton pattern should be used, that's another question (to which the answer is NO if you care about testing, dependency management, maintainability, readability)
http://accu.org/index.php/journals/337
Why implementing a Singleton pattern in Java code is (sometimes) considered an anti-pattern in Java world?

As it seems, this replaces the Function Object with the new instance
No, it does not replace anything. The name of a function expression (that's what you have) is only accessible inside the function itself, not outside of it. It would be exactly the same as if you omit the name:
var myFunc = new function(){};
In general, if you don't want certain symbols accessible, just don't make them global. Define those symbols inside a function and just return whatever you want to make accessible, e.g:
var myobj = (function() {
function Foo() {};
// do whatever
return new Foo();
}());
However, if you just want to create a single object, it is often easier to use an object literal:
var myobj = {};
There is no reason to use a constructor function if you only want to create a single instance from it. If you want to establish inheritance, you can use Object.create [MDN]

Related

Putting methods on Object.getPrototypeOf(this)

See this class definition:
function MyClass (property) {
// Private
var privateVariable;
var privateMethod = function () {};
// Public
this.publicProperty = property;
this.publicPrivilegedMethodOnInstance = function () {};
Object.getPrototypeOf(this).publicPrivilegedMethodOnPrototype = function () {};
}
MyClass.prototype.publicMethod = function () {};
var myMyClass = new MyClass('foo');
The method publicPrivilegedMethodOnPrototype is public, yet can access private variables (which publicMethod) can’t. It’s also shared on the prototype, which publicPrivilegedMethodOnInstance is not.
Any downsides of defining publicPrivilegedMethodOnPrototype like this? I guess ECMAScript 5 is a requirement, and that the method is redefined every time MyClass is instantiated.
It's a very bad idea.
So you create many objects but as you're assigning the property to the prototype of all of them, at some point even functions which weren't meant to access certain values will do it... This is very odd.
A given prototype function is meant to access properties from the object whose own the prototype using this:
function X() {
this.text = "hello world";
}
X.prototype.doStuff() {
console.log(this.text);
};
Thus, avoid that anti-pattern. It makes no sense. My advise is that you need to deal with the absense of access modifiers in JavaScript instead of blindly looking for a workaround.

Difference between using a module pattern and instantiating new objects

I'm trying to restructure some javascript and I'm confused about the module pattern.
One way I have now is to simply declare a class containing all the functionality for a component like so
var Foo = function(){
this.Bar = {};
...
}
and create a new instance for use in the component. But I've also read about the module pattern and I can't see what the benefit would be compared to what I have since it appears to do about the same, just in a more complicated way. Maybe I just haven't encountered the case that makes it a better choice.
For example, a pattern like this:
var module = (function () {
// private variables and functions
var foo = 'bar';
// constructor
var module = function () {
};
// prototype
module.prototype = {
constructor: module,
something: function () {
}
};
// return module
return module;
})();
var my_module = new module();
doesn't appear significantly different from what I already had. What does this pattern let me do that I can't do the other way?
The key difference between the two is in the first example, you can't have private variables and functions if you want to work with the prototype. You can have private variables and functions, but only if your public properties and methods are created in the constructor by attaching them to this.
Example 1 with a private variable and function:
var Foo = function(){
var privateVar = "priv";
function privateFunction(){
console.log(privateVar);
}
this.publicProperty = 1;
this.publicFunction = function(){
console.log(privateVar);
}
}
The above is no problem if you don't want to use the prototype. However, if you do then there is no way to have private variables, without the new scope that your second example benefits from.
As you can see, you have to include everything within the constructor, whereas the second example you can leave the constructor just for initialising variables.
Conversely, the prototype methods in the second example are out of scope of the constructor, so they can't use any variables of functions within the constructor. All functions and variables that the prototype methods need must be declared in the outer closure scope.

Is it possible to add a constructor afterwards to an existing object? Is it meaningful?

Assuming there is a construct like that:
var Foo = {
someVar : 13,
someMessage : function () {
return "Hello";
}
};
I would like to add a construct outside of Foo to initalize someVar, so that following action would be possible:
var foo = new Foo (someVar);
I know the so called constructor invocation pattern (which I am actually not looking for but I've also here a question):
var Foo = function (someVar) {
this.someVar = someVar;
};
Foo.prototype.getSomeVar = function () {
return this.someVar;
};
var foo = new Foo ("some content");
console.log (foo.getSomeVar());
How can I add a property (someSecondVar) to Foo outside of Foo?
attaching a property is simple and can be done just like how you would attach a function to a construct:
Foo.prototype.someSecondVar = 0;
Foo.prototype.someThirdVar = "blah";
You can not instantiate object literal (comparison to other programming languages does not work here) in JavaScript unfortunately. It would be (maybe) a good idea, you could save some paperwork.
"Constructor invocation pattern" is a try in the right direction and you can simply add a property in this way:
Foo.prototype.someSecondVar = "what ever";
EDIT: You can not instantiate an object literal but you can make a new object and select the object, that should be its prototype (from Douglas Crockford):
Please study the following example:
var Person = {
"name" : "Max",
"age" : 30,
"children" : ["Susi", "Ben"]
};
Object.create = function (obj) {
var F = function () {};
F.prototype = obj;
return new F();
};
var Person2 = Object.create(Person);
Person2.name = "John";
Person2.age = 40;
Person2.children = ["Sara"];
Person.city = "New York";
console.log(Person2);
The output shows 2 important things:
The new object has all properties from the old one
If you add some properties to old object afterwards, the newones will get it automatically
What you want to do can be accomplished by using the .prototype of the object. Keep in mind, altering the prototype is computationally expensive usually and it also alters all objects that are instances of the object who's prototype you're altering, which may or may not be what you want.
You can add a property the way Husman mentions in his answer.
If you really need to instantiate it and can't just place a value there with a custom function, look into getters and setters: MDN
by using getters/setters, you can add some conditional for whatever case you need the value of the property for, thus emulating a constructur, in a way.
Overall however, I'd advise rethinking your code structure. These kinds of approaches generally can only be justified if what you want to do is quite complicated and are usually not necessary if you re-think your code.

Use of Init in javascript

Is there a specific use of init() method in javascript?
Consider
var obj = {
init: function(){
return "Hello World";
},
foo: function(){
return "Foo";
}
}
Is there a difference between obj.init() v/s obj.foo()? Is it just a naming convention? Renaming init to main() has no effect. I realize that init is a naming convention that is used to place all of the initialization code for the object. Is that correct?
init has no special meaning in Javascript. It is just an ordinary valid identifier, like foo.
It is often used instead of initialize, because most developers know that init means initialize, and it's shorter to type. If you prefer, there would be no problems with using initialize instead.
Init has no special meaning in javascript. If you're looking for a constructor, in javascript you can call a function with the new keyword. This will create a 'new' this object and pass it to that function as the scope.
function obj(){
this.foo = function() {
return "foo";
}
}
var o = new obj(); // o.foo() returns "foo"
a lot of time people will use an init function to encapsulate the constructor functionality. It is common practice to also write an init function for setting up a plain object when you're not using a constructor.

What are the differences between to create a "classic" class in javascript and JSON notation?

In Javascript there are several ways to create a class. But I have some doubts between these two ways:
function MyClass(){
this.myFun = function(){
// do stuff
}
}
and
var MyClass = {
myFun: function(){
// do stuff
}
}
The only difference is that the second way I can't to use a new operator? So the Json notation allows me to create a static class or singleton class, right?
The code you showed doesn't create classes. The notion of class is unknown to javascript, it uses prototypal inheritance. Now as to your code. The first piece of code represents a constructor function. From it, you can derive instances - javascript objects with shared properties -, using the keyword new.
function MyConstructor(name){
this.name = name || 'no name yet';
this.myFun = function(){
alert(this.name);
}
}
var instanceA = new MyConstructor('Webman')
,instanceB = new MyConstructor;
instanceA.myFun(); //=> 'Webman'
instanceB.myFun(); //=> 'no name yet'
The second piece of code creates a single javascript object. It uses an object literal notation.
var mySingleObject = {
myFun: function(){
alert('I am single');
}
};
mySingleObject.myFun(); //=> 'I am single'
The Mozilla Developer Network has a nice page, where things are explained in more detail.
Creating an object using an object literal, everything is public. Using a constructor, it is possible to have private variables, using javascripts closure mechanism:
function MyConstructor(name){
var namestring = 'the name property of this instance is: '+
(name || 'not set');
this.myFun = function(){
alert(namestring);
}
}
A few minor corrections. In JS these is only class simulation - the language lacks a formalised notion of actual classes. And your JSON notation is actually a JS object - that would be invalid JSON as you currently have it.
You do not have to use an object to simulate the singleton pattern. You can do this with constructors like so:
function Animal() {
if (Animal.instance) return Animal.instance;
Animal.instance = this;
/* constructor code here */
}
var animal_a = new Animal(); //constructor runs
var animal_b = new Animal(); //singleton instance returns
console.log(animal_a === animal_b); //true
Also, with your first approach, note it is better to put reusable, inheritable code on the prototype rather than declaring separately for each instance. This is faster, and also more sensible - the prototype is the place for this.
function Animal() {}
Animal.prototype.method = function() {}
This also avoids the problem of distinguishing between own and inherited properties, which, in your code, could not be done because you're declaring methods separately on each instance.
[EDIT - in response to the OP's question about private members]
Private members are implemented as local variables/functions, which means they are inaccessible outside the current closure.
function Animal() {
var private_var = 'foo';
function private_method = function() { alert('bar'); };
}
Public methods may (if you choose) be able to get or set them - but in order that they themselves have access to these private members, they would have to be declared inside the constructor, not separately, outside it.
function Animal() {
var private_var = 'foo';
function private_method = function() { alert('bar'); };
if (!Animal.prototype.public_method)
Animal.prototype.public_method = function() {
alert(private_var);
};
}
var dog = new Animal();
dog.public_method(); //'foo'
There are no classes in javascript, javascript is a prototypal language.
There is no way to explain this faster than watching: Crockford on JavaScript - Chapter 2: And Then There Was JavaScript for a simple CORRECT explanation by the father of json (amongst other things).
Good Luck!!

Categories

Resources