function setx(){
var x = 'foobary bazer'
showit();
}
function showit(){
console.log(x);
}
setx();
In the above example, the showit function fails because x is undefined. However, x is set and is available in memory (or so I thought) before showit is called. Why is this not the case?
Also, what's the best way to make this code work, so the console.log does indeed print foobary bazer to the console? I could get rid of the var and make it a global, but I don't think this is the best way as it can cause strange bugs.
You could pass the x variable to the showit function:
function setx(){
var x = 'foobary bazer'
showit(x);
}
function showit(x){
console.log(x);
}
setx();
Related
I just started to learn about javascript etc, and I get a project from my friend to take a look at it, and what I saw there is that they are using javascript functions all the time as a function expression, like this:
var a = function(Id) {
//Do something here
}
I could say like ok, they'r working like that and I'm gonna work like that also like robot, even if I don't understand why is that like that..
So I'm wondering what is this acctually, (in that code I posted above) is that function called "a" which is expecting 1 argument called "Id" in our case so I could call it on click of some button for example, or maybe this var a is acctually variable which is called "a" but it might be called as a function and acctually it is a javascript function?
This is little bit confusing me here, and I saw in this project that almost all javascrit functions are used like this, but is this a right approach or they should use named functions expression so it might look like this:
var a = function myFunction(Id) {
//Do something here
}
So what is this now ? I created function called myFunction which is expecting 1 argument called "Id" and it could be called on click by myFunction and also by calling "a" varible ? (if it is variable, or it is also function name or whatever)..
Thanks guys
Cheers
The key to understanding this is that, in JavaScript, functions are data, just like any other. So, if you are ok understanding this:
var x = 10;
If you were to try to get the value of x, you'd get 10:
console.log(x);
Then, understanding this isn't that much of a stretch:
var x = function(){
// do something
}
if you were to try to get the value here, you'd get the actual text of the function:
console.log(x); // function(){ // do something }
Since this last version retrieves a function, you could then invoke the function by simply appending () to the returned value, like this:
x(); // This would invoke the function stored in x
The alternative approach is with a "function declaration" which looks like this:
function x(){
// Do something
}
Here, there is no variable storing the function...x is the function and to invoke it, you'd do it directly:
x();
However, in JavaScript, all declarations are "hoisted" to the top of their enclosing scope, so this:
var x = function(){};
would cause the declaration of x to be hoisted, but not the value of x, while this:
function x(){ ...};
would cause the entire declaration to be hoisted.
The difference is that a declaration would allow you to invoke the function in code the precedes the actual declaration (since hoisting would cause the function to be read first) and with an expression, if you tried this, you would get an error stating that x is not a function.
Here's an example of this:
// Print the return value from runing the function who's name is "x".
// This will succeed even though we haven't even declared the function x yet becuase all
// declarations are hoisted to the top of their enclosing scope;
console.log(x());
// Print the return value from runing the function stored in the variable called "y":
// This will fail with an error stating that y is not a function because only the variable
// declaration (var y) is hoisted to the top of the enclosing scope, but not the value assigned to it.
console.log(y());
// This is a function "declaration" for a function who's name is "x"
function x(){
return "hello from function declaration x";
}
// This is a function expression being assigned as the data for a variable
var y = function(){
return "hello from function expression y";
}
Both are useful and often interchangeable, but hoisting causes differences in how (and when) you can call the function.
Is it possible to get a variable value inside a function without having to set it globally?
I know this is possible:
var testvalue;
function setTestValue(){
testvalue = 30;
}
if you console.log this outside the setTestValue function you will get: 30. Which is clear.
But is there also a possibility to have the same effect but without a global variable?
function setTestValue(){
var testvalue = 30;
}
console.log(testvalue); // will print undefined
The reason why I want this is because I can not change the Javascript file where this function is created. I can only read it and not write it so I need it a workaround.
PS. It might be that this question is already been aksed on stackoverflow but I could not really find it. So if there is, please provide the links to that question.Thanks!
This works (if you don't have var keyword before the variable in the function )
function foo() {
bar = 10; // variable without var comes under window scope so you can access them outside fuction
}
foo();// you have to call the function to set its value
alert(bar) // window.bar also gives 10
why not returning the var in the function:
function setTestValue(){
var testvalue;
do whatever to assign value
return testvalue;
}
console.log(setTestValue());
Is there any reason to think one of these methods is better or worse than the other?
function func1(x,y,z){
//do something with x,y,z
}
var x,y;
if (CONDITION){
var z;
}
// method1
if (z) {
func1(x,y,z);
}
the first method checks for z, then calls x,y,z to a function
function func2(x,y,z){
if (z){
//do something with x,y,z
}
}
var x,y;
if (CONDITION){
var z;
}
// method2
func2(x,y,z);
the second just calls the function with x,y,z knowing z is potentially undefined then checks z
edit ...
in the comments i was able to parse out what else i am asking...
... am i setting myself up for a bad time in the future should the interpreter choose to handle the undefined property differently... meaning is this an exploit, or is being able to send functions undefined variables a feature
if performance is your primary concern, as suggested by the title, I'd expect method 1 to be better. Testing z for truthiness is probably less expensive than making a function call, so you avoid the call when z is undefined. But if you want to be sure, go to jsperf.com and test it.
my concern is more with how javascript will deal with the undefineds
Consider the following (which is only visible in strict mode, hence IIFE pattern)
// A
(function () {
"use strict";
function foo(bar) {console.log('foobard');}
foo(z);
}()); // ReferenceError: z is not defined
// B
(function () {
"use strict";
var z;
function foo(bar) {console.log('foobard');}
foo(z);
}()); // foobard
// C
(function () {
"use strict";
if (false) {
var z;
}
function foo(bar) {console.log('foobard');}
foo(z);
}()); // foobard
You'll see that even if the var is inside the code block of an if that never gets it's contents executed, that var still gets applies to the names there (they'll be left undefined if they were set though). Therefore, worrying about how JavaScript will deal with the undefined is not a problem in your current pattern, which uses var for all the names before trying to reference them.
The parameter names of a function can be thought of as like another var line before the rest of the function's body, so if a parameter is named, even if undefined is passed of the function is invoked with fewer arguments than named parameters, they will not cause reference errors.
The additonnal function call should technically be more expensive in the second example, but I'm guessing that the difference is insignificant.
Also, there's nothing wrong in passing a potentially undefined value to a function. It all depends on your use cases. If it makes sense to encapsulate that undefined check in the function itself, let it be.
Finally, all variable declarations will be hoisted at the top of their scope even if they appear at other places in the code. Basically, as long as you are only declaring a variable, but not initializing it, there's no difference if you put the declaration in a if statement or not.
Let's say I have the following situation:
CLICK ME
and
var x = alert("test");
$('#trigger').click(function() {
x
});
Why is x firing on loading the page, and not while pressing the button? I know when placing the variable into the function it works, but I don't really get why!
var x = alert("test");
This will execute alert("test"), then assign the value of that expression to x. (alert doesn't return anything, so x will be set to undefined.)
Instead, use this code:
var x = function() {
alert("test");
}
$('#trigger').click(function() {
x(); //remember to actually call it!
});
Here are some better ways:
$('#trigger').click(x); //no need to wrap in function if it does not have
//any arguments
$('#trigger').on('click', x); //using on
In this line
var x = alert("test");
you actually call the function and put its return value into the variable x. As alert() has no return value besides undefined there is nothing really stored in x.
That's why the next time you access x it is still empty and does not contain a pointer to a function or something similar!
var x = alert("test"); will call the function alert("test") immediately, and then assign the return value to x.
To get the behavior you desire, you can wrap the call to alert in a function:
var x = function() {
alert("test");
}
And then to call it later, use parentheses (a parameter list):
$('#trigger').click(function() {
x();
});
Because alert("test") is a function which will show an alert message. Since you call this function not in the $('#trigger') area, it has nothing to do with the click functionality of the trigger but will be executed as soon as the script part is executed by your browser.
I have:
var f1 = function(a){
alert(a)
}
var f2 = function(data, method){
method(data) // the problem is here,
// the method f1 is not called. Is there a way to call that method f1?
// the method f1 might not be in this scope, the method f1 can
// be in a class or like this...
}
f2(a, f1)
The question is: Is there a way to call that f1 from f2, from the passed method?
thanks
EDIT: this is some code I write here, but I miss to set the a. anyway the value of is 5.
EDIT: yes! it was just a tiny stupid error in my original code that missed up, i set the value after calling the method. hehe
Try running your Javascript through a debugger. You'll get a message like a is not defined because the call f2(a, f1) is trying to pass a variable named a but you haven't declared one. However, this code will work:
var f1 = function(a){
alert(a);
}
var f2 = function(data, method){
method(data);
}
var a = 'this is a';
f2(a, f1); // results in alert('this is a')
Yes, this should work fine. In your example however, a is undefined when you make the invocation. Make sure you define it; this could be the reason it's not working.
In other words, changing your example to:
f2(42, f1);
Will alert the number 42.