javascript function object method - javascript

Hey im new to javascript and i stumbled upon this code in javascript. I dont understand how can be methods increment and print defined inside function. Does that mean that create is an object?
function create() {
var counter = 0;
return {
increment: function () {
counter++;
},
print: function () {
console.log(counter);
}
}
}
var c = create();
c.increment();
c.print(); // 1

The function "create()" returns an object. The object it returns has two properties, "increment" and "decrement", both of which have functions as values. The functions operate on the variable "counter" defined in "create()".
Each call to "create()" instantiates a new context called a "closure". The context encloses a new copy of the "counter" variable. The objects returned from calls to "create()" thus have access to their own private "counter" instance.

The keyword for you is closure.
Closures in javascript are quite covered, e.g. in How do JavaScript closures work?.

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.

why does a variable need to be created in this closure

Hi I have the following closure
function createCounter() {
var numberOfCalls = 0;
return function() {
return ++numberOfCalls;
}
}
var fn = createCounter();
fn()
fn()
And I believe I understand about scope and the fact that the inner function keep the outer function's values after the outer one has returned.
What I don't understand is why I need to create this variable
var fn = createCounter()
and then invoke the variable fn() instead of initially invoking createCounter()
I saw that createCounter() just returns 'function()' instead of what has to be '1' and I don't understand why.
Thanks for the help. Read many tutorials still having problems with understanding this.
Please note: the question's isn't about how to make the code more eloquent or better, it's about understanding of what's been done
When createCounter is called it returns another function and that returned function is not evaluated unless you do so. Remember, in JavaScript functions are objects too. They can be the return value of a function.
So when you do this:
var fn = createCounter();
fn references only the function returned by createCounterfunction and not its evaluated value.
If you need to evaluate the function returned by createCounter try something like:
createCounter()();
This evaluates the returned function.
If you call it like this it will always return the same value as it creates a new numberOfCalls variable every time you call createCounter.
In Javascript, functions are objects which can be passed to and returned by other functions, as any other objects (e.g. a string, a number...).
So doing:
function foo(arg) { /* ... */ }
var someObject = new String("Hello");
foo(someObject);
is similar as:
function foo(arg) { /* ... */ }
var someFunction = new Function("Hello", "...");
foo(someFunction);
A function may thus return another function, which can be invoked as needed.
function foo() {
return new Function(...);
}
var functionReturnedByCallingFoo = foo();
functionReturnedByCallingFoo(); // can be invoked
functionReturnedByCallingFoo(); // and again
functionReturnedByCallingFoo(); // and again
Now, functions are almost never declared using the Function constructor, but rather with constructs named "function declarations" or "function expressions" - basically, the way we have defined the function "foo" in the previous examples, with a function signature and a function body delimited by curly brackets.
In such cases, the statements inside of the function body can read and write variables declared outside of the function itself ("free variables"), and not only variables declared within the function, as per the rules of lexical scoping. This is what we call a closure.
So in your case, the createCounter() function, when invoked, defines a local variable named "numberOfCalls", then return a function - the body of which having access to that variable. Executing the returned function changes the value of the variable, at each invocation, as it would for any "global" variable (i.e. variables declared in outer scopes).
Executing the createCounter() function many times would simply, each time, recreate a new local variable "numberOfCalls", initialize it to zero, and return a new function object having access to that variable.

Why cannot use function name to retrieve property in JavaScript?

The following is the code
function add() {
var counter = 0;
this.num = 0;
function plus (){ return counter +=1;}
plus();
return counter;
}
console.log(add.num); //outputs :undefined
Function name can be treated as reference of a function object, so the num is the property of add function object, the outputs could have been 0. But the result is not like so, why?
If i change the code to:
function add() {
var counter = 0;
this.num = 0;
function plus (){ return counter +=1;}
plus();
return counter;
}
var obj = new add();
console.log(obj.num); //outputs : 0
it works correctly. Can anyone explain this? Many many many thanks.
this refers to current instance of your function. until you create a new instance using new add() this will refer to window object.
add.num will check if add has a property named num. Which is false because add refers to a function definition not an instance/object of function.
function add() {
var counter = 0;
this.num = 0;
function plus (){ return counter +=1;}
plus();
return counter;
}
console.log(add.num); //outputs :undefined because add=function(){};
while in another case, when you create object using new it returns you a javascript object having all the public properties.
///obj=Object{ num : 0};
function add() {
var counter = 0;
this.num = 0;
function plus (){ return counter +=1;}
plus();
return counter;
}
var obj = new add();
console.log(obj.num); //outputs : 0 because obj is {num:0}
Fiddle to play: http://jsfiddle.net/ZpVt9/76/
It will help to read-up on this in JavaScript: MDN
When you do new add(), the interpreter creates a new JavaScript Object/Hash and binds it to this variable in the function. So this is valid inside the scope of the function.
When you don't do a new you are calling the function without a context, so this is undefined in such cases (in 'use strict' mode).
You can explicitly pass a context to Functions using Function.apply/Function.call/Function.bind
this inside a function points to different object depending on how the function is called:
If the function is called in the global context (outside any function) this points to global object (which is window if the script is executed within a browser).
console.log(this === window) will output true.
If this is referred inside a function, then it depends if we have set strict mode.
If the code is in strict mode then this will be undefined unless we explicitly assign it to something.
If the code is not in strict mode then this will point to global object. (Which is again window if script is executed in a browser).
If function is used as constructor to make new objects then this points to the new object being made.
If function is used as object method then this points to the object method is called on.
More explanation with examples here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Every function is an object in JavaScript. But as you can see from above explanation none of the ways this points to function object itself from the same function body. Thus the only way you can set function's property is by directly assigning it to the function without using this.
There is another way of adding a property to functions. This is a very bad idea of doing so as adding any property this way will reflect in all functions used. Every function is linked to Function.prototype object. Thus adding any property in this object will get reflected in all functions.
Function.prototype.someProperty = 1;
//now try accessing it via any function object
console.log(add.someProperty); //should print 1 to console.
"num" is not a property of the "add" function is a property of the object created and returned by that function if you want to add num to your add function you need to do
add.prototype.num=0;
and remove it from your objects definition

Why do new invocations of this function create new scope chains and a new private variables?

If we have this basic function (and its closures):
function counter(){
var n = 0;
return {
count: function() {return n++},
reset: function() {n = 0}
};
}
Is this what's happening in memory? (basically a pointer to a function object and its scope chain)
(source: geraldleroy.com)
Is the above diagram correct? If so, I'm not understanding why these two lines of code create two new scope chains and new private variables:
var c = counter();
var d = counter();
It seems like both c and d would refer to the original function object and would use its scope chain.
I'm a little confused and would appreciate any insight on this that anyone can offer.
Thanks!
Scope chains do not really apply here. Look up 'execution context' and 'activation object' to understand what is happening when a function is invoked. See the brief summary of these concepts at http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
Your return statement includes an object literal. So each time counter is invoked a new object is created in memory.
Java script is 'lexically scoped'. This means that they run in the scope in which they are defined, not the scope from which they are executed. You define 2 variables definitions that get the object returned by the function, hence you get 2 scopes.
Basically what is happening here, is that when you call function counter() - new private counter - n is created and an object which contains two functions that can access that private variable, so it can not be disposed of until your returned object is not destroyed. Also everything that is within your function is not bound to anything, meaning if your object that you are returning would be defined somewhere else and you would only return it's reference - this function would create new counter n and your object would now refer to new counter n, but the old one would be disposed of.

Please explan this javascript function definition and their best use (Module Pattern)

What type of function is the following and which is their best use?
var f = function (){
var a = 0;
return {
f1 : function(){
},
f2 : function(param){
}
};
}();
I tried to convert it to:
var f = {
a : 0,
f1: function (){
},
f2: function (param){
}
}
But seems does not works the same way.
It's just a plain old function that is invoked immediately, and returns an object which is then referenced by f.
The functions referenced by object returned retain their ability to reference the a variable.
No code outside that immediately invoked function can reference a so it enjoys some protection since you control exactly what happens to a via the functions you exported.
This pattern is sometimes called a module pattern.
Regarding your updated question, it doesn't work the same because a is now a publicly available property of the object.
For the functions to reference it, they'll either do:
f.a;
or if the function will be called from the f object, they can do:
this.a;
Like this:
var f = {
a : 0,
f1: function (){
alert( this.a );
},
f2: function (param){
this.a = param;
}
}
f.f2( 123 );
f.f1(); // alerts 123
But the key thing is that a is publicly available. Any code that has access to f can access f.a and therefore make changes to it without using your f1 and f2 functions.
That's the beauty of the first code. You get to control exactly what happens to a.
Basically that creates a "class" - JS doesn't have classes so a class is basically a function such as your function f.
The interesting thing about the code you posted is that it creates a private variable a and two public functions f1 and f2. They are public because the constructor - the outer function - returns them.
This is a common pattern for organising and encapsulating JS code.
You can read more about it here
It's a simple function to create and return an object. It's immediately executed, and its result is saved to your variable f
It first declares a local (or private) variable a, visible only withing the scope of the function. Then it constructs an object which has members f1 and f2, both of which are functions. Since this return object is declared within the same scope that a is declared, both f1 and f2 will have access to a.
Your conversion simply creates a single object. Where before you had a function that would create endless objects, you now have a single object, and no more. I'm not sure exactly why it doesn't work, but one major difference is that a is now visible to the world, where before it was private to the return object.

Categories

Resources