Controlling access to data in JavaScript

Controlling access to data in JavaScript

A rant about preventing access to certain methods in our code and why that's a good thing.

An Introduction

If you've ever written a piece of software that is meant to be shared and used by other developers you may have reached a point where you have some internal functionality or piece of data that is needed for the code to work but shouldn't be directly accessed, modified or played with by others.

The main reason for wanting to limit the visibility or accessibility of a function or variable is that we want to keep the door open to being able to refactor that functionality. Take the following over-simplified example:

You wrote a JavaScript library that listens to user keypresses and keeps track of the last pressed key in order to account for modifier and special behaviours. You keep an internal variable _lastKeyDown which holds the key code of the last key that triggered the keydown event. You even named it with a leading underscore to signal people not to use it, maybe even added a comment next to it asking them not to.

If people start relying on that internal variable in their code and you later decide that you would be better off handling the key events by looking at the keyup event you'd find that refactoring that code would likely break your user's code! Now you’re left with either non refactorable code, badly named variables/functions or, breaking your dear users’ integrations. This can be frustrating!

It's not my fault if they access what they're not supposed to! All the blame is on the user who ignored my rules!

Well.. yes and no.

You, as the author of the software have to keep in mind that the users integrating your piece of software into theirs will do it in the way that's most convenient or easy for them. If you are exposing a piece of functionality or data and it's conveniente for them, you can't expect them not to use it.

You can document the restriction, but if it’s there, and they need it, they will access it.

A solution

What you can do is wrap your functionality in a way that prevents them from access it without your own code losing access to those private parts. We can do this in a few different ways but personally, I like creating a block that limits encapsulates all our functionality and data, and then returning a public API for users to integrate and access.

To illustrate this with an even simpler snippet

let myFantasticJSLibrary = (function internalName(){
    var myPrivateVar = 42;
    
    return {
        myPublicMethod : function() { return myPrivateVar; }
    }
})();

Notice how when accessing myFantasticJSLibrary the user will not know of the existence of myPrivateVar but will see myPublicMethod . This allows us to keep control of the private part for pain-free refactoring in future versions. We are not trying to be obscure about what we are doing under the hood, we are trying to prevent the user from relying on something that can be gone tomorrow.

Of course anyone with access to the source code could see it’s there, and could modify it but that’s a totally different problem. They modified our software, it’s not our problem to maintain or solve the issues that may arise from doing so.

In summary anything that’s not included directly in the returned object will not be visible for the integrating developer. However, due to the nature of closure of javascript, our own returned object has access to anything that is referenced inside internalName. This is a very powerful yet often overlooked behaviour in JavaScript

要查看或添加评论,请登录

Juan Cortés Ross的更多文章

社区洞察

其他会员也浏览了