Passing global javascript array to another function - javascript

I have a small javascript which has a globally declared array. The values for that array are filled inside the function foo() as given below:
<html>
<head></head>
<body>
<script>
var myArray = [];
function foo() {
var j = 5;
for (var i = 0; i < j; i++) {
myArray.push(i+1);
}
}
function bar() {
alert(myArray);
}
</script>
</body>
</html>
When I trying to access that array in another javascript function bar(), the values of array are null. How can I fix this?

you have defined the function but never called it.
Try calling foo() and bar() like this
var myArray = [];
function foo() {
var j = 5;
for (var i = 0; i < j; i++) {
myArray.push(i+1);
}
}
function bar() {
alert(myArray);
}
foo();
bar();
JSFiddle

If you are going to call bar() directly then.
<script>
function foo(myArray) {
var j = 5;
for (var i = 0; i < j; i++) {
myArray.push(i+1);
}
return myArray;
}
function bar()
{
alert(foo([]));
}
bar();
// or
alert(foo([]));
</script>
Try to avoid as many global variables as you can,

Related

Javascript - get value of variable without declaring a second one

var i = 5;
test();
function test() {
let i = 3;
alert(i);
}
The above example alerts the value of the second variable that is 3. How can I code it to alert the value of the first while keeping the two with the same name? Thanks
Use outside scope
var i = 5;
test();
function test() {
// let i = 3;
alert(i);
}
or make it a function parameter
// var i = 5;
test(5);
function test(i) {
// let i = 3;
alert(i);
}
Use it's global namespace, i.e. the global window variable.
var i = 5;
test();
function test() {
let i = 3;
alert(window.i);
}
What you probably want is this:
var i = 5;
test(i);
function test(x) {
alert(x);
}

Javascript Objects and variable scope

Can someone explain this to me?
This works:
function Pin() { };
function Pi() { };
function User() { };
var PiArray = [];
var PinArray;
for (var i = 0; i < 2; i++) {
PiArray[i] = new Pi();
PiArray[i].Name = '';
PiArray[i].PinArray = [];
for (var j = 0; j < 25; j++) {
PiArray[i].PinArray[j] = new Pin();
PiArray[i].PinArray[j].Number = j + 2;
PiArray[i].PinArray[j].PulseWidth = 0;
PiArray[i].PinArray[j].PulseFrenquency = 0;
PiArray[i].PinArray[j].Dirtybit = false;
};
}
/* Output is
[{"Name":"","PinArray":[{"Number":2,"PulseWidth":0,"PulseFrenquency":0,"Dirtybit":false},{"Number":3,"PulseWidth":0,"PulseFrenquency":0,"Dirtybit":false},{"Number":4,"PulseWidth":0,"PulseFrenquency":0,"Dirtybit":false},
etc.
*/
But I cannot figure out how to make this into an object, the scope of the variables do not behave as I expect.
this is what an instance of what I tried:
function Pin() { };
function Pi() { };
var User = (function () {
PiArray = [];
function User() {
var PinArray;
for (var i = 0; i < 2; i++) {
PiArray[i]= new Pi();
PiArray[i].Name = '';
PiArray[i].PinArray = [];
for (var j = 0; j < 25; j++) {
PiArray[i].PinArray[j] = new Pin();
PiArray[i].PinArray[j].Number = j + 2;
PiArray[i].PinArray[j].PulseWidth = 0;
PiArray[i].PinArray[j].PulseFrenquency = 0;
PiArray[i].PinArray[j].Dirtybit = false;
};
}
}
console.log(JSON.stringify(PiArray));
return User;
})();
new User();
and the output is:
[ ]
I don't understand why?
Your console.log(JSON.stringify(PiArray)); shows an empty array in the second case because at the time it runs, you've have not called the function User() yet. The IIFE just defines the function User() and then returns it. It does not actually call it.
Your later code new User() does call it, but that's after your console.log() has already executed.
Move the console.log() to the end of your User() function definition (but inside the function) and you will see the expected value.
function Pin() { };
function Pi() { };
var User = (function () {
PiArray = [];
function User() {
var PinArray;
for (var i = 0; i < 2; i++) {
PiArray[i]= new Pi();
PiArray[i].Name = '';
PiArray[i].PinArray = [];
for (var j = 0; j < 25; j++) {
PiArray[i].PinArray[j] = new Pin();
PiArray[i].PinArray[j].Number = j + 2;
PiArray[i].PinArray[j].PulseWidth = 0;
PiArray[i].PinArray[j].PulseFrenquency = 0;
PiArray[i].PinArray[j].Dirtybit = false;
};
}
console.log(JSON.stringify(PiArray));
}
return User;
})();
new User();
FYI, it is unclear what you are trying to accomplish with this structure because PiArray is only reachable from your constructor. Once the constructor has been called, no other code can reach it or use it. Plus all calls to the constructor will modify the same PiArray. PiArray in this context works like a class static (as the term is used in other languages). It's a common variable shared by all instances of the class, but not accessible outside the code for the object itself.
If you had other methods on the User object, then they could also access PiArray and it might make more sense to have it.
You can create an instance that has a different array stored in it like this:
var MyObj = function(data) {
// assign a copy of the passed-in array as instance data
// You don't have to make a copy - you could just assign in incoming array
this.data = data.slice(0);
}
var x = new MyObj([1,2,3]);
var y = new MyObj([9,8,7]);
console.log(x.data); // [1,2,3]
console.log(y.data); // [9,8,7]

Take the value of a function

I have this function:
x = function() {
for (i = 0; i < window.document.querySelectorAll('.btn[href*="/p"]').length; i++) {
return window.document.querySelectorAll('.abtk[href*="/url"]')[i].href;
}
};
I would like to have in x the results of the function and now the function in self when I test it in console in Chrome. How can I do it?
Make it Immediate invoke function, so the function gets executes immediately after defining. Below is the syntax for that
x = (function() {
for (i = 0; i < window.document.querySelectorAll('.btn[href*="/p"]').length; i++) {
return window.document.querySelectorAll('.abtk[href*="/url"]')[i].href;
}
})();
Observe () at the end of function declaration.

How can I prevent this infinite loop, if I don’t know content of function

How can I isolate my variable from variable in this function, if his creator forgot for var keyword?
for (var i = 0; i < 4; i++)
{
test();
}
function test()
{
i = 0;
}
Same idea than previous answer using scoping but a better way would be to use IIFE:
(function () {
for (var i = 0; i < 4; i++) {
test();
}
})();
http://jsfiddle.net/8vBc5/
put your for loop in a separated scope:
in a function.
function test(){
i = 0;
}
function trial(){
for (var i = 0; i < 4; i++){
test();
}
}
trial();
That way only the code and functions inside the trial function can access variables declared at that level.

Closures in Javascript: assigning local variable doesn't work

Just when I thought I understood closures...
The following code snippet:
function f() {
var a = [];
var i;
for (i = 0; i < 3; i++) {
a[i] = function () {
var x = i;
return x;
}
}
return a;
}
var a = f();
console.log(a[0]());
console.log(a[1]());
console.log(a[2]());
prints out 3, 3, 3. I don't understand why. I'm copying the value of 'i' to the local variable x, so there should be three x's: x0=0, x1=1. x2=2. How are all of them reading the final value of i?
Your problem is caused by each a[i] being, in fact, a closure. They all share the same i, which is evaluated when each a[i] is called, not when the loop executes. You need to create each closure with a separate context. For instance:
function f() {
var a = [];
var i;
for (i = 0; i < 3; i++) {
a[i] = makeClosure(i);
}
return a;
}
function makeClosure(i) {
return function () {
var x = i;
return x;
}
}
Even though the value of i changes in your for loop, it's still the same i variable. You need to shadow i in that scope and effectively pass it by value:
for (var i = 0; i < 3; i++) {
(function(x) {
a[x] = function() {
return x;
}
})(i);
}

Categories

Resources