I am looking for a fancy way to prevent a closure from inheriting surrounding scrope. For example:
let foo = function(t){
let x = 'y';
t.bar = function(){
console.log(x); // => 'y'
});
};
there are only two ways I know of preventing sharing scope:
(1) Use shadow variables:
let foo = function(t){
let x = 'y';
t.bar = function(x){
console.log(x); // => '?'
});
};
(2) Put the function body somewhere else:
let foo = function(t){
let x = 'y';
t.bar = createBar();
};
My question is - does anyone know of a 3rd way to prevent closures from inheriting scope in JS? Something fancy is fine.
The only thing that I think could possibly work is vm.runInThisContext()
in Node.js.
Let's use our imaginations for a second, and imagine JS had a private keyword, which meant the variable was private only to that function's scope, like this:
let foo = function(t){
private let x = 'y'; // "private" means inaccessible to enclosed functions
t.bar = function(){
console.log(x); // => undefined
});
};
and IIFE won't work:
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;
};
I am looking for a fancy way to prevent a closure from inheriting surrounding scrope. For example:
let foo = function(t){
let x = 'y';
t.bar = function(){
console.log(x); // => 'y'
});
};
there are only two ways I know of preventing sharing scope:
(1) Use shadow variables:
let foo = function(t){
let x = 'y';
t.bar = function(x){
console.log(x); // => '?'
});
};
(2) Put the function body somewhere else:
let foo = function(t){
let x = 'y';
t.bar = createBar();
};
My question is - does anyone know of a 3rd way to prevent closures from inheriting scope in JS? Something fancy is fine.
The only thing that I think could possibly work is vm.runInThisContext()
in Node.js.
Let's use our imaginations for a second, and imagine JS had a private keyword, which meant the variable was private only to that function's scope, like this:
let foo = function(t){
private let x = 'y'; // "private" means inaccessible to enclosed functions
t.bar = function(){
console.log(x); // => undefined
});
};
and IIFE won't work:
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;
};
Share
Improve this question
edited Jul 23, 2017 at 0:13
Alexander Mills
asked Jul 22, 2017 at 23:45
Alexander MillsAlexander Mills
100k166 gold badges537 silver badges916 bronze badges
17
- There generally isn't much use for "private" variables or variables that aren't accessible in a lower scope etc. that why there really aren't any ways to create such variables. If you want something to not be accessible, enclose it in it's own scope, such as an IIFE etc. – adeneo Commented Jul 22, 2017 at 23:53
- Maybe you want an IIFE? – Kyle Richardson Commented Jul 22, 2017 at 23:53
- 1 You can transfer my 1000 bucks to my account in the Caymans -> jsfiddle/01fyqp0v – adeneo Commented Jul 23, 2017 at 0:00
- 1 Got it, block scope seems to be the way! – Kyle Richardson Commented Jul 23, 2017 at 0:12
- 2 @AlexanderMills I dunno... I think the OP is kinda IIFE. – Kyle Richardson Commented Jul 23, 2017 at 0:17
2 Answers
Reset to default 8You can use block scope
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();
This technique works:
Create helper function to run a function in an isolated scope
const foo = 3;
it.cb(isolated(h => {
console.log(foo); // this will throw "ReferenceError: foo is not defined"
h.ctn();
}));
you might also have some luck with the JavaScript with
operator