Предотвращение закрытия JavaScript от наследования области видимости

Я ищу причудливый способ предотвратить замыкание от наследования окружающего скропа. Например:

let foo = function(t){

  let x = 'y';

  t.bar = function(){

    console.log(x); // => 'y'

  });

};

Есть только два способа предотвращения общего доступа:

(1) Используйте теневые переменные:

let foo = function(t){

  let x = 'y';

  t.bar = function(x){

    console.log(x); // => '?'

  });

};

(2) Поместите тело функции в другое место:

  let foo = function(t){

      let x = 'y';

      t.bar = createBar();

    };

Мой вопрос - знает ли кто-нибудь о 3-м способе предотвращения замыканий от наследования области действия в JS? Что-то необычное в порядке.

Единственное, что, я думаю, могло бы сработать, vm.runInThisContext() в Node.js.

Давайте на секунду используем наше воображение и представим, что у JS есть ключевое слово private, что означает, что переменная была приватной только для области действия этой функции, например так:

  let foo = function(t){

      private let x = 'y';  // "private" means inaccessible to enclosed functions

      t.bar = function(){

        console.log(x); // => undefined

      });

    };

и IIFE не будет работать:

let foo = function(t){

    (function() {
    let x = 'y';
    }());

   console.log(x); // undefined (or error will be thrown)
   // I want x defined here

  t.bar = function(){
    // but I do not want x defined here
    console.log(x); 
  }

  return t;
};

2 ответа

Решение

Эта техника работает:

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

 const foo = 3;

 it.cb(isolated(h => {
    console.log(foo);  // this will throw "ReferenceError: foo is not defined"
    h.ctn();
 }));

вам также может повезти с JavaScript with оператор

Вы можете использовать область видимости

let foo = function(t) {
  {
    // `x` is only defined as `"y"` here
    let x = "y";
  } 
  {
    t.bar = function(x) {
      console.log(x); // `undefined` or `x` passed as parameter
    };
  }
};


const o = {};
foo(o);

o.bar();

Другие вопросы по тегам