阻止JavaScript闭包继承作用域

8
我正在寻找一种花哨的方法来防止闭包继承周围的作用域。例如:
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();

    };

我的问题是 - 有没有人知道JS中防止闭包继承范围的第三种方法?可以使用一些高级方法。
我认为唯一可能起作用的是Node.js中的vm.runInThisContext()。
让我们想象一下,假设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;
};

@marekful 我想让父级作用域中的变量对子级(闭包)作用域不可访问。 - Alexander Mills
1
你可以将我的1000美元转移到我在开曼群岛的账户上 -> https://jsfiddle.net/01fyqp0v/ - adeneo
@adeneo 做得很好,但是 IIFE 方法存在问题,我在问题中提到了它。 - Alexander Mills
1
明白了,块作用域似乎是正确的方式! - Kyle Richardson
2
@AlexanderMills 我不知道...我觉得这个OP有点像IIFE。 - Kyle Richardson
显示剩余12条评论
2个回答

8
您可以使用块级作用域。

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();


5
该短语可翻译为“我真是该死了”或“我竟然错了”。 - Alexander Mills
1
如果你正在编写一个库,那么如果需要这个来使其工作,你可能做错了。然而,块级作用域与 letconst 配合得非常好,它们当然是块级作用域的。 - adeneo
1
块语句本身在几乎所有浏览器中都得到支持,并且自 JavaScript 诞生以来一直是 JS 的一部分,包括带标签和不带标签的情况。然而,块作用域变量,即 letconst,仅在较新的浏览器中可用,而这不能使用常规的函数作用域变量 var - adeneo
1
需要注意的是,如果你想让它在旧版浏览器中工作,使用 var,我们又回到了创建新作用域的额外函数,很可能是一个 IIFE,看起来与块语句非常相似,但字符更多 -> https://jsfiddle.net/adeneo/ydpfaq5w/1/ - adeneo
1
@AlexanderMills:“为什么这么字面化?”为了明确要求。 - guest271314
显示剩余14条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接