Bug while Create multiple instances of an object in JavaScript - javascript

I want to create multiple instances of an object in Javascript. I know that using Object.create(obj) or using new ObjConstructor(); or using ObjFactory(); (thanks to #WiktorZychla) will let me create different instances.
I understand the differences from this question, and both of them do work when the Object Constructor is coded in a certain way.
However when I use return in my object constructor factory to implement private variables using closure, the two instances created seem to be the same.
This is my object constructor function:
var obj3 = function () {
variable3 = "Hello World";
function3_private = function () {
return variable3;
};
return {
function3_get : function () {
return variable3;
},
function3_set : function (v) {
variable3 = v;
},
function3_print : function () {
return function3_private();
}
};
};
How do I use this constructor to create two different instances? Or should I make changes in the constructor to achieve the same?
Please suggest best practices if my code is not following any.
Here's the fiddle: http://jsfiddle.net/GcD9n/

Your private variables are actually global, because you've missed out the keyword var. This means that any objects you make are all using and modifying the same instance of variable3 and function3_private, and calling
function3_private();
works and prints out the value of variable3.

Related

What is it called when a function behaves like a class but doesn't use the class keyword, nor "new" keyword (in Javascript)?

I looked through the suggested links but can't seem to find the term for a function that acts like a class (is it a constructor function? doesn't have that keyword either!) but doesn't use the new keyword, nor class.
I've used both this example's pattern and the class pattern in my code but realized I don't know how to describe the former.
I think this is in part because I learned JS recently, have seen class thrown around a lot, yet looking through my notes of not-ES5,6,7,2018,2020 etc. can't seem to find what var aCounter = counterFunction() is called for the life of me.
I know what the result of what i'm doing is, how to work it, etc. but why no constructor(), no new, no class, no etc.prototype.etc pattern? I know i'm creating an object, calling a method existing Within the object, etc. I believe i'm beginning to ramble.
Lo, an example
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
which is || can be instantiated (?) like so:
let aCounter = counterFunction() // where i'm getting tripped up
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
I know this is rambling, but help! I think it will make things click more inside once this lexical puzzle piece is put into position!
That is just a function that returns an object literal, which does not act like a class (doesn't have a prototype, and as you pointed out, does not use new, etc).
The functions that are set as the properties of this object (which you store in aCounter) seem to act like class methods because they keep the reference to the variable val alive, but this is not because val is in any way associated with the actual object.
Instead, those functions are closures that keep the reference to the variable alive for as long as the functions themselves are alive.
So to answer your question, what you have described doesn't have any name in particular. It's just a function that returns an object.
Edit:
You asked why there is no constructor() or related syntax in this pattern. Object literals in JavaScript are just mappings of names and values:
const x = { a: 3, b: "hello" };
You do not need a constructor for this, and there is no prototype because it was not instantiated using a constructor. On the other hand, classes and constructor functions are templates for objects that will be created later, and those objects do have a prototype and a constructor because the template contains logic that initializes the object.
class A
{
constructor()
{
this.a = new Date();
this.b = this.a.toString(); // you cannot do this in an object literal
}
}
const x = new A();
Question:
What is it called when a function behaves like a class but doesn't use the class keyword, nor “new” keyword (in Javascript)?
Answer:
It's called a "factory function".
Factory functions usually return a object of a consistent type but are not instances of the factory function itself. Returned objects would rarely inherit from the factory function's prototype property, and calling the factory function does not require new before the function being called.
What you showed there is nothing special. It is just a normal function that has a closure.
Though, you can call it as a type of design pattern.
It looks similar to Revealing Module Pattern where you can separate public property and private property.
Below is an example (not a good one tho):
var counter = function(){
var privateCount = 0;
var privateHistory = [];
return {
getVal: function(){
return privateCount;
},
increment: function(){
privateCount++;
privateHistory.push('+');
return this.getVal();
},
decrement: function(){
privateCount--;
privateHistory.push('-');
return this.getVal();
},
publicHistory: function(){
return privateHistory;
}
}
}
var aCounter = counter();
console.log(aCounter.increment());
console.log(aCounter.decrement());
console.log(aCounter.publicHistory());
Here, you can't directly manipulate the private variables that I don't expose to you.
You can only manipulate those private variables only if I expose the function to you. In this case, the .increment() and .decrement() function.
As you can see, there is no class, no prototype, no constructor.
I can see how you may get tripped up, let's go through your code and explore what's going on:
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
At this point counterFunction is a variable that points to a function, it's essentially a function name. The ()=>{...} is the function body or function definition and within it the return statement shows that it returns an unnamed object with two property methods.
let aCounter = counterFunction() // where i'm getting tripped up
This is calling your previously defined function, which again returns the object with two methods and assigns it to the variable aCounter. If you did the same thing again for a variable called bCounter they would hold two independent objects.
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
Because the method inside the object refers to a variable outside the scope of the object, but within the function body, a closure is created so that the state of val may be retained. Because the variable is in use, the browser's cleanup process skips over it, so the function is still kept in memory, I believe until the object is destroyed and the function's variable is no longer used.

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.

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

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]

Creating functions for an object in javascript

As far as I can tell, there are two main ways of creating functions for an object in javascript. They are:
Method A, make it in the constructor:
function MyObject() {
this.myFunc1 = function() {
...
}
this.myFunc2 = function() {
...
}
...
}
Method B, add it to the prototype:
function MyObject() {
...
}
MyObject.prototype.myFunc1 = function() {
...
}
MyObject.prototype.myFunc2 = function() {
....
}
Obviously if you did:
MyObject.myFunc3 = function() {
....
}
then myFunc3 would become associated with MyObject itself, and not any new objects created with the new keyword. For clarity, we'll call it method C, even though it doesn't work for creating new objects with the new keyword.
So, I would like to know what the differences between the two are. As far as I can tell they have the same effect logically, even if what's happening on the machine is different.
If I were to guess I would say that the only real difference is when you're defining them in the constructor like in method A, it creates a whole new function object for each object that's created, and Method B only keeps one copy of it (in MyObject), that it refers to any time it's called. if this is the case, why would you do it one way over the other. Otherwise, what is the difference between method A and method B.
The advantage of giving a separate function to each object is that you can close over variables in the constructor, essentially allowing for "private data".
function MyObject(a,b) {
var n = a + b; //private variable
this.myFunc1 = function() {
console.log(n);
}
};
vs
function MyObject(a,b) {
this.n = a + b; //public variable
}
MyObject.prototype.myFunc1 = function() {
console.log(this.n);
}
Whether this is a good idea or not depends on who you ask. My personal stance is reserving constructor functions for when I actually use the prototype, as in option #2 and using plain functions (say, make_my_object(a,b)) when using closures, as in option #1.
The idea is that you can modify the prototype at any time and all objects of the type (even those created before the modification) will inherit the changes. This is because, as you mentioned, the prototype is not copied with every new instance.
The MyObject in method A is an instance for inner functions.
You cannot call its functions explicitly outside of it unless object (you can call it a class) was instantiated.
Assume this:
MyObject.MyFunc1(); // will not work
var obj = new MyObject();
obj.MyFunc1(); // will work
so this is the same as any class in other languages. Describing usefulness of classes and their usages goes beyond that question though.
Also to notice:
function MyObject() {
var privateVar = "foo";
this.publicProperty = "bar";
// public function
this.publicFunc = function() {
...
}
// private function
function privateFunc () {
...
}
}
For method B it's same as with method A, the only difference is prototyping is a style of creating object. Some use prototypes for readability or out of preference.
The main advantage in prototypes is that you can extend existing object without touching the original source. You need to be careful with that though.
(as example Prototype framework)
For method C you can call them a static functions. As you said they can be called explicitly by referring through object like:
MyObject.MyFunc1();
So which one to use depends on situation you're handling.

Javascript closures -- what is the difference between these

EDIT
With the number of responses saying "you can make private things!" below, I'm going to add this to the top as well:
I know you can emulate private variables within a closure. That is not what I'm asking. I'm asking, given the two examples below where I'm "exporting" EVERYTHING from the closure, what is the fundamental difference between these two examples.
Given these two methods of creating objects/methods:
var test = {}
test = (function(){
var a_method = function(print_me){
return "hello "+print_me;
}
return {print_me: a_method};
})();
test.print_me2 = function(print_me2){
return "hello "+print_me2;
}
test.print_me('world');
>>> returns "hello world"
test.print_me2('world');
>>> returns "hello world"
I understand that the first method allows for private variables (which as a python developer at heart i don't really care to use), but both seem rather equivilent to me, only the first one looks "cooler" (as in all the big javascript people seem to be doing it that way) and the second way looks very passé.
So, like, what is the difference?
I've looked through the closure questions here -- most of them center around what or why do you use them; I understand their utility, I just want to know why you'd do the first over the second and what benefits it has.
I'd prefer hard evidence over conjecture -- not looking for a "this is how the cool kids are doing it" or "i heard that mozilla does better memory usage when you use a closure", but rather qualitative evidence towards one being 'better' than the other.
The difference between the methods is the anonymous function wrapper that creates a closure, but also that the first method replaces the entire object while the second method just sets a property in the existing method.
There are different ways of adding methods to an object. You can put them there when you create the object:
var test = {
print_me: function(text) { return "hello " + text; }
};
You can add a method as a property to an existing object:
var test = {};
test.print_me = function(text) { return "hello " + text; };
You can make a constructor function, and add methods to its prototype:
function Test() {}
Test.prototype.print_me = function(text) { return "hello " + text; };
var test = new Test();
As Javascript has a prototype based object model, the last one is how methods were intended to be created. The other ways are just possible because an object property can have a function as value.
You can use a function wrapper around any code where you want local variables, so you can do that with the second way of setting the property:
test.print_me2 = (function(){
var method = function(print_me2) {
return "hello "+print_me2;
}
return method;
})();
In the first example, the closure is used to keep local variables out of the global scope.
var thisIsGlobal = 2;
var test = (function () {
var thisIsLocal = 3;
return function () {
return thisIsLocal;
};
}());
What you get is a function test which when invoked returns the value of the local variable thisIsLocal. There is no way to change the value of the variable. You can be look at it as to a private variable.
The first method you present (an anonymous function which is executed immediately) keeps your program out of the global scope. Within that private scope you can decide what properties you want to expose as your API:
(function(win){
var a, b, c = 1;
function init(){
return aa(b);
}
function exit(){
if(cc()){
return a;
}
}
function aa(){
}
function bb(){
}
function cc(){
}
win.myProgram = {init: init,
exit: exit };
})(window);
// We now have access to your API from within the global namespace:
myProgram.init();
//etc

Categories

Resources