javascript object variables and functions - javascript

First question
var obj = function(){
var a = 0;
this.b = 0;
}
Is there any difference in behaviour of a and b?
Second question
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')
Is there any difference in behaviour of f1 and f2

Question 1
var obj = function() {
var a = 0;
this.b = 0;
}
Within the function, you'll be able to access both variables, but in the case of
var x = new obj();
... you'll be able to access x.b, but not x.a.
Question 2
As your question is written at the moment, it is a syntax error. The following will work:
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')
... but that would be the same thing as writing:
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert(a)')
The difference here is obvious. f1 disregards the global variable x and alerts whatever is passed to it, while f2 also disregards the global variable x, and tries to look for a global variable a. This is probably not what you're trying to ask about.
What you probably want is something like this:
var x = 'a';
var f1 = function(){ alert(x) }
var f2 = new Function('alert(x)')
... or this:
var f1 = function(x){ alert(x) }
var f2 = new Function('x', 'alert(x)')
The difference between the two alternatives above is that the first always uses the global variable x, while the second never uses any global variable. The difference between f1 and f2, internally, in both examples, is none at all.
These are two ways of generating the exact same result. The only reason you'd ever want to use the f2 approach would be when generating the code in some dynamic manner that require string input for its definition. In general, try to avoid this practice.

var obj = function() { // function expression, while obj is created before head
// it's only assigned the anonymous function at runtime
var a = 0; // variable local to the scope of this function
this.b = 0; // sets a property on 'this'
}
Now what this is depends on how you're calling the function.
Also note the difference between function statements and expressions.
var x = 'a'; // string a, woah!
var f1 = function(x){ alert(x) } // another anonymous function expression
// Does not work
// 1. it's "Function"
// 2. It gets evaluated in the global scope (since it uses eval)
// 3. It searches for 'a' in the global scope
var f2 = new function('alert('+x+')') // function constructor
In short, never use the Function constructor, it will never inherit local scope and therefore you can't use closures with it etc.

First question:
var obj = function() {
var a = 0;
this.b = 0;
}
instance = new obj();
instance.showA = function() {
alert("this.a = " + this.a);
}
instance.showB = function() {
alert("this.b = " + this.b);
}
instance.showA(); // output undefined - local scope only, not even to methods.
instance.showB(); // output 0 - accessible in method
Paste this in your Firebug console and run to see the output and behavior for yourself.
Second question:
var f2 = new function('alert('+x+')');
This throws a syntax error in Firebug because the f should be capitalized. This is a case where a function is defined inside a string and evaluated. Here is a good example:
var x = 'a=3';
var f2 = new Function('alert('+x+')');
f2(); // outputs 3 because the x passed into the variable is evaluated and becomes nested inside the quotes prior to the alert command being fired.
Here is what the substitution process looks like:
1: x = "a=3";
2: 'alert(' + x + ')');
3: 'alert(' + 'a=3' + ')'); // x replaced with a=3
4: 'alert(a=3)';
5: 'alert(3);'
When function runs, alert(3) is fired. This can be used to execute other JavaScript pulled down from a remote server, although extreme care should be used for security reasons. When evaluating code that is nested in quotes, it helps to start from the inside and work your way up to the top level context. More information on dealing with nested quotes or embedded code can be found here: http://blog.opensourceopportunities.com/2007/10/nested-nested-quotes.html

Question 1: homework on scoping of variables (var b is local to the enclosing {} (local to the function in this case).
Question 2: Instead of using the Function constructor you could use eval? http://www.w3schools.com/jsref/jsref_eval.asp , as in
eval 'alert('+x+')';

Second question is VERY interesting. Only benchmarks can say the truth.
http://jsperf.com/function-vs-function/
http://jsperf.com/function-vs-function/1..8
http://jsperf.com/function-vs-constructor-vs-eval
http://jsperf.com/function-vs-constructor-vs-eval/1..5
It looks they are almost equal? I can see in modern browsers each variant is optimized enough
BUT BE AWARE OF RECREATING THE FUNCTION IN A LOOP!
http://jsperf.com/function-vs-function/2
Any wise comments?

Related

What is the meaning of function(){} in javascript?

Recently I came across a piece of code which was like this:
var noop = function(){};
options.ondragover = options.ondragover || noop;
options.ondragleave = options.ondragleave || noop;
options.ondrop = options.ondrop || noop;
options.onfilesdone = options.onfilesdone || noop;
This is a No Operation function
Discussed in detail in following link
https://disqus.com/home/discussion/chrislaughlin/noop_no_operation_function/oldest/
What is the JavaScript convention for no operation?
The code you posted declared an empty function with the name noop (No Operation) as an alternative to execute when certain conditions apply.
For example the code:
options.ondragover = options.ondragover || noop;
checks if options.ondragover exists and if not assigns the empty function to the variable.
It is simply a self executed function in which whatever you declare, you can execute the same.
It restrict the scope and make it private and hide the variables from global objects.
// Somewhere it is defined as global..
var x = 7;
// Your piece of code
var x = "roman" // Here, you override the value of x defined earlier.
alert(x); // "roman"
But when you use a closure which you have mentioned:
var x = 7;
// it doesn't affect/change the value of global x
(function (){ var x = "roman";})();
alert(x); // 7

Do I need to add a parameter to the function?

I am wondering if this way is correct:
var userInput = confirm('roll die?');
var rollDie = function() {
while(userInput) {
var dieSide = Math.floor(Math.random() * 6);
document.write('you rolled a ' + (dieSide + 1));
userInput = false;
}
}
rollDie(userInput);
Or do I need to write var rollDie = function(userInput) {
Javascript works with scopes. You call the function 'rollDie' from a scope where 'userInput' is a variable. The function 'rollDie' has its own scope. In your example there's no variable 'userInput' in the scope of the function rollDie. There for javascript is looking for the variable in an outer scope and find the variable. So your program is working but the code is not good code.
because you call the function rollDie with the parameter 'userInput' you should add 'userInput' as param to the function rollDie. var rollDie = function(userInput) {} It is always better the give a function all the params the function needs to execute. This prefents problems with the 'this' scope in javascript when you call the function in an other context and make it easier to refactor your code.
twoStrars is quicker :)
You should understand the difference and then choose for yourself.
Basically, you have these two patterns:
x as global variable:
var x = 1;
var f = function() {
console.log('x in f:', x);
x = 2;
}
console.log('x before f:', x);
f();
console.log('x after f:', x);
and x as argument:
var x = 1;
var f = function(x) {
console.log('x in f:', x);
x = 2;
}
console.log('x before f:', x);
f(x);
console.log('x after f:', x);
There two main differences:
if f uses a global variable, it is going to modify the global variable, whereas if it works with an argument, it does not affect any variables visible outside, i.e. the first code writes x after f: 2, whereas the second writes x after f: 1
if f uses a global variable, then it becomes less convenient to pass it different values. With an argument, you don't even need a global variable, you can call f(1); f(2); f(3456);. With global vaiables, you would accomplish the same with var x=1; f(); x=2; f(); x=3456; f();.
Instead of going more into details, I'll give you a link: Why are global variables evil?
Anyway, there are cases when global variables are good! I would make a global variable for a value which is constant and used by multiple functions (var GRAVITY = 9.81; or var BASE_URL = "https://stackoverflow.com/";)
This line:
rollDie(userInput);
…means you're trying to pass a value into your rollDie() method. This isn't strictly necessary because you have this variable declared globally:
var userInput = confirm('roll die?');
So, you could pass nothing in if you wanted, but if you want to write much cleaner code it's preferable to avoid having these global variables around as much as you can. The way you've written it – passing in a value to your function – is much nicer, so it's better to write var rollDie = function(userInput) {.

Why is non-static variable behaving like static?

function emergency() {
var ambulance = 100;
var callAmbulance = function() { alert(ambulance); }
ambulance++;
return callAmbulance;
}
var accident = emergency();
accident(); // alerts 101
I am referring to the variable 'ambulance'.
When I call accident(); it should call emergency() which should use the declared variable 'ambulance' [considering the global scope thing in javascript, still it could set the value to global] but its using old value 101 instead of setting again back to 100 - behaving more like static var.
What's the Explanation?
What you have there is called a closure. It means a function can access variables declared in outer functions (or in the global scope). It retains access even after the 'parent' function has returned. What you need to understand is that you don't get a copy. The changes performed on that variable are visible to your inner function, which in theory means you could have multiple functions sharing access to the same variable.
function f () {
var x = 0;
function a() { x += 1; }
function b() { x += 2; }
function show() { console.log(x); }
return {a:a, b:b, show:show};
}
var funcs = f();
funcs.a();
funcs.b();
funcs.show(); // 3
One thing to be aware of is that a subsequent call to f will create a new scope. This means a new x variable will be created (new a, b, show functions will be created as well).
var newFuncs = f();
newFuncs.a();
newFuncs.show(); // 1
funcs.a();
funcs.show(); // 4
So, how do you get a copy? Create a new scope.
function g () {
var x = 0;
var a;
(function (myLocal) {
a = function () { myLocal += 1; }
}(x));
x += 200;
return a;
}
JS only has pass-by-value so when you call the anonymous function, the xvariable's value will be copied into the myLocal parameter. Since a will always use the myLocal variable, not x, you can be certain that changes performed on the x variable will not affect your a function.
If, by any chance, you're coming from a PHP background you are probably used to do something like
use (&$message)
to allow modifications to be reflected in your function. In JS, this is happening by default.
You are creating a function definition which is not compiled at this time:
var callAmbulance = function() { alert(ambulance); }
And before you are sending it to the called function, you are incrementing the num:
ambulance++;
And then you are sending it to the called function:
return callAmbulance;
But whether you are sending it there or not, it doesn't matter. The below statement executes or compiles the function:
var accident = emergency();
And this takes in the current ambulance value which is 101 after the increment. This is an expected behaviour in creating function but not executing it. Please let me know, if you didn't understand this behaviour. I will explain it more clearly.

Javascript variable declarations at the head of a function

I've been told that javascript variables should all come before they are used in a function, such that:
function contrived() {
var myA, myB;
myA = 10;
myB = 20;
return myA + myB;
}
Is prefered over:
function furtherContrivance() {
var myA = 10;
var myB = 20;
return myA + myB;
}
Is this the case? And why is that?
I guess some people might prefer the former style because that's how it works inside. All local variables exist for the entire lifetime of the function, even if you use var to declare them in the middle of the function.
There's nothing wrong with declaring variables later in the function, syntax-wise, it might just be confusing as the variables will then exist before the line that declares them. Hence this function:
function bar() {
alert(foo); // Alerts "undefined". Not an error because the variable does exist.
var foo = 10;
alert(foo); // Alerts the value 10.
}
Is equivalent to this:
function bar() {
var foo;
alert(foo);
foo = 10;
alert(foo);
}
Another related fact is that nested function definitions (done using function foo() { ... }) will get moved to the top of the containing function as well, so they will be available even if the code that calls them comes before them.
Yes, the variable declaration should come at the top of the function:
function foo() {
var a, b;
}
However, initializing variables can be part of the declaration:
function foo() {
var a = 10, b = 20;
}
The reasoning behind declaring all variables at the top of the function where they are used is to avoid scope confusion.
Here is an example of bad code:
function foo() {
var b;
for (var i = 0; i < 5; i++) {
var a;
a = b = i;
setTimeout(function(){
console.log(a, b);
}, 1000);
}
}
If you execute the code, it will log 4, 4 5 times, rather than counting up. This is because only functions act as closures and introduce new scope. In JavaScript, any var declaration within a function gets executed at the beginning of the function.
This makes the above error much more visible:
function foo() {
var a, b, i;
for (i = 0; i < 5; i++) {
a = b = i;
setTimeout(function(){
console.log(a, b);
}, 1000);
}
}
There is no difference in this case between this two. I'd go with:
function furtherContrivance() {
var myA = 10,
myB = 20;
return myA + myB;
}
which is knows as single var pattern in javascript.
What you really need to take care of is defining your variables in the beginning of your functions. There is a thing in javascript called variables hoisting which means that variable definitions used in function "raise" on top. It's best described by an example:
var x = 'global'; // global (bounded to a global object which is window in browsers)
function func() {
alert(x); // undefined (you expected 'global', right?)
var x = 'local';
alert(x); // local
}
func();
what really happens is called (as I said) variables hoisting (definition of x raises on top), so the code above is actually the same as:
var x = 'global';
function func() {
var x; // definition of `x` raised on top (variables hoisting)
alert(x); // undefined in a local scope
x = 'local';
alert(x);
}
What a javscript interpreter does is it looks inside a function, gathers locally defined variables and raises them on top - this might be a good reason why you should use single var pattern.
In the example you give this is absolutely not the case. In a language like Javascript, it will be more of a developer preference, but it won't have any impact on the result.
Yes, place them at the top. It adds to code clarity.
Try this example:
var x = 1;
(function() {
x++;
alert( x ); // What will this alert show?
var x = 'done';
alert( x );
})();
Looks like it should alert 2, but it alerts NaN.
This is because the variable declaration is hoisted to the top, but the initialization stays in the same place.
So what is actually happening is:
var x = 1;
(function() {
var x;
x++;
alert( x ); // What will this alert show? NaN
x = 'done';
alert( x );
})();
...which makes the NaN expected.
For readability, it's definitely preferred.
However, Javascript "hoists" declarations. Hoisting means that vars and functions will be automatically moved to the top of their scope. This allows you to do things such as use a function before it's declared:
function myScope()
{
test();
function test()
{
//...
}
}
This can lead to some confusion, especially if variables within block scopes are declared. For example:
for(var i in foo)
{
var e = myFunc();
}
The declaration of e will be hoisted to the top of the closure, and e will be initialized to undefined. This allows for some interesting non-intuitive situations, such as:
if(!foo) //Will not throw reference error because foo is declared already
{
var foo = {};
}
So, regardless of how you declare your variables, they'll all get "moved up" to the top of the function anyway.
Hope this helps!

Why is setTimeout closing my variables twice?

I really don't get it
var f = function() { alert('f') };
var g = function() { alert('g') };
setTimeout(f, 2000);
var h = function() { f() };
f = g;
h();
Yeah, I know, this is the way it goes and I have to live with it, but I don't see any reason for this. Enlighten me.
PS. Check the subj btfore you answer, I'm doing Python, Ruby and .NET for a living and I've read Crockford. And I even know what the pointer is.
I really don't get it
Which bit?
That your code echoes g first?
When you say:
var h = function() { f() };
you are not taking the current value of f and remembering it, you're making a closure containing a reference to the variable f in the container scope (potentially global scope here).
Change the contents of the variable f after that definition, and the value seen by the function h, run afterwards, will change. It's identical to the situation with:
var a= 1;
function b() {
alert(a);
}
a= 2;
b(); // 2
That your code echoes f second?
setTimeout(f, 2000);
In this case you have set the timeout whilst the value of f is still the function that prints f. You have not made a reference to the variable f, only passed its current value. Changing the value of f afterwards doesn't change the value that was previously passed in; that remains the f-printing function.
(Value-versus-reference is something that most currently-popular programming languages obscure a bit, but at least in JavaScript, there's nothing special about the fact that some of the values in question are Function objects.)
1) setTimeout() takes a ptr to Function object as a first parameter.
Like you expect
function strlen(s) {
var f = function() { alert(s.length); };
return setTimeout(f, 1000);
var s1 = "xx";
strlen(s1);
s1 = "yyy";
to alert length of "xx", not of "yyy".
2) var h = function() { f() }; uses closure of var f. Object stored in f is "read" when h() is called.

Categories