Подтвердить что ты не робот

JavaScript передает область действия другой функции

Можно ли каким-то образом передать область действия функции другому?

Например,

function a(){
   var x = 5;
   var obj = {..};
   b(<my-scope>);
}

function b(){
   //access x or obj....
}

Я хотел бы получить доступ к переменным напрямую, т.е. не использовать что-либо вроде this.a или this.obj, а просто использовать x или obj напрямую.

4b9b3361

Ответ 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
   }
}