JavaScript pass scope to another function
Solution 1
The only way to truly get access to function a
's private scope is to declare b
inside of a
so it forms a closure that allows implicit access to a
's variables.
Here are some options for you.
Direct Access
Declare
b
inside ofa
.function a() { var x = 5, obj = {}; function b(){ // access x or obj... } b(); } a();
If you don't want
b
inside ofa
, then you could have them both inside a larger container scope:function container() { var x, obj; function a(){ x = 5; obj = {..}; b(); } function b(){ // access x or obj... } } container.a();
These are the only ways you're going to be able to use a
's variables directly in b
without some extra code to move things around. If you are content with a little bit of "help" and/or indirection, here are a few more ideas.
Indirect Access
You can just pass the variables as parameters, but won't have write access except to properties of objects:
function a() { var x = 5, obj = {}; b(x, obj); } function b(x, obj){ // access x or obj... // changing x here won't change x in a, but you can modify properties of obj } a();
As a variation on this you could get write access by passing updated values back to
a
like so:// in a: var ret = b(x, obj); x = ret.x; obj = ret.obj; // in b: return {x : x, obj : obj};
You could pass
b
an object with getters and setters that can accessa
's private variables:function a(){ var x = 5, obj = {..}, translator = { getX : function() {return x;}, setX : function(value) {x = value;}, getObj : function() {return obj;}, setObj : function(value) {obj = value;} }; b(translator); } function b(t){ var x = t.getX(), obj = t.getObj(); // use x or obj... t.setX(x); t.setObj(obj); // or you can just directly modify obj's properties: obj.key = value; } a();
The getters and setters could be public, assigned to the
this
object ofa
, but this way they are only accessible if explicitly given out from withina
.And you could put your variables in an object and pass the object around:
function a(){ var v = { x : 5, obj : {} }; b(v); } function b(v){ // access v.x or v.obj... // or set new local x and obj variables to these and use them. } a();
As a variation you can construct the object at call time instead:
function a(){ var x = 5, obj = {}; b({x : x, obj: obj}); } function b(v){ // access v.x or v.obj... // or set new local x and obj variables to these and use them. } a();
Solution 2
Scope is created by functions, and a scope stays with a function, so the closest thing to what you're asking will be to pass a function out of a()
to b()
, and that function will continue to have access to the scoped variables from a()
.
function a(){
var x = 5;
var obj = {..};
b(function() { /* this can access var x and var obj */ });
}
function b( fn ){
fn(); // the function passed still has access to the variables from a()
}
While b()
doesn't have direct access to the variables that the function passed does, data types where a reference is passed, like an Object, can be accessed if the function passed returns that object.
function a(){
var x = 5;
var obj = {..};
b(function() { x++; return obj; });
}
function b( fn ){
var obj = fn();
obj.some_prop = 'some value'; // This new property will be updated in the
// same obj referenced in a()
}
Solution 3
what about using bind
function funcA(param) {
var bscoped = funcB.bind(this);
bscoped(param1,param2...)
}
Solution 4
No.
You're accessing the local scope object. The [[Context]]
.
You cannot publicly access it.
Now since it's node.js you should be able to write a C++ plugin that gives you access to the [[Context]]
object. I highly recommend against this as it brings proprietary extensions to the JavaScript language.
Solution 5
You can't "pass the scope"... not that I know of.
You can pass the object that the function is referring to by using apply
or call
and send the current object (this
) as the first parameter instead of just calling the function:
function b(){
alert(this.x);
}
function a(){
this.x = 2;
b.call(this);
}
The only way for a function to access a certain scope is to be declared in that scope.
Kind'a tricky.
That would lead to something like :
function a(){
var x = 1;
function b(){
alert(x);
}
}
But that would kind of defeat the purpose.
ciochPep
Updated on April 23, 2021Comments
-
ciochPep about 3 years
Is it possible to somehow pass the scope of a function to another?
For example,
function a(){ var x = 5; var obj = {..}; b(<my-scope>); } function b(){ //access x or obj.... }
I would rather access the variables directly, i.e., not using anything like
this.a
orthis.obj
, but just usex
orobj
directly. -
david almost 13 yearsThis is context, rather than scope.
-
Raynos almost 13 yearsAny reason for a downvote? If you can access
[[Context]]
please do let me know. -
gion_13 almost 13 years@Erik that's redundant. If I want to pass the vars as arguments, I wouldn't need scope.
-
Raynos almost 13 yearsit's annoying when people don't read the question and use browser js. It's just as bad as using jQuery in JavaScript only questions.
this
ismodule
instead ofwindow
so just write to that. I also highly recommend againts overwritingglobal
as that's the real global scope in node.js (and it may have unknown side-effects) -
ErikE almost 13 years@gion See my answer (third code block). I was suggesting something a little different than passing them as arguments.
-
david almost 13 years@Raynos, I read the question, and knew it was in node. The window keyword was in there because I tested it in jsfiddle first, rather than blindly spewing code and hoping it works. My bad for not proofreading it again.
-
gion_13 almost 13 years@Erik I know. You want to pass an object that would "simulate" the scope.I'm not saying it's wrong or that it won't work. It's great, but it's not quite the answer for this question.
-
ErikE almost 13 years@gion I find it helpful to give more choices instead of only answering exactly what was asked. For example, "you CAN do this with dynamic SQL but you probably shouldn't, here are other options". Anyway, I didn't downvote you if that's what you're thinking.
-
gion_13 almost 13 yearsIt's not the best answer, but it's a good one. One of the ways to pass the scope is by defining the function in that scope, so stop downvoting this
-
ErikE almost 13 years1. There's no need for using
this
at all. Just declaringb
inside ofa
will automatically grantb
access toa
's private variables. 2. Using thethis
keyword inb
will not give access to the private variables sothis.obj
will be undefined inb
. -
gion_13 almost 13 years@Erik: let it go. It's not that funny and it's a bit different.
-
ErikE almost 13 yearsAs given, your
b
function will be accessing a globala
andobj
, not the ones ina
. -
ErikE almost 13 years@patrick Where is the access to variable
a
inb
? @gion sure, okay. :) -
KooiInc almost 13 yearsYep, forgot the params in b(), edited, and by the way renamed var a, because that may conflict with the function name (jshint.com complained)
-
user113716 almost 13 years@Erik: There is none, except in whatever capacity the function allows manipulation. "While b() doesn't have direct access to the variables..."
-
user113716 almost 13 years@Erik: Well, the question's actual requirements are not supported by the language (direct access), but it does demonstrate that indirect access is possible, as shown by the
a++
. -
ErikE almost 13 yearsI was referring to "//access a or obj..." inside of
b
. Anyway, I don't mean to nitpick, I was trying to help you improve your answer. -
user113716 almost 13 years@Erik: Not a problem at all. Ultimately there's no way to "access a or obj" inside of
b()
because JavaScript is pass-by-value. The only thingb()
will ever be able to get is a copy of the value that thea()
function references via an intermediary function. That same function (or a different one) can overwrite the value with a new value passed fromb()
, or perform some other manipulation such as a++
. It's basically all the same concept. ;o) -
Raynos almost 13 years@patrick_dw I'm sure you can inject a
with
oreval
into the local scope in buggy browsers. -
user113716 almost 13 years@Erik: I think the main point of the answer, and the reason for the votes, is that scope is created by a function, and that function will never lose its scope, and as such will always be able to manipulate those variables in its scope. The specific manipulation needed will vary.
-
ErikE almost 13 yearsShawn there's no need for
b.call();
. Justb();
directly. -
gion_13 almost 13 years@Erik: it has nothing to do with node.js. see java-samples.com/showtutorial.php?tutorialid=829 for more info
-
James Andino about 12 yearsJust gave you an up vote. If any one writes this extension I would love to know and then it is not proprietary. It blows my mind that people refer to bind this as changing scope. All you are doing is changing a reference to an object and including it into the scope of the function. To actually change real "scope" you need to do as you said here and change the frame in which these things point at.
-
Gabriel G over 3 yearsif funcA is defined on global scope "this" passed through bind will be the window. No argument defined inside funcA will be readable inside funcB. Or am I missing something here? Still, when passing funcB.bind(this.funcA), I can only access the variables that are defined as funcA.variable.
-
zergski almost 2 yearskeep far away from eval.. Atleast use new Func