It is my first question here, so apologise if I missed anything.
Perhaps solution for my problem could be find, but I have no idea how to search for it, no clues about how to ask it in google or something.
I have a following problem, let's have such constructor
const Product = function (color) {
let self = {};
self.setColor = function(colorToSet) {
color = colorToSet;
}
self.getColor = function() {
return color;
}
return self;
};
now when I tried to use:
let self = {}, color;
in chrome console I received error that color has been already declared, so I removed color field and after this (with a snippet code above), magic happened that I cannot explain.
let's say I will write something like this:
let a = Product("Yello");
a.getColor() ----> "Yellow"
a.setColor("red");
a.getColor() ----> "red";
If it returns color for the first time, then it has to be declared somehow.
I do not know where is color field, I cannot find it in the object nor in its prototype, nowhere actually. Could you explain me why ? and where it is ?
I know that I can just declare color for example:
self.color = color;
But I want to know how is working the example above and what happened with color field.
Also could you tell me if I can use let with declaring values from parameters in such way ?
const Product = function (color) {
let self = {}, color;
self.setColor = function(colorToSet) {
color = colorToSet;
}
self.getColor = function() {
return color;
}
return self;
};
It's not magic :) this behaviour happens because:
You're returning an object that has two methods which are
closures.
When a function is defined within another function and then a reference to it stored somewhere (in this case when you returned then attached to the self variable) then a closure is created.
In short, a function has access to variables created inside its definition block and to its enclosing environment (your constructor definition).
As a result it will have access to any variables in the enclosing scope at the time the parent was invoked.
This includes any parameters of that enclosing Product function, i.e. the color argument you define.
So:
You invoke Product passing in a colour and store this in a variable a. At this point a will contain a reference to an object whose properties include two methods getColor and setColor
since the latter methods are closures, they have access to their enclosing scope at the time Product (their enclosing function environment was called). Since Product was invoked with a color, a variable called color local to Product but also available to any closures will be created and assigned the value passed in. In this case color will be equal to 'Yellow
Since both methods were defined in the same scope at the same time, they both have access to this variable, producing the results you experienced.
It has to be declared somehow. I do not know where is color field, I cannot find it in the object nor in its prototype, nowhere actually. Could you explain me why? and where it is?
It is the variable that you declared by using it as a parameter name. That parameter variable is scoped to the Product function, i.e. can be used anywhere inside it. It's the reason why you get an "already declared" error if you try to use let color.
Your methods can access (read/write) this local variable because they are closures.
Related
I know I can define properties on functions, which can then be accessed from within the function. Right now, the only syntax I can work out involves two statements. Is there a more concise way to express the following:
function myFunc() {
// do some work
}
myFunc.myProp = 0;
I'm not looking for a solution that is fewer characters -- this isn't code golf. I'm asking something more along the lines of "are there different patterns of function declaration that have this other desirable merit?" This is almost about ways to use closures (because I suspect the answer lies there).
Thanks!
Especially if you want to access properties of the function from inside the function itself, you're better off doing this:
var theFunction = function() {
function theRealFunction() {
// the code
if (theRealFunction.something == "not whatever")
// do something
// more code
}
theRealFunction.something = "whatever";
return theRealFunction;
}();
What that does is wrap your function declaration up in an anonymous function. The problem with accessing function properties via the function name is that it must do that by finding the function's name in the surrounding scope. That's kind-of icky, but at least this way it involves a scope that's essentially private. It'll work whether or not the resulting function (returned as the return value of the anonymous function) is assigned to a different variable, passed to a function as a handler function, etc.
This really, really all depends. If you're looking for private variables, then you can easily return a function from the function -- an inner-function will contain access to its parent's scope.
var outer_function = (function () {
var private_var = "secret",
public_var = "public",
inner_function = function () {
return private_var;
};
inner_function.public_var = public_var;
return inner_function;
}());
outer_function now equals inner_function, with the benefit of having access to the enclosed data. Any properties attached to the inner (in the way you did) will now be accessible as public properties of outer.
To this end, you can return, say, a constructor for a class, with public-static properties, with the enclosed vars acting as private-static properties, shared between every instance of the "class" you build.
Not exactly the answer to your question, but if you ever want to read up some different design patterns that can be used when defining a javascript function, this is one of the best articles I've ever read on the topic:
http://www.klauskomenda.com/code/javascript-programming-patterns/
Apologies for what must seem like a very stupid question.
I'm currently working through codecadamy, and this is throwing me off:
var greeting = function(name) {
name = "sausage";
console.log(name);
};
greeting(name);
I understand that I will get sausage
Why don't I just write var name = "sausage";? What is the difference?
The name in function(name) is a parameter. That is, it is used to pass data into the function. But, parameters are local variables. Assigning a value to name inside the function is a little strange though. I would assume you want to do something like this:
var greeting = function(name) {
console.log(name);
};
greeting("sausage");
In this version of the code you are passing the value "sausage" into the function via the parameter name. This is useful because you can call the function many times and each time the function may print a different value depending on what you pass.
In your function definition:
function(name) {
name is already being declared. It is a parameter for the function. If you want to change name, you can, but you don't need to use var to declare it as a new variable.
On the other hand, if you wanted to add, say, flavor, you should use var then since it is not already defined.
var flavor = 'savory';
In this case, flavor is a local variable and name is a parameter. A parameter is a type of local variable that is declared with the function declaration, but a local variable isn't necessarily a parameter because it may be declared elsewhere in the function.
Parameters are a general programming construct and are necessary to do anything sane in the world programming (dealing with masses of global variables is not sane.
var name would declare a new variable in the function scope that would override the value of the parameter name, so you would not be able to use the parameter anymore.
The CodeAcadamy example is a bit strange because it's rare that you want to override a parameter's value -- especially before you have used it.
Technically, there is no real difference.
Without giving you the huge background here, you have to understand that in the underlaying implementation, a special object (not a javascript object, on C/C++ level) is formed which is called Activation Object (ES3) or Lexical Environment Record (ES5).
However, this hash / object structure is used to store
variables declared by var
formal parameters
function declarations
As you can see, both var variables and parameters are stored in this structure.
This construct is most likely used to have somewhat default values for not passed in arguments. In a real world example, this would probably look more like
var greeting = function( name ) {
name = name || 'default';
console.log( name );
};
greeting('john'); // 'john'
greeting(); // 'default'
I'm quite still confused with the concept of closure in JavaScript. I get the point that closure is the ability of the inner function to access the variable created within its mother function after the mother function has returned.
But I'm still confused why do we have to create inner function to protect the local variable if we could just create a variable inside the function?
We need to create an inner function so that the variables in the outer function have some existence after the outer function returns.
Consider a simple function:
function f() {
var x = 0;
return ++x; // x=1
} // Once the function has exited then "x" no longer exists.
Note that the variable "x" is only "active" (alive, existent) when control of the program flows from the start of the "f()" function to the end of it. But if we enclose "x" in an inner function then x will live as long as the inner function does:
function g() {
var x = 0;
return function() {
// Now "x" will live for as long as this function.
return ++x;
}
};
var counter = g();
counter(); // => 1
counter(); // => 2
counter(); // => 3
Now when we call "g()" we get another function, and "x" is active for as long as that function is referenced by a variable.
Why use closure?
(function(){
var current_page = 1;
function previous_page() {
current_page--;
// update interface
}
function next_page() {
current_page++;
// update interface
}
// a bit of jQuery, ok?
$('#previous').click(previous_page);
$('#next').click(next_page);
})();
Look: we have no global variables, not even any function defined in the global space... yet, we have attached a behaviour to the click events of "#previous" and "#next" buttons for a paging feature. How would you do it without closures? How would you do it defining current_page variable inside the functions?
You just answered your question, the inner function protects it's variable. jsFiddle
(function outer(){
var foo = 'bar';
function inner(){
var foo = 'OMG NO!';
}
alert(foo);//alerts 'bar'
})()
FROM MDN CLOSURES
why to use:
A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to object oriented programming, where objects allow us to associate some data (the object's properties) with one or more methods.
when not to use
It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task as it will negatively affect script performance both in terms of processing speed and memory consumption.
For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called the methods would get reassigned (that is, for every object creation).
The reason you need to create the inner function with scoped variables is object oriented encapsulation. It's essentially private variables.
The variables are "closed over".
// constructor function
var myObject = function(message) {
// private - scope is function level. It's CLOSED OVER the the inner function (closure).
// not delcared as a JSON property so not visible externally
var value = 0;
// constructor returns JSON object with public methods
// always constructed from the myObject var so it always hands back the same instance
// of the public methods
return {
// nested functions have access to outer function variables.
increment: function (inc) {
value ++;
},
getValue: function() {
return value;
},
// the inner function even has access to the outer function's args!
getMessage: message
}
};
Look at the return statement. It returns the public interface - some methods that have access to the private variable because they are in the inner function. It's using JavaScripts function scoped variable to create object oriented encapsulation.
After that I can it like:
var obj = myObject('Hello World');
obj.increment();
obj.increment();
console.log(obj.getValue());
console.log(obj.getMessage);
// should be undefined
console.log(obj.value);
Note at this point the consumer does not have access to the protected/encapsulated value or message.
Now, here's the kicker - the object is mutable so the caller can add methods or even replace methods. So, you would think someone could add a method that exposes the internals. But, they can't because of function scope (closure - they're closed over). Only the nested function has access to the variables of the outer function. So, if the caller adds a method to return the internal, they can't get access and it will be undefined.
The code above outputs:
2
Hello World
undefined
As a side note, I'm running the javascript with node.js
Here's a good blog post on the module pattern using closures:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
The point is that the variable is shared between the two functions. If you declared the variable in the inner function, then the outer function would not be able to access it, so it wouldn't be shared.
If you declared the variable in the inner function, then each call to the inner function would create a new variable: any modifications made by a previous call are lost.
But if the variable is declared in the outer function then multiple calls to the inner function would see the same variable and one call would see the modifications of a previous call so long as they were both scoped to the same version of the outer function.
There are alot of right answers out there about closures, but it always seems to get really technical while many people asking might be looking for a higher level simple explanation first.
I like to think of it like a car. When you drive a car, there are many many complex processes going on, but the average person doesn't need to know about these on an average day. Think of all those complexities as "private" variables hidden away by closures which makes the gas pedal, the break, the shifter, the steering wheel, and so on a lot easier to use.
So what is the purpose of a closure? To hide away all the complex variables and such to make a script much more usable. If you had to worry about every variable in a script everytime you wanted to use any function in the script, well that could quickly get very difficult. YAY CLOSURES!
I am trying to have some const global variables which I can use in the javascript and I came out with this code and picking up from some answers referred in SO. But it seems that I have a little mistake somewhere which I couldn't spot. Can someone help me with this?
in testQuery.js
(function (window, undefined) {
var testQuery = function(obj) {
if (!(this instanceof testQuery)) {
return new testQuery(obj);
}
}
var MYGLOBALS = function() {
var globals = {
foo : "bar",
batz : "blah"
}
return {
getValue : function(s) {
return globals[s];
}
}
}();
window.testQuery = testQuery;
}) (window);
and in the html javascript tag i have this line of code.
in testQuery.html file
<html>
<head>
<script src="testQuery.js"></script>
<script>
function onClick() {
alert(MYGLOBALS.getValue("foo"));
}
</script>
</head>
<body>
<input type="button" onclick="onClick()">
</body>
</html>
The variable MYGLOBALS is local to your scoping function (the big outermost function that has no name), so it can only be accessed from within that function.
I'm not sure what you mean by "...in the html javascript tag..." but if the alert you've quoted is outside that scoping function, MYGLOBALS is out of scope for it.
Update: The thing about JavaScript scope is that it's much simpler than people think it is. Variables declared with var are private to the scope (function or global; JavaScript has no block-level scope so just {} doesn't do it) in which they're declared, and sub-scopes of that scope (e.g., functions declared or define within it). And scope is entirely lexical — that is, it is what you see in the source code, not dictated by some other runtime structure. They don't pop out of that scope unless you see code somewhere explicitly making that happen, as with your window.testQuery = testQuery; line, which explicitly makes testQuery a property on window and therefore a global variable. (And even then, it's not that the variable has popped out of the scope, just that you've created a new property referring to the same thing which is more broadly-accessible.)
Update 2: Re your comment
Actually what I am trying to do is to create something like what you would see when you are doing programming in other language where there will be a final static integer which you can put into the parameters fields on the functions you call. is there a better way of doing it? For example, in visual basic its something like me.background = Color.YELLOW. what I want is to have a static variable which will represent that YELLOW color.
JavaScript doesn't have user-defined constants, and doesn't have enums. (Update: Both of those things may change with ES6.) What you do instead is define an object with the properties, e.g.:
var COLORS = {
RED: "#FF0000",
BLUE: "#0000FF",
// ...
GREEN: "#00FF00"
};
Those aren't constants, there's nothing to keep anyone from assigning to COLORS.RED except your telling them not to.
(Update: In ES5, we can make those properties constant using Object.defineProperties, like this:
var COLORS = Object.defineProperties({}, {
RED: {value: "#FF0000"},
BLUE: {value: "#0000FF"},
// ...
GREEN: {value: "#00FF00"}
});
When you define a property that way, by default it's not writable.)
For what you're doing, you probably want the module pattern, where you have a single global symbol whose value is an object, and everything else is properties on that object:
(function() {
var mod;
// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = mod = {};
// Colors
mod.COLORS = {
RED: "#FF0000",
BLUE: "#0000FF",
// ...
GREEN: "#00FF00"
};
mod.testQuery = MyModule_testQuery;
function MyModule_testQuery() {
// Do something
}
})();
alert(MyModule.COLORS.RED); // #FF0000
MyModule.testQuery(); // Do something
Or if you prefer, that testQuery function could be defined like this:
mod.testQuery = function() {
// Do something
};
...but then the function is anonymous, and I'm not a fan of anonymous functions. (Note that there's nothing special about the name MyModule_testQuery, that's purely my naming convention.)
Somewhat off topic:
Regarding this line where we're publishing our global symbol above:
// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = mod = {};
Note that that is very specific to browser environments. We could make it applicable to any JavaScript environment with a trivial change:
// Create the global, and also give ourselves a convenient alias for it (`mod`)
this.MyModule = mod = {};
That works because we're the ones who call the outermost scoping function, and so we know that we're not calling it with any particular this value (this in JavaScript — unlike some other languages — is determined entirely by how a function is called, not where or how it's defined). So since we know we're not using any special this value, we know that it will be the global object, because that's how JavaScript works. And the global object is window on web browsers (effectively; technically window is a property on the global object that refers back to itself).
http://jsfiddle.net/vXu7m/1/
Some syntactic cleanup, and attaching you MYGLOBALS to the window object should do what you want.
When we have code like:
function a(){
var x =0;
this.add=function(){
alert(x++);
}
}
var test = new a();
test.add(); // alert 0
test.add(); // alert 1
test.add(); // alert 2
How does this work?
Doesn't that the value of 'x' in a() should be 'gone' as soon as test = new a() is complete? The stack contains x should also be gone as well, right? Or, does javascript always keep all the stacks ever created in case they will be referenced in future? But that wouldn't be nice, would it...?
The word you're looking for is “closure”.
Creating a function inside another function gives the inner function a (hidden) reference to the local scope in which the outer function was running.
As long as you keep a copy of your test, that has an explicit reference to the add function, and that function has an implicit reference to the scope created when calling the a constructor-function. That scope has an explicit reference to x, and any other local variables defined in the function. (That includes the this value and the constructor's arguments — though you can't access them from inside add as that function's own this/arguments are shadowing them.)
When you let go of test, the JavaScript interpreter can let go of x, because there's no way to get a reference back to that variable.
What you're seeing is the effect of a closure. The function being defined within the other function gets access to all of the variables and such in scope where it is — even after the outer function returns. More here, but basically, the variables (and arguments) in the function all exist as properties on an object (called the "variable object") related to that function call. Because the function you've bound to this.add is defined within that context, it has an enduring reference to that object, preventing the object from being garbage-collected, which means that that function can continue to access those properties (e.g., the variables and arguments to the function).
You normally hear people saying that the function closes over the x variable, but it's more complex (and interesting) than that. It's the access to the variable object that endures. This has implications. For instance:
function foo() {
var bigarray;
var x;
bigarray = /* create a massive array consuming memory */;
document.getElementById('foo').addEventListener('click', function() {
++x;
alert(x);
});
}
At first glance, we see that the click handler only ever uses x. So it only has a reference to x, right?
Wrong, the reference is to the variable object, which contains x and bigarray. So bigarray's contents will stick around as well, even though the function doesn't use them. This isn't a problem (and it's frequently useful), but it emphasizes the underlying mechanism. (And if you really don't need bigarray's contents within the click handler, you might want to do bigarray = undefined; before returning from foo just so the contents are released.)