javascript shadowing of variable throw an exception - javascript

The code:
(function() {
'use strict'; // es6 is on
var a = {
b: 3
};
(function() {
var a = a.b + 4;
console.log(a);
/** many lines where a is used */
})()
})()
I am expecting to get 7 in console, but I got an exception. I can understand why this happaned, and work-around will be tupically rename internal variable. But I'd like to avoid this, so is there another way to force this working without renaming variables? I am working in es6-compatible env, so might be in es6 there is something for such cases?

var a reserves the local variable name even before any of the function body is executed; it shadows it immediately, not only upon assignment. Imagine it executing like this:
var a = undefined;
a = a.b + 4;
As such, there's no way to get the parent scope's value of a without renaming the inner variable.
To work around this, you can pass the value into your IIFE:
var a = { b: 3 };
(function (_a) {
var a = _a.b + 4;
console.log(a);
})(a)
Or even use the fact that a function parameter already declares a new local variable name:
(function (a) {
a = a.b + 4;
console.log(a);
})(a)

First proposed varian not working for me as far as I have event-listeners there, not a IIFE, so I cannot pass any params, as far as closure parameters controlled by event emmiter.
But the implementation suggested me another solution, whitch is fit perfect:
(function(){
'use strict'; // es6 is on
var a = {b:3};
function getA(){
return a;
}
(function(){
var a = getA().b+4;
console.log(a);
/** many lines where a is used */
})()
})()

u override 'a' by defining ( local version "var a")... just say a = a.b+4; since you did define it, it wont become new global variable and will use the other...
also you are overriding object a with primitive 7 value, so in this self called method it's nothing, but in another place where you want to call it again, there won't be any object, and theres only a primitive left to you

Related

What is the difference between var foo=function() and function foo() [duplicate]

No matter whether I define the function after the variable
var a = 1;
function a() {};
typeof a // number
Or if I define the function before the variable
function a() {};
var a = 1;
typeof a // number
the final typeof result is always number
I found some explanation about execution context in http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/
Before executing the function code, create the execution context.
......
Scan the context for variable declarations:
If the variable name already exists in the variable object, do nothing and continue scanning.
but this does not seem to work.
So how can I explain it?
It's to do with JavaScript's variable hoisting. Try this instead:
var a = 1;
var a = function() {};
typeof a // function
You're implicitly declaring the variable multiple times by using the function statement 'function a() {};', which as noted by others hoists the variable and behaves unexpectedly due to the order that the browser registers the declarations.
Behind the scenes, this statement instantiates a function object and assigns the result to the variable passed as the function name (reference) but this is done before the explicit var declarations are performed, and so that overrides the implicit declaration. If you just do the following, it will work more intuitively:
var a = 1;
a = function(){};
console.log(typeof a); // function
This is a better option than the multiple var declaration in the other answer from a logical standpoint because (even though you can), it's not a good practice to declare the variable multiple times anyway.
To specifically answer the 'why' for this question: it's so that you can use these kinds of statements to define functions and use them in your explicit declarations, as in
var a = someFunction();
function someFunction(){ return 'someVal'; }
If the function statements weren't parsed and hoisted first, this wouldn't be possible.
As already mentioned, it has to do with the way JavaScript hoisting works. The main issue to notice is that JavaScript will hoist the complete function definition (along with the function body) up to the top, but keeps the variable initialization where it is (only the declaration is hoisted).
So if you write this:
var a = 1;
function a () {
}
it will be translated to:
var a;
function a() {
}
a = 1;
and if you write this:
function a () {
}
var a = 1;
it will be translated to:
function a () {
}
var a;
a = 1;
So no matter what you do, a = 1; will remain at the very bottom.
Please note that the above "translations" should be seen theoretically. JavaScript probably has a way to omit the var a; statement if there is already a function declaration with the same name. And there also might be a defined order (functions get hoisted before variables or the other way around). But all of this doesn't affect the outcome of the variable initialization being the only part that is NOT hoisted at all.

How does defining and immediately calling an anonymous function solve namespace problems?

I'm reading this page where it says:
myNameSpace = function(){
var current = null;
function init(){...}
function change(){...}
function verify(){...}
return{
init:init,
change:change
}
}();
Instead of returning the properties and methods I just return pointers
to them. This makes it easy to call functions and access variables
from other places without having to go through the myNameSpace name.
But I don't see how that's true. You still have to do myNameSpace.init() to call init. init() alone doesn't work.
Edit: it occurred to me later that maybe the author meant they were able to call init() without qualification inside the anonymous function. But what stumped me is that the author's previous examples were already able to do that. Specifically, in the immediately foregoing example:
myNameSpace = function(){
var current = null;
function verify(){...}
return{
init:function(){...}
change:function(){...}
}
}();
s/he defined init as s/he was returning it, instead of the example above where s/he defined init first then returned a pointer to it. But in that earlier example, within the anonymous function, if you wanted to call init() without having to do myNameSpace.init(), you already can. So how is the quoted example better?.
Can someone explain? Thanks.
The idea of using a function to clean up scope is, let's say you have a program that looks like this:
var number = 10;
var multiplier = 2;
var endingText = " days left!";
var string = (10 * 2) + endingText;
// string is "20 days left!"
This is an extremely contrived example, but hopefully it's obvious enough that this will declare four variables in the global scope, which is horrible. Let's say what you really want is string, but you still want to keep the other three variables around for whatever reason. You can put them inside an anonymous function, like so:
var string;
(function(){
var number = 10;
var multiplier = 2;
var endingText = " days left!";
string = (10 * 2) + endingText;
})();
// string is still "20 days left!"
Because variables are function scoped, number, multiplier and endingText are NOT declared in the global scope. However, you are still able to use them to get the result that you wanted in the first place.
By the way, you need to wrap parens around a function if you want to immediately invoke it. Also, you should not confuse this with namespacing. Namespacing in JavaScript is the idea of assigning meaningful values to the properties of objects.
var foo = {
hello: "goodbye",
frank: "bob"
};
hello and frank are declared in the foo namespace. That's all there is to it. The example that you posted uses both the namespacing concept and immediately invoking function concept to clean up variables.
The wording is a bit confusing. He meant to say:
Functions and variables can now be easily accessed without a namespace from inside the module
- in contrast to the object literal pattern or the previous example where he put the public methods directly on the exported object. Of course, from outside you always will need to access them as properties of the namespace object - that's the whole point of making it a namespace :-)
For an example, let's fill the functions with a some minimal code:
myNameSpace = function(){
var current = null;
function verify(…){…}
return {
init:function(el){
el.addEventListener("input", myNameSpace.change, false);
// ^^^^^^^^^^^^^^^^^^
},
change:function(){
if (!verify(this.value)) alert("wrong");
}
}
}();
myNameSpace.init(document.getElementById("testInput"));
vs
myNameSpace = function(){
var current = null;
function verify(…){…}
function change(){
if (!verify(this.value)) alert("wrong");
}
function init(el){
el.addEventListener("input", change, false);
// ^^^^^^
}
return {
init:init,
change:change
}
}();
myNameSpace.init(document.getElementById("testInput")); // no difference here
The differences may be minimal in this example, but when you have lots of functions mutually referencing each other it can matter. Also, you would know that all local, namespace-less functions belong to the current module, which massively increases maintainability when dealing with many different namespaces.

How do browsers handle multiple function declarations with the same name?

How do browsers handle multiple function declarations with the same name?
Specific test case is below - NOTE: I know this does not make sense to allow a server script to create more than one function declaration with the same name, but I am curious so please realize this before answering. This is purely for behavioral research.
Our CMS creates multiple instance of a single "widget" that is comprised of a
<div class="targetMeWithThis"></div>
and a
function startWidgetFunction() {
var param1 = $server.Variable1
var param2 = $server.Variable2
var param3 = $server.Variable3
}
When the server renders a page that has multiple instance of this widget on it, how does the browser decide which javascript function is used? Are there any browsers that actually create separate objects(functions) for each?
Thanks,
j
in javascript, (almost) everything is an object, including functions. that being said, overwriting a function definition works exactly the same as overwriting a variable.
var myFunc = function () {
alert('1');
};
myFunc(); // alerts '1'
var myFunc = function () {
alert('2');
};
myFunc(); // alerts '2'
http://jsfiddle.net/KgKgf/3/
Note that declaring a variable that is already declared is not a good practice and many code quality tools (jslint, jshint, etc) will warn you about it.
In this particular instance:
function = startWidgetFunction() {
var param1 = $server.Variable1
var param2 = $server.Variable2
var param3 = $server.Variable3
}
The browser will throw an error because function is a reserved keyword.
Given a different variable name, then you are just assigning a value to a (global) variable. The variable will be overwritten with a new (identical) function with each successive execution of the widget script.

How to organise my code in 'modules'?

I'm trying to wrap my head around organising my code. I have several modules within my project, which I'd like to organise.
The point is that all what has come to my mind doesn't work out. I'm currently thinking of four ideas:
Simple object - Is not useful due to scoping issues. Using this.a would work, but this has a different meaning depending on who called it so it's not reliable. For example, I once assigned a function to a WebSocket class, but all of a sudden this referred to the WebSocket instance when the function was called by a WebSocket event. I could use bind(foo) each time I call the function, but there must be another way I guess.
var foo = {
a: 3,
s: function() {
alert(a); // a doesn't exist in this scope
alert(this.a); // 'this' isn't always foo
alert(foo.a); // I would have to put 'foo.' before each variable
// reference, but I'm sure that's not the way to do it
}
};
Instance - a is not defined. Again, this isn't reliable.
var foo = function() {
this.a = 3;
this.s = function() {
alert(a);
};
};
var foo_instance = new foo();
foo_instance.a = 4;
foo_instance.s(); // Error: a is not defined
Closure with instance - Doesn't return anything; it stays undefined.
var foo = (function() {
this.a = 3;
this.s = function() {
alert(a);
};
})();
// foo === undefined
Closure with getter/setter - Works beautifully on Chrome, however IE doesn't support getters/setters.
var foo = (function() {
var a = 3;
return {
get a() { return a; },
set a(v) { a = v; },
s: function() {
alert(a); // Doesn't work in IE as getters/setters are
// not supported
}
};
})();
How would I effectively organise my modules, so that I can access the properties safely and in a cross-browser way?
Thanks.
3 is undefined because you are not returning anything. instead of assigning properties and methods to 'this', try this:
var foo = (function() {
var self = {};
self.someProperty = someValue;
self.someFunction = function () {
}
return self;
}());
foo will now return an object with the properties and methods defined. doing it this way you never have to wonder what 'this' is actually referring to.
It seems to me that you have no real understand of how this and closures work in JavaScript.
Please read up on both of these topics and also have a look at namespaces.
There are a ton of different ways how one could realize modules, but it doesn't make much sense to talk about it here unless you understand the basics, so please refer to my links for a in-depth explanation.
Your first code snippet uses a closure, and corresponds to a pattern that was made popular by the yui library. The second pattern corresponds to the notion of private, public and privileged members of an object.
I recommend that you read this staple article about javascript private members by Douglas Crockford, and go either with the first option or the second. They are semantically equivalent.
(The third and the forth snippets seem overly complex to me in comparison to the first two)

What are these lines doing?

I'm starting learning javascript for a project, I've found a script that does a part of what I need to do, I'd like to know how it works, both for me and in case it needs to be modified.
Originally it was used inside the page, now I've put it in a file on its own and does not work anymore, so I'm dividing it in parts, because I fail to get the whole thing.
Here is what bother me most for now:
1) Is this a declaration of a function? What is its name? How can it be invoked?
(function() {
//some code
})();
2) No clue of what is going on here
var VARIABLE = VARIABLE || {};
3) Am I defining the implementation of methodCall here? Something like overriding a method in Java?
VARIABLE.methodCall = function(parameter) {
console.log("parameter was: " + parameter);
};
Thank you in advance for your help.
1) creates an unnamed function and executes it. this is useful for creating a scope for local variables that are invisible outside the function. You don't need to invoke it aside from this, the '()' at the end does that for you.
2) if variable is null/undefined, set it to an empty object.
3) yes, that should work as you expect, you can call VARIABLE.methodCall(parameter)
in response to your comment, here is a common example
function foo (VARIABLE) {
var VARIABLE = VARIABLE || {};
}
(function() {
//some code
})();
simply runs //some code, but variables in it will not remain, since the function() { } block introduces a new inner scope.
function() { } notation is called a closure, it allows variables be functions. For example,
(function() { })() is a common JavaScript idiom. After the ), there is (), which invokes the expression before as function, so (callback || function(x) { return x; })(x) is allowed.
var a = function a() { return 1; }
var VARIABLE = VARIABLE || {}; uses the short-circuit OR, If VARIABLE is not defined, VARIABLE will be set to {}, an empty object. (otherwise, if VARIABLE exists, it will not change)
x = A || B means "If A evaluates to TRUE, x is A, otherwise, x is B.".
VARIABLE.methodCall, as you said, adds methodCall to VARIABLE, without erasing other values in VARIABLE

Categories