有没有可能将一个函数的作用域传递给另一个函数?
例如,
function a(){
var x = 5;
var obj = {..};
b(<my-scope>);
}
function b(){
//access x or obj....
}
我更倾向于直接访问变量,即不使用像this.a
或this.obj
这样的东西,而只是直接使用x
或obj
。
有没有可能将一个函数的作用域传递给另一个函数?
例如,
function a(){
var x = 5;
var obj = {..};
b(<my-scope>);
}
function b(){
//access x or obj....
}
我更倾向于直接访问变量,即不使用像this.a
或this.obj
这样的东西,而只是直接使用x
或obj
。
a
的私有作用域的方法是在a
内部声明b
,这样就形成了一个闭包,允许隐式访问a
的变量。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();
除了一些额外的代码来移动变量之外,这些是你唯一可以直接在b中使用a
的变量的方式。如果你能接受一些“帮助”和/或间接性,以下是一些更多的想法。
间接访问
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();
作用域是由函数创建的,而作用域会随着函数一起存在,所以最接近你要求的方式将是从a()
传递一个函数到b()
,这个函数将继续访问来自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()
}
b()
虽然无法直接访问传递给函数的变量,但是如果传递的是引用类型,比如对象,则可以通过函数返回该对象来访问。
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()
}
a
在 b
中的访问在哪里?@gion 当然,好的。 :) - ErikEa++
所示。 - user113716b
中的 "//access a or obj..."。无论如何,我并不是要挑剔,我只是想帮助你改进你的答案。 - ErikEwith
或 eval
到本地作用域。 - Raynos使用bind
如何呢?
function funcA(param) {
var bscoped = funcB.bind(this);
bscoped(param1,param2...)
}
不。
你正在访问本地作用域对象。 [[Context]]
。
你不能公开访问它。
现在,由于它是node.js,你应该能够编写一个C++插件,使你可以访问[[Context]]
对象。我强烈建议不要这样做,因为它会给JavaScript语言带来专有扩展。
[[Context]]
,请务必告诉我。 - Raynos你不能“传递作用域”...至少我不知道怎么做。
但是你可以通过使用apply
或 call
传递函数所引用的对象,并将当前对象 (this
) 作为第一个参数,而不仅仅是调用函数:
function b(){
alert(this.x);
}
function a(){
this.x = 2;
b.call(this);
}
function a(){
var x = 1;
function b(){
alert(x);
}
}
正如其他人所说,你不能像那样传递作用域。但是,你可以使用自执行匿名函数(如果你很讲究,也可以称之为立即执行函数)来正确地定义变量的作用域:
(function(){
var x = 5;
var obj = {x:x};
module.a = function(){
module.b();
};
module.b = function(){
alert(obj.x);
};
}());
a();
this
是module
而不是window
,所以只需写入该模块。我还强烈建议不要覆盖global
,因为那是node.js中的真正全局范围(它可能具有未知的副作用)。 - Raynos我认为最简单的方法是将变量从一个作用域传递到函数外部。如果你通过引用传递(比如对象),那么 b 就可以“访问”它(请参见以下 obj.someprop):
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
}
b
函数将访问全局变量 a
和 obj
,而不是在 a
中的那些。 - ErikE你只能使用 eval 来实现这个功能。以下代码将返回函数 b 在函数 a 的作用域中的值。
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();
}
b.call();
。直接使用 b();
即可。 - ErikE