Created
March 20, 2013 16:24
-
-
Save creationix/5206044 to your computer and use it in GitHub Desktop.
Idea to make private properties and methods non-enumerable instead of prefixing them with underscores (in ES5 and above environments of course)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Object.defineProperty(Object.prototype, "hide", { | |
value: function () { | |
[].forEach.call(arguments, function (name) { | |
var descriptor = Object.getOwnPropertyDescriptor(this, name); | |
if (descriptor.enumerable) { | |
descriptor.enumerable = false; | |
Object.defineProperty(this, name, descriptor); | |
} | |
}, this); | |
} | |
}); | |
function Rectangle(w, h) { | |
this.w = w; | |
this.h = h; | |
// For some reason, we want "w" and "h" to be private properties | |
this.hide("w", "h"); | |
} | |
Rectangle.prototype.privateMethod = function () {}; | |
Rectangle.prototype.hide("privateMethod"); |
I can think of a couple special case uses for this. Just glancing at it, I was wondering if this wouldn't be safer if line 5 were instead:
if (descriptor.enumerable && descriptor.configurable) {
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@creationix I usually distinguish privacy in few different ways:
_private
that communicates that property is private and changes to it fromthe external may cause unpredictable reactions. For this purpose
_
prefix works very well, and in fact markingsuch properties non-enumerable is has risks of other changing them by accident. Of course later comment may
or may not apply to your case.
by derivee).
In SDK we use weak-maps for private properties since capability leak is a real issue and can cause harm. In personal projects I rarely have such concerns and mostly care about name collisions and use following technique for making names unique:
This also goes well along with private names that may or may not happen one day.
Finally I'm starting to drift more and more in favor of using polymorphic functions for designing APIs
that avoid name collisions and have all the function composibily advantages:
The best part is here is that all the code deals with just
width
andheight
functions that can be passeda rectangle or anything that implements these functions. And implementation is type / instance specific.
Even better functions definitions are independent of type definitions and there for different types can
implement same interface (by which a mean set of polymorphic functions) without being aware of each
other. Even better you can define definitions for types from other libraries to make them API compatible: