Function.prototype.environment

A function is depend on it's source code and it's environment variables.
This function will get a read-only access to function environment.

Example

const f = (x) => (y) => x+y;
f.enviroment(); //returns {}
f(2).enviroment(); //returns { x : 2 }
const counterClosure = () => {
  let x = 0;
  return {
    add: () => { x++; },
    get: () => x,
  };
};
const counter = counterClosure();
counter.add();
counter.add.environment(); //returns { x: 1 }
counterClosure.environment(); //returns {}

Why

with combination with Function.prototype.toString this function will be useful for serializing Functions and objects.

This would shatter the only kind of privacy JS currently has, closure-based privacy. A great many security and encapsulation and robustness use cases would break if a feature like this existed.

5 Likes

We're all consenting adults here.

The closure privates are "too private". One of the usage of environment function is implement functions that need those privates. such as serializing or checking equality.

Encapsulation is not even weakly related to "security", or keeping the kids off the lawn. It is just another pattern that should be used to make a code base easier to understand.
In Some languages like python, private methods are accessible outside their class, just not easily accessible.

That mindset does not create a secure or safe language imo. There's no "too private". If you want something exposed, expose it.

I would not support anything that violates the privacy of closures, as that's one of the best features of JavaScript.

4 Likes

What is the usage of that security? What is problem with languages that does not have this privacy, such as java or python?
Encapsulation is a different matter. The access to private fields shouldn't be impossible, just it should be hard ( as in c++, java or python )
Access to private fields is not always bad. For example in making unit tests or checking eqality or serializing or ... .

Yes it is always bad. Private things should not be tested; if it needs testing, it shouldn't be private. Other languages do this wrong - which is why I'm happy that JavaScript private class fields will be "hard private" - not observable or accessible even by any form of reflection, just like closures.

2 Likes

People use closures for security-sensitive stuff like restricting DOM access for third party scripts by forging properties on window, replacing Math.random and Date.now() to disallow side-channel opportunities, and so on. If you don't trust the code that calls it to not muck with internal state and screw with your internals, closures help here. This isn't theoretical - malicious tracker scripts are a thing, and they have a knack for reading <input type="password"> fields without prejudice on the open DOM. As for how they get there, the site developer is rarely told about this, and often the immediate vendor has no idea, either. Instead, it's a malicious actor gaining access much further down the supply chain, like the event-stream issue but on steroids. This is one of the largest sources of data breaches, and it's fairly well-documented and you could easily find out more in a Google search.

It's one thing if an implementor chooses to expose closure data for inspection, but it doesn't belong in the spec and most certainly won't find much availability in browsers. We've been bit too many times with malicious actors to not be at least moderately conservative when it comes to security, and you can see this even in the HTML spec in parts.

See also https://github.com/tc39/proposal-function-implementation-hiding#the-problem for an example (not related to security only) where we want “encapsulation” to be interpreted literally, i.e., meaning “completely hidden from the outer world”.

1 Like