How to Access Local Scope Dynamically in JavaScript

How can I access local scope dynamically in javascript?

No, like crescentfresh said. Below you find an example of how to implement without eval, but with an internal private object.

var test = function () {
var prv={ };
function prop(name, def) {
prv[name] = def;
return function(value) {
// if (!value) is true for 'undefined', 'null', '0', NaN, '' (empty string) and false.
// I assume you wanted undefined. If you also want null add: || value===null
// Another way is to check arguments.length to get how many parameters was
// given to this function when it was called.
if (typeof value === "undefined"){
//check if hasOwnProperty so you don't unexpected results from
//the objects prototype.
return Object.prototype.hasOwnProperty.call(prv,name) ? prv[name] : undefined;
}
prv[name]=value;
return this;
}
};

return pub = {
a:prop('a', 1),
b:prop('b', 2),
c:prop('c', 3),
d:function(){
//to show that they are accessible via two methods
//This is a case where 'with' could be used since it only reads from the object.
return [prv.a,prv.b,prv.c];
}
};
}();

How do I access a local variable dynamically (via a String form of its name) from a closure scope?

You're mixing up local variables (which are not properties of an object) with properties (which are not local variables). There is no answer to your question, or, rather, the answer is "it can't be done".

How to access dynamic local variables

Use an object instead of a set of separate variables instead. (I can't think of a real world situation where you would want to use a dynamically named variable where it isn't part of a group of logically related ones).

var animals = { dog: "Rover", cat: "Flopsy", goldfish: "Killer" };
var which = 'dog';
alert(animals[which]);

How can I read/write local variables dynamically in JavaScript/TypeScript?

Best solution: Use an array instead:

Change this:

if (...) {
const day1 = { date: null, total: 0 };
const day2 = { date: null, total: 0 };
const day3 = { date: null, total: 0 };
const day4 = { date: null, total: 0 };
const day5 = { date: null, total: 0 };
const day6 = { date: null, total: 0 };
const day7 = { date: null, total: 0 };

// ...

day1.date = ... ;
day2.date = ... ;
day3.date = ... ;
day4.date = ... ;
day5.date = ... ;
day6.date = ... ;
day7.date = ... ;
}

...to this:

// Declared in module scope:
type Day = { date: Date | null, total: number };

// Inside your function:
if( ... ) {

const days: Day[] = [
{ date: null, total: 0 },
{ date: null, total: 0 },
{ date: null, total: 0 },
{ date: null, total: 0 },
{ date: null, total: 0 },
{ date: null, total: 0 },
{ date: null, total: 0 }
];

//

for( let i = 0; i < 7; i++ ) {
days[i].date = ...
}
}

You can also initialize days in a loop too:

const days: Day[] = [];
for( let i = 0; i < 7; i++ )
{
days[i] = { date: null, total: 0 };
}

And you can have named references to elements in the array if you want to keep on using day1, day2, etc (but remember these are references to the object values in the array rather than being aliases to array indexes):

const day1 = days[0];
const day2 = days[1];

...though try not to let your 1-based day numbering be confused with JavaScript/TypeScript's 0-based array indexing.

Worst solution: Using eval:

You can manipulate locals using eval(), but you shouldn't use eval(), ever. But you can do this:

if (...) {
const day1 = { date: null, total: 0 };
const day2 = { date: null, total: 0 };
const day3 = { date: null, total: 0 };
const day4 = { date: null, total: 0 };
const day5 = { date: null, total: 0 };
const day6 = { date: null, total: 0 };
const day7 = { date: null, total: 0 };

for (let i = 1; i <= 7; i++) {
const expr = 'day' + i + ' = ...;';
console.log( expr );
eval( expr );
}
}

Javascript: Get access to local variable or variable in closure by its name

I'm not aware of anything built into JavaScript to reference local variables like that (though there probably should be considering all variables are internally referenced by strings).

I'd suggest keeping all your variables in an object if you really need to access by string:

var variables = {
"j": 1
};
alert(variables["j"]);

Update: It kind of bugs me that there's no way to do this like you want. Internally the variable is a mutable binding in the declarative environment records. Properties are bound to the object they're a property of through the object's environment records, but there's actually a way to access them using brackets. Unfortunately, there's no way to access the declarative environment records the same way.

Javascript: Passing local variables into a dynamically created function that is a parameter inside another function

You need to create a closure that contains the value of i at the time where the anonymous function is created. You can use a wrapper function for that:

function createClosure(x, func) {
return function(results, status) { func(x, results, status); }
}

/* ... */

for(var i = 0; i < 10; i++) {
var data = 'cannot modify this data';
my_function(data, createClosure(i, function(i, results, status) {
alert(i);
alert(results);
alert(status);
}));
}

Or if you want to be short, you can create the closure in place:

for(var i = 0; i < 10; i++) {
var data = 'cannot modify this data';
my_function(data, (function(i) {
return function (results, status) {
alert(i);
}
})(i));
}


Related Topics



Leave a reply



Submit