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
}
}
}
Related
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.
Following a rapid-prototyping approach, I am developing an application in Marionette.js/backbone.js and heavily used the window-object to bind collections and views to the global stack (e.g. window.app.data, window.app.views).
Of course, it is always better (smoother!) to encapsulate objects in a single class and pass them as parameters where needed. However, this has some limitations when an app and its potential use-cases become really big. And as the data I deal with comes from an API and therefore would be anyway accessible to anybody interested, does that justify storing data in the window-object? Or are there other best-practices in ES6 (or especially Marionette.js) to achieve the same results, but in a more private manner?!
I already go into details about a simple namespacing pattern in JavaScript in another answer. You seem to be already close to this with window.app.data etc.
But it looks like you have a lot of misconceptions about how JavaScript works.
a namespace-based solution that integrates nicely with Browserify/AMD-modules
Then why not use RequireJS? Browserify? or Webpack? There's nothing that a global ridden spaghetti code can do that a modular approach can't do better.
such would be read-only
No. While not impossible to set an object property to read-only, you must explicitly do it with something like Object.seal or Object.freeze.
I do not want to attach objects to the namespace, but actual instances
JavaScript do not have "namespaces" as part of the language, it's just a pattern to scope all your code within literal objects (key-value).
You can put whatever you'd like.
const MyNamespace = {
MyType: Backbone.Model.extend({ /*...*/ }),
instance: new Backbone.Model(),
anyValue: "some important string",
};
Ideally, you would define the namespace within an IIFE to avoid leaking any variable to the global scope.
const app = app || {};
app.MyModel = (function(app){
return Backbone.Model.extend({
// ...
});
})(app);
[...] data I deal with comes from an API and therefore would be anyway accessible to anybody interested
Even if the data is contained within a module that do not leak to the global scope, anybody can access the data. That's how JavaScript works, it's in the user's browser, he can do whatever he wants with the code and the data.
does that justify storing data in the window-object?
No.
Or are there other best-practices in ES6
ES6 has nothing to do with the architecture and patterns you take for your app.
but in a more private manner?!
Like I said earlier, privacy in JavaScript can't be expected.
[encapsulate objects in a single class and pass them as parameters where needed] has some limitations when an app and its potential use-cases become really big.
That's just incorrect. It's the other way around. Software patterns exist solely to help alleviate any limitations that arise as a project grows in scope.
There are multiple patterns you can use that will help deal with the complexity of a bigger app, like:
Modular approach with components
Dependency injection
Service containers
Factories
Events
etc.
I didn't read specifically this book, but JavaScript Design Patterns seems to be a good way to learn more and it demonstrates specific implementations of software patterns in JS.
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.
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?
I've heard that it's not a good idea to make elements global in JavaScript. I don't understand why. Is it something IE can't handle?
For example:
div = getElementById('topbar');
I don't think that's an implementation issue, but more a good vs bad practice issue. Usually global * is bad practice and should be avoided (global variables and so on) since you never really know how the scope of the project will evolve and how your file will be included.
I'm not a big JS freak so I won't be able to give you the specifics on exactly why JS events are bad but Christian Heilmann talks about JS best practices here, you could take a look. Also try googling "JS best practices"
Edit: Wikipedia about global variables, that could also apply to your problem :
[global variables] are usually
considered bad practice precisely
because of their nonlocality: a global
variable can potentially be modified
from anywhere, (unless they reside in
protected memory) and any part of the
program may depend on it. A global
variable therefore has an unlimited
potential for creating mutual
dependencies, and adding mutual
dependencies increases complexity. See
Action at a distance. However, in a
few cases, global variables can be
suitable for use. For example, they
can be used to avoid having to pass
frequently-used variables continuously
throughout several functions.
via http://en.wikipedia.org/wiki/Global_variable
Is it something IE can't handle?
No it is not an IE thing. You can never assume that your code will be the only script used in the document. So it is important that you make sure your code does not have global function or variable names that other scripts can override.
Refer to Play Well With Others for examples.
I assume by "events" you mean the event-handling JavaScript (functions).
In general, it's bad to use more than one global variable in JS. (It's impossible not to use at least one if you're storing any data for future use.) That's because it runs into the same problem as all namespacing tries to solve - what if you wrote a method doSomething() and someone else wrote a method called doSomething()?
The best way to get around this is to make a global variable that is an object to hold all of your data and functions. For example:
var MyStuff = {};
MyStuff.counter = 0;
MyStuff.eventHandler = function() { ... };
MyStuff.doSomething = function() { ... };
// Later, when you want to call doSomething()...
MyStuff.doSomething();
This way, you're minimally polluting the global namespace; you only need worry that someone else uses your global variable.
Of course, none of this is a problem if your code will never play with anyone else's... but this sort of thinking will bite you in the ass later if you ever do end up using someone else's code. As long as everyone plays nice in terms of JS global names, all code can get along.
There shouldn't be any problem using global variables in your code as long as you are wrapping them inside a uniqe namespase/object (to avoid collision with scripts that are not yours)
the main adventage of using global variable in javascript derives from the fact that javascript is not a strong type language. there for, if you pass somes complex objects as arguments to a function, you will probebly lose all the intellisence for those objects (inside the function scope.)
while using global objects insteads, will preserve that intellisence.
I personally find that very usfull and it certainly have place in my code.
(of course, one should alwayse make the right balance between locales and globals variables)