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
or this.obj
, but just use x
or obj
directly.
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();
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()
}
what about using bind
function funcA(param) {
var bscoped = funcB.bind(this);
bscoped(param1,param2...)
}
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.
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.
As others have said, you cannot pass scope like that. You can however scope variables properly using self executing anonymous functions (or immediately executing if you're pedantic):
(function(){
var x = 5;
var obj = {x:x};
module.a = function(){
module.b();
};
module.b = function(){
alert(obj.x);
};
}());
a();
I think the simplest thing you can do is pass variables from one scope to a function outside that scope. If you pass by reference (like Objects), b has 'access' to it (see obj.someprop in the following):
function a(){
var x = 5;
var obj = {someprop : 1};
b(x, obj);
alert(x); => 5
alert(obj.someprop); //=> 'otherval'
}
function b(aa,obj){
x += 1; //won't affect x in function a, because x is passed by value
obj.someprop = 'otherval'; //change obj in function a, is passed by reference
}
You can really only do this with eval. The following will give function b function a's scope
function a(){
var x = 5;
var obj = {x};
eval('('+b.toString()+'())');
}
function b(){
//access x or obj....
console.log(x);
}
a(); //5
function a(){
this.x = 5;
this.obj = {..};
var self = this;
b(self);
}
function b(scope){
//access x or obj....
}
function a(){
var x = 5;
var obj = {..};
var b = function()
{
document.println(x);
}
b.call();
}
Have you tried something like this:
function a(){
var x = 5;
var obj = {..};
b(this);
}
function b(fnA){
//access x or obj....
fnA.obj = 6;
}
If you can stand function B as a method function A then do this:
function a(){
var x = 5;
var obj = {..};
b(this);
this.b = function (){
// "this" keyword is still === function a
}
}
精彩评论