Home > OS >  JS scope that cannot access its parents scopes
JS scope that cannot access its parents scopes

Time:01-06

Is it possible in Javascript to create an isolated scope within any other scope that cannot access its parent scope's variables and functions, I am thinking of something like this:

// global scope
let a = 'hello';

function shout() {
  console.log('shouting');
}

// an isolated scope
// a scope that is unable to access $a and $shout
(() => {

  console.log(a); // ReferenceError: a is not defined
  shout(); // ReferenceError: shout is not defined

})();

CodePudding user response:

No, but you could selectively override the names as arguments or local variables, e.g.:

// global scope
let a = 'hello';

function shout() {
  console.log('shouting');
}

// an isolated scope
// a scope that is unable to access $a and $shout
((a, shout) => {

  console.log(a); // ReferenceError: a is not defined
  shout(); // ReferenceError: shout is not defined

})();

CodePudding user response:

Currently no, but in the future though, we might get ShadowRealms, which allows you to run code in a brand new context (same environment).

Your example could look like

let a = 'hello';

function shout() {
  console.log('shouting');
}

const sr = new ShadowRealm();
sr.evaluate(`console.log(a);`);
sr.evaluate(`shout();`);

Since this shadow realm does not have an a nor a shout function defined, this would result in a reference error. I'm not sure how errors are handled in ShadowRealms yet, but it would produce the desired behavior.

You can read more about how to use shadow realms here if they ever get added, or star the proposal here to support it (and hopefully get it added to the standard).

For now you could try something like @canon's answer, or try using worker scripts, but I doubt either of them will produce the behavior you want.

CodePudding user response:

Currently any lower level scope can see everything at higher level, so the answer is currently not.

You can however define your own shielded object:

function shout() {
  console.log('shouting');
}

let whoIsThis = (() => {
  this.name = 'Just me';
  let self = this;
  return {
    set: function(name) {
      self.name = name;
    },
    showMe: function() {
      return 'Who am I? '   self.name;
    }
  };
})();

(() => {
  shout(); // public scope
  console.log(whoIsThis.showMe());      // 'Who am I? Just me'
  whoIsThis.set('Peter');
  console.log(whoIsThis.showMe());      // 'Who am I? Peter'
  console.log('name:', whoIsThis.name); // 'name: undefined'
})();

CodePudding user response:

// global scope
var a = 'hello';

function shout() {
  console.log('shouting');
}

// a scope that is unable to access $a and $shout
function test(a, shout) {
  console.log(a); // ReferenceError: a is not defined
  shout(); // ReferenceError: shout is not defined
}

// you're setting the function's arguments for a and shout to undefined
// it's more ugly than the short forms mentioned above.
test(undefined,undefined);

// You could likely do test(null,null); perhaps as well
  • Related