views:

594

answers:

8

Basically this is a question how to access local scope handler. I trying to achieve something similar for global variable definition like:

window['newObject'] = "some string";
alert(newObject);

but for local scope. Right now only solution I have is using evals:

eval("var newObject='some string'");

But this is really ugly solution... The best one would be like using some reference to local scope like in a window[] solution, but I never heard of any reference to local scope... Any ideas ?

Example goes here:

function x(arg)
{
   localScope[arg.name]=arg.value;
   alert(sex);
}

x({name:"sex", value:"Male"});
+1  A: 
Jason S
Yes - I want to do that dynamically coresponding to data I receive to this function.
Wilq32
I mean - yes you miss something there. I need a defining local variable dynamically ;)
Wilq32
A: 

Interesting question, never thought of something like this. But what is the usecase?

The reason you'd want to do something like this, is if you don't know the name of the variable. But then in that case, the only way to access the variable again would be using the same reference object. I.e. you could just use any old object to store data in.

Reading from such a reference object would be interesting for debugging purposes, but I don't see why you'd want to write to it.

Edit:

The example you posted doesn't convince me of the need for access to the local scope, since you still have the name sex hard coded in the alert. This could be implemented as:

function x(arg)
{
  container = {};
  container[arg.name] = arg.value;
  alert(container.sex);
}

Could you elaborate more on the example?

Tom Lokhorst
Example is not for convincing that this is needed. I working on template system and explaining why I need that would take alot of time and would be really complicated :)
Wilq32
I just need to be able to call (alert(sex)) where the variable name can be taken from outside source;)
Wilq32
Ah, so what it comes down to is that your template system doesn't allow for dots in alertboxes? ;-) Otherwise, `alert(obj.someObj)` just works.
Tom Lokhorst
It alows a dots... but I trying to replace some bad template system from past and I need to support that you can put a variables from local scope where you want to get that template.
Wilq32
+1  A: 

Why not create an object in local scope and then use it as a container for any variables you wish to create dynamically?

function x(arg)
{
    var localSpace = {};
    localSpace[arg.name] = arg.value;
}
Sebastian Celis
But I need to be able to refer to element as a name only, not with localSpace[name] before every variable...
Wilq32
why is that a requirement?
Jason S
because third parties would like to refer in templates to their own values from local scope... well explaining this is really complicated, but I can sure you that there is no other way of doing this only by having local scope extended (or global but with longer access to variables).
Wilq32
+1  A: 

Okey I found related question that is talking about what I need...

http://stackoverflow.com/questions/598878/how-can-i-access-local-scope-dynamically-in-javascript

I just remember that in ECMA 262 is only one way to add dynamically local variables to scope using "with" statement (and eval of course), here are solution:

var x=function(obj)
{

    with(obj) 
    {
       alert(someObj);
    }
 }
 alert(typeof someObj);


 x ( {someObj:"yea"}) ;

 alert(typeof someObj);
Wilq32
The only thing this `with` block gives you, is that you don't have to write `alert(obj.someObj)`. At the expense of adding three extra lines of code.
Tom Lokhorst
"with" is a bad thing to use. See http://www.yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/ and https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Object_Manipulation_Statements
Jason S
Yes - both of those problems : readability and little slower local scope access is affordable with templatings system that I need to create.
Wilq32
Wait: where does the "alert(someObj)" code come from? Are you writing it yourself or is this automatically generated code? Why can't you use alert(obj.someObj) ?
Jason S
@Jason S: Exactly my point, it seems the OP either can't generate this, or finds it "too much code" to type. I'd say added the extra "`obj.`"-prefix is clearer, since the actual arguments to the function aren't in scope either: `alert(fakeScope.myVar);`
Tom Lokhorst
content of alert would be outside of a function, and would refeer to something from local scope that should be passed to function... Its really complicated to tell you why is that :)) really :)
Wilq32
A: 

I'm not entirely sure I understand your question. When creating a class x, I generally do this:

function x(args) {
  var _self = this;

  _self.PriviledgedMethod(a) {
      // some code
  }

  function privateMethod(a) {
      // some code
  }
}

var newObject = new x(args);

You can continue to access _self and args since it is closed on by the contained functions.

Jacob Lauzier
avoid eval at all costs (sometimes you can't). by avoiding it, you will allow for better minification possibilities.
Jacob Lauzier
I ask for something completly diffrent - how to create dynamically a variables in local scope - that you can type alert(sex) where 'sex' is dynamically created in local scope
Wilq32
+1  A: 

You could try the named arguments trick
EDIT: This isn't cross browser

function x( {sex:sex, height:height} ) {
    alert( sex );
    alert( height );
}

x( { sex: 'male', height: 'short' } );
x( { height: 'medium', sex: 'female' } );

// male
// short
// female
// medium
meouw
intriguing... is this ECMAscript, or just a particular dialect? (e.g. Spidermonkey since it seems to work with Spidermonkey 1.7)
Jason S
Interesting one.. I adding +1 :)
Wilq32
This is part of JS1.7 and is called destructuring assignment. You can simplify this function declaration to: function x({sex, height}) { ... }
Prestaul
+2  A: 

What you're looking for is called the call object. But according to this, you can't access it directly, so you're out of luck.

JW
I've never heard the term _call object_ before, but the link you provided was useful. It looks like a JavaScript implementation detail for describing the local scope of a function (that can escape "local" scope by being captured in a closure). However, I don't think this has very much to do with the original question.
Tom Lokhorst
On second thought, if you _could_ directly access that implementation detail, it would be relevant to the question, so you're right in that respect.
Tom Lokhorst
Right; if you could, you could do what he's asking: "localScope[name]=value;"
JW
A: 

Not sure what you need exactly, but here's my 2 cents.

The only way to dynamically create vars in an existing function is the eval method you've already mentioned.

Another option (mentioned by others) is that your function take a context map, and the template access it with dot notation (context.var1)

My final suggestion is the Function constructor. But I have a feeling this may be what you're looking for. (Note that the function constructor suffers from the same problems as an eval call)

var arg1 = "first";
var arg2 = "last";

// This is the body of the function that you want to execute with first
// and last as local variables. It would come from your template
var functionBody = "alert(first + ' ' + last)";

var myCustomFun = new Function(arg1, arg2,  functionBody);

myCustomFun("Mark", "Brown"); // brings up and alert saying "Mark Brown";

Hope it helps

Juan Mendes