Should I care about private members in JavaScript - javascript

I know that JavaScript doesn't support private members, but you can emulate those. I'm wondering here is that if it's worth it. Is there a point in making variables and/or functions private in JavaScript?

Is there a point in making variables and/or functions private in JavaScript?
I would argue ‘no’... and ‘no’ in more languages than merely JavaScript.
Information-hiding and encapsulation is all very commendable, but unless you have security boundaries inside your application, you don't actually need to enforce privateness with strict language-level limits. Who is the untrusted attacker you're protecting your code from? Yourself? Others in your team?
In a Java environment you might theoretically be writing a class to give limited access to a resource to a sandboxed party like an applet. In that case you wouldn't want the applet code to be able to mess with private members as it might transgress over a security boundary.
But in JavaScript this isn't possible. You get one security context per host:port and you can't create effective security boundaries to limit code that shares your context. The ability to hide a variable is pretty meaningless when any JS code can completely take over the page's UI. (Plus, some browsers have occasionally had features that defeat private variables, for example Mozilla's old, now-removed __caller__.)
Consider instead the Python way: have a convention for effectively-private, even if the language doesn't enforce it. Putting an underscore at the beginning of a member name is warning enough that class-users shouldn't be messing with that member, but doesn't make yourself a load of annoying extra work when you're debugging or prototyping and need to temporarily ignore the privateness.

Here is the stackOverflow answer about how to do this in circumstances when you would want to:
JavaScript private methods
And here is an article about signing that does include an expert's quote:
'On the other hand, because JavaScript has no concept of public and private methods, there are no internal methods that could be protected by simply signing a class. In addition, all methods can be changed at runtime, so must be protected at runtime.
In JavaScript you can add new properties to existing objects, or replace existing properties (including methods) at runtime. You cannot do this in Java. So, once again, protection that is automatic in Java must be handled separately in JavaScript.'
in the article at
http://docs.sun.com/source/816-6409-10/sec.htm
However, I would imagine that using private variables and methods might have some functionality in terms of resolving methods and variables that have the same signature but are in different classes, or not?

Related

Accessing private variables defined with WeakMap inside a derived class

I'm using the common WeakMaps pattern to emulate private variables inside es6 classes, but I cannot find a way to have "protected" variables, meaning variables that are private and that can be accessed through derived classes, eg:
var Window = (function() {
const _private = new WeakMap();
const internal = (key) => {
// Initialize if not created
if (!_private.has(key)) {
_private.set(key, {});
}
// Return private properties object
return _private.get(key);
};
class Window {
constructor() {
// creates a private property
internal(this).someProperty = "value";
}
}
return Window;
})();
If I create a subclass using the same pattern, how can I access someProperty in the subclass without having to define a getter method in the base class (thus completely defeating the whole purpose of having weakmaps for private properties) ?
If there's no elegant solution by using this pattern, what would be the best course of action to take?
I'm building a webapp which can have various "layered windows" displaying various products, loaded from a different script that makes few requests to .php endpoints to gather this information.
The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions
from a security standpoint most requests to other APIs would be done from a separate script handling validation of the payload so what I'm really trying to accomplish is to make reusable Window classes that can use some sort of "protected" variables across derived classes since it would definitely help me in the process of building this particular type of GUI
The library itself is not intended to be a public library for everyone to get access to, at most other team-mates might have to edit parts of it but they would still respect the defined patterns/conventions
From the description of what you're really trying to do that you added to your question, it sounds like this isn't a "security" issue per se, but rather you're looking for the best programming implementation/convention for your local team that will be using this interface so that it will be clear to other developers which state is "protected" and for use only inside the implementation and not from the outside consumers of the objects.
If that's the case, I'd just go with the underscore convention where a property name on the object that starts with an underscore as in this._someProperty is meant only for internal use in the methods of the object itself (analogous to "protected" members in C++) and not for external use by consumers or users of the object.
Then communicate that in the doc for the implementation and verbally with the team you work with to make sure everyone not only understands that convention in the code you write, but so that they can also consistently use the same convention in their code.
Since it doesn't appear you have an actual security need here, the reasons to go with this type of leading underscore "convention" instead of more involved solutions that provide some real protection of the data from other developers (like what you were attempting to do):
Implementation is simpler
There is no performance degradation
Does not interfere with modularity and putting derived classes in separate files
Infinitely extensible to as many properties, as many classes
Easier to educate the team you're working with on how to do it
A saying once shared with me by a senior developer was that "my code should be as simple as it can be to meet the objectives (correctness, stability, testability, maintainability, extensibility and reuse)". This helped me to strive for simplicity in implementation and avoid over designing beyond what is actually needed.

Examples of cases where using private variable/methods in oop languages is useful/necessary [duplicate]

This question already has answers here:
Why "private" methods in the object oriented?
(9 answers)
Why encapsulation is an important feature of OOP languages? [closed]
(5 answers)
Closed 9 years ago.
Whenever I try to research this question the answer usually presented is along the lines of "so the outside world does not have direct access to the local variables." What's missing here for me is the context to which this applies. I get that, for instance, in the code below
function Person(firstName, lastName) {
var _firstName = firstName,
_lastName = lastName;
this.firstName = function(value) {
if (!arguments.length) return _firstName;
_firstName = value;
}};
the variables are considered private because they can only be accessed from calling the functions. What is the significance of this? Why does it matter? And most achingly mysterious is what is a "real life" situation in which the common explanation of "so the outside world does not have direct access to the local variables..." would apply/make sense to someone who has not seen a situation where it matters.
Thanks SO.
It's all to ease development.
Only public properties or methods of objects are accessible to "outside code", i.e. any code that uses an object, accesses its properties or calls its methods can only use the public interfaces of said object. When code uses the public interface in any way, you get code coupling. When you declare a method foo on your object/class, and somewhere in your code you have obj.foo(), that line of code is now coupled to the existence of the foo method. If you want to remove or change the foo method, you (probably) also have to change every line of code that calls it.
Protected and private properties and methods are pieces of code which are explicitly only usable by the class/object itself. "Outside code" cannot couple to it, neither purposefully nor accidentally. When you need to refactor that code, you can be sure the changes are isolated to within the class itself and not worry about possibly breaking tons of other code.
Protected and private properties also don't run the risk of being modified by outside code in an incorrect way. A private property can only be modified by the class/object itself, so the class/object itself is always in full control of the value of that property. This ensures a consistent state of the object.
Therefore, a class/object should keep its public interface to a minimum and keep everything that's not intended or necessary for "public consumption" private. This allows you to focus on your class design in terms of what needs to be public for an object to be useful, and keep the rest of the implementation flexible.
In an OO language, classes should expose behaviour and hide implementation. That's called encapsulation, makes reutilization easier, and is one of the bases of OO.
Generally speaking, variables are part of implementation and not of behaviour. That's why, normally, you don't declare them public.
An example from "real life" is any API you have to interact with (i.e. Amazon REST API). Your work as a developer is easier, if you only have to learn behaviour details (public methods), than if you had to learn the usage of every internal variable of the site. Also, if client code only interacts with the behaviour (again, public methods) of a system, the system may change (i.e. optimize) it's implementation without affecting it's users.

Is there a "typical" usage for private variables?

First, my experience with JavaScript is limited to web development and a little self-study. I want to understand the point of having private members in JavaScript. Take an example,
var myObject = {
WriteWord: function() {
var secret = 'word';
document.writeln(secret);
}
};
myObject.WriteWord();
Private variable secret cannot be seen by the caller. AFAIK, I can notify potential callers of the existence of WriteWord in a few ways:
Document the code. Like jQuery does.
For .NET guys, write a custom visual studio intellisense plugin.
Read the code directly.
Now let's say I minify and even obfuscate the code. Its now unreadable. In my mind, given this scenerio, a lack of documentation is just as good as a private variable.
Is this scenerio uncommon or somehow wrong? What is the importance of private variables in JavaScript?
The whole purpose of encapsulation and private variables, in Javascript or any other language, is to restrict yourself in a way that allows the implementation of a class to be changed at any time without breaking the rest of the code. You can rename secret to any other name or completely remove it and be sure that the code would continue to correctly work.
On the other hand, a public method is a point of coupling between the producer and the consumer and you can't easily change the public interface, method names or arguments without risking to break other parts of the program that depend on it. (This is completely unrelated to wether the code has been obfuscated or how weel docomented it is - if someone is using a public method the coupling will already be there)
Scoping variables carefully in JavaScript eliminates the possibility of another script on your page clobbering a variable.
This becomes a valid concern when working with many different JavaScript libraries/files from possibly many different programmers.
Local ("private") variables are very useful to keep the code readable. Not only because of descriptive names, but also because a developer don't have to keep track of 1000+ variable names.
Also, some variables shouldn't be able to be changed "from the outside". Consider:
function (){
var password = "random word";
window.passwordAsker = function(){
var asked = prompt("Password?", "");
if(asked == password) {
alert("Access granted"); //This should NOT be a real verification method
}
}
}

The disadvantages of JavaScript prototype inheritance, what are they?

I recently watched Douglas Crockford's JavaScript presentations, where he raves about JavaScript prototype inheritance as if it is the best thing since sliced white bread. Considering Crockford's reputation, it may very well be.
Can someone please tell me what is the downside of JavaScript prototype inheritance? (compared to class inheritance in C# or Java, for example)
In my experience, a significant disadvantage is that you can't mimic Java's "private" member variables by encapsulating a variable within a closure, but still have it accessible to methods subsequently added to the prototype.
i.e.:
function MyObject() {
var foo = 1;
this.bar = 2;
}
MyObject.prototype.getFoo = function() {
// can't access "foo" here!
}
MyObject.prototype.getBar = function() {
return this.bar; // OK!
}
This confuses OO programmers who are taught to make member variables private.
Things I miss when sub-classing an existing object in Javascript vs. inheriting from a class in C++:
No standard (built-into-the-language) way of writing it that looks the same no matter which developer wrote it.
Writing your code doesn't naturally produce an interface definition the way the class header file does in C++.
There's no standard way to do protected and private member variables or methods. There are some conventions for some things, but again different developers do it differently.
There's no compiler step to tell you when you've made foolish typing mistakes in your definition.
There's no type-safety when you want it.
Don't get me wrong, there are a zillion advantages to the way javascript prototype inheritance works vs C++, but these are some of the places where I find javascript works less smoothly.
4 and 5 are not strictly related to prototype inheritance, but they come into play when you have a significant sized project with many modules, many classes and lots of files and you wish to refactor some classes. In C++, you can change the classes, change as many callers as you can find and then let the compiler find all the remaining references for you that need fixing. If you've added parameters, changed types, changed method names, moved methods,etc... the compiler will show you were you need to fix things.
In Javascript, there is no easy way to discover all possible pieces of code that need to be changed without literally executing every possible code path to see if you've missed something or made some typo. While this is a general disadvantage of javascript, I've found it particularly comes into play when refactoring existing classes in a significant-sized project. I've come near the end of a release cycle in a significant-sized JS project and decided that I should NOT do any refactoring to fix a problem (even though that was the better solution) because the risk of not finding all possible ramifications of that change was much higher in JS than C++.
So, consequently, I find it's riskier to make some types of OO-related changes in a JS project.
I think the main danger is that multiple parties can override one another's prototype methods, leading to unexpected behavior.
This is particularly dangerous because so many programmers get excited about prototype "inheritance" (I'd call it extension) and therefore start using it all over the place, adding methods left and right that may have ambiguous or subjective behavior. Ultimately, if left unchecked, this kind of "prototype method proliferation" can lead to very difficult-to-maintain code.
A popular example would be the trim method. It might be implemented something like this by one party:
String.prototype.trim = function() {
// remove all ' ' characters from left & right
}
Then another party might create a new definition, with a completely different signature, taking an argument which specifies the character to trim. Suddenly all the code that passes nothing to trim has no effect.
Or another party reimplements the method to strip ' ' characters and other forms of white space (e.g., tabs, line breaks). This might go unnoticed for some time but lead to odd behavior down the road.
Depending on the project, these may be considered remote dangers. But they can happen, and from my understanding this is why libraries such as Underscore.js opt to keep all their methods within namespaces rather than add prototype methods.
(Update: Obviously, this is a judgment call. Other libraries--namely, the aptly-named Prototype--do go the prototype route. I'm not trying to say one way is right or wrong, only that this is the argument I've heard against using prototype methods too liberally.)
I miss being able to separate interface from implementation. In languages with an inheritance system that includes concepts like abstract or interface, you could e.g. declare your interface in your domain layer but put the implementation in your infrastructure layer. (Cf. onion architecture.) JavaScript's inheritance system has no way to do something like this.
I'd like to know if my intuitive answer matches up with what the experts think.
What concerns me is that if I have a function in C# (for the sake of discussion) that takes a parameter, any developer who writes code that calls my function immediately knows from the function signature what sort of parameters it takes and what type of value it returns.
With JavaScript "duck-typing", someone could inherit one of my objects and change its member functions and values (Yes, I know that functions are values in JavaScript) in almost any way imaginable so that the object they pass in to my function bears no resemblance to the object I expect my function to be passed.
I feel like there is no good way to make it obvious how a function is supposed to be called.

What does XPCSafeJSObjectWrapper do?

What does Mozilla Firefox's XPCSafeJSObject wrapper actually do?
MDC's documentation is as follows:
This wrapper was created to address some problems with XPCNativeWrapper. In particular, some extensions want to be able to safely access non-natively-implemented content defined objects (and to access the underlying JavaScript object under an XPCNativeWrapper without its strong behavior guarantees). XPCSJOW act as a buffer between the chrome code.
This doesn't tell me a lot. In particular, I can't tell how accessing objects via XPCSafeObject is any different to accessing them directly.
Edit: I understand that the purpose of the wrappers in general is to protect privileged code from unprivileged code. What I don't understand (and doesn't seem to be documented) is how exactly XPCSafeJSObject does this.
Does it just drop privileges before accessing a property?
Actually XPCSafeJSObjectWrapper is used for all content objects, including windows and documents (which is in fact where it's most usually needed.) I believe it was invented mainly to stop XSS attacks automatically turning into privilege escalation attacks (by doing XSS against the browser itself). At least now if an XSS attack is found (and people will unfortunately keep looking) it doesn't compromise the whole browser. It's a natural development from the XPCNativeWrapper which was originally a manual (and therefore prone to accidental misuse by extensions) way for the browser to defend itself from XSS attacks.
The wrapper just ensures that any code that gets evaluated gets evaluated without chrome privileges. Accessing objects directly without this wrapper can allow for code to run with chrome privileges, which then lets that code do just about anything.
The purpose of the wrappers in general is to protect Privileged code when interacting with unprivileged code. The author of the unprivileged code might redefine a JavaScript object to do something malicious, like redefine the getter of a property to execute something bad as a side effect. When the privileged code tries to access the property it would execute the bad code as privileged code. The wrapper prevents this. This page describes the idea.
XPCSafeJSObject provide a wrapper for non-natively implemented JavaScript objects (i.e. not window, document, etc. but user defined objects.)
Edit: For how it's implemented, check out the source code (it's not loading completely for me at the moment.) Also search for XPCSafeJSObject on DXR for other relevant source files.

Categories

Resources