可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答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 of a
.
function a() {
var x = 5,
obj = {};
function b(){
// access x or obj...
}
b();
}
a();
If you don't want b
inside of a
, 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 access a
'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 of a
, but this way they are only accessible if explicitly given out from within a
.
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();
回答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()
}
回答3:
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.
回答4:
what about using bind
function funcA(param) {
var bscoped = funcB.bind(this);
bscoped(param1,param2...)
}
回答5:
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();
回答6:
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
}
回答7:
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.
回答8:
function a(){
this.x = 5;
this.obj = {..};
var self = this;
b(self);
}
function b(scope){
//access x or obj....
}
回答9:
function a(){
var x = 5;
var obj = {..};
var b = function()
{
document.println(x);
}
b.call();
}
回答10:
You can create your variables without the var
keyword and they will be global, but no way to pass the scope that I'm aware of...
回答11:
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
}
}