JavaScript передает область действия другой функции
Можно ли каким-то образом передать область действия функции другому?
Например,
function a(){
var x = 5;
var obj = {..};
b(<my-scope>);
}
function b(){
//access x or obj....
}
Я хотел бы получить доступ к переменным напрямую, т.е. не использовать что-либо вроде this.a
или this.obj
, а просто использовать x
или obj
напрямую.
Ответы
Ответ 1
Единственный способ получить доступ к функции a
private scope - объявить b
внутри a
, поэтому он образует замыкание, которое допускает неявный доступ к переменным a
.
Вот несколько вариантов для вас.
Прямой доступ
-
Объявить b
внутри a
.
function a() {
var x = 5,
obj = {};
function b(){
// access x or obj...
}
b();
}
a();
-
Если вы не хотите b
внутри a
, то вы можете использовать их внутри большей области контейнера:
function container() {
var x, obj;
function a(){
x = 5;
obj = {..};
b();
}
function b(){
// access x or obj...
}
}
container.a();
Это единственные способы, с помощью которых вы можете использовать переменные a
непосредственно в b
без дополнительного кода для перемещения. Если вы довольны небольшим количеством "помощи" и/или косвенности, вот еще несколько идей.
Непрямой доступ
-
Вы можете просто передать переменные в качестве параметров, но не иметь доступ на запись, кроме свойств объектов:
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();
В качестве варианта этого вы можете получить доступ на запись, передав обновленные значения обратно на a
следующим образом:
// in a:
var ret = b(x, obj);
x = ret.x;
obj = ret.obj;
// in b:
return {x : x, obj : obj};
-
Вы можете передать b
объект с геттерами и сеттерами, которые могут получить доступ к a
частным переменным:
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 properties:
obj.key = value;
}
a();
Получатели и сеттеры могут быть общедоступными, назначенными объекту this
a
, но таким образом они доступны только в том случае, если они явно выдаются из a
.
-
И вы можете поместить свои переменные в объект и передать объект вокруг:
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();
В качестве варианта вы можете вместо этого построить объект во время вызова:
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
Область создается функциями, а область действия остается с функцией, поэтому самое близкое к тому, что вы просите, состоит в том, чтобы передать функцию из 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()
}
Ответ 3
Нет.
Вы получаете доступ к локальному объекту области видимости. [[Context]]
.
Вы не можете публично обращаться к нему.
Теперь, после node.js, вы сможете написать плагин С++, который даст вам доступ к объекту [[Context]]
. Я настоятельно рекомендую против этого, поскольку он привносит собственные расширения на язык JavaScript.
Ответ 4
как насчет использования bind
function funcA(param) {
var bscoped = funcB.bind(this);
bscoped(param1,param2...)
}
Ответ 5
Вы не можете "передать область"... не то, что я знаю.
Вы можете передать объект, к которому обращается функция, используя apply
или call
и отправить текущий объект (this
) в качестве первого параметра вместо вызова функции:
function b(){
alert(this.x);
}
function a(){
this.x = 2;
b.call(this);
}
Единственный способ для функции доступа к определенной области должен быть объявлен в этой области.
Kind'a сложно.
Это приведет к чему-то вроде:
function a(){
var x = 1;
function b(){
alert(x);
}
}
Но это могло бы сорвать цель.
Ответ 6
Как говорили другие, вы не можете передавать такой масштаб. Вы можете, однако, обладать переменными должным образом, используя самостоятельные исполняемые анонимные функции (или сразу же исполняемые, если вы педантичны):
(function(){
var x = 5;
var obj = {x:x};
module.a = function(){
module.b();
};
module.b = function(){
alert(obj.x);
};
}());
a();
Ответ 7
Я думаю, что самое простое, что вы можете сделать, это передать переменные из одной области в функцию вне этой области. Если вы передаете ссылку (например, объекты), 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
}
Ответ 8
function a(){
var x = 5;
var obj = {..};
var b = function()
{
document.println(x);
}
b.call();
}
Ответ 9
Вы можете создать свои переменные без ключевого слова var
, и они будут глобальными, но не смогут передать область, о которой я знаю...
Ответ 10
function a(){
this.x = 5;
this.obj = {..};
var self = this;
b(self);
}
function b(scope){
//access x or obj....
}
Ответ 11
Вы пробовали что-то вроде этого:
function a(){
var x = 5;
var obj = {..};
b(this);
}
function b(fnA){
//access x or obj....
fnA.obj = 6;
}
Если вы можете выставить функцию B как функцию метода A, тогда сделайте следующее:
function a(){
var x = 5;
var obj = {..};
b(this);
this.b = function (){
// "this" keyword is still === function a
}
}