Public and Privileged methods in javascript: Why are they called that way?
If I understand correctly, according to Douglas Crockford http://javascript.crockford.com/private.html, the "privileged" methods are similar to what we know as "public" methods. and "public" methods are something that's a bit different.
Here's how I understand it:
"Privileged" methods can access private variables since it is defined inside the closure when the rest of the private variables were defined.
var C = function(){
var private;
this.privilegedMethod = function(){
/* blah blah */
};
}
var cObj = new C();
"Public" methods are the ones that are added to the object outside of the object itself, through prototype.
var C = function(){
/* blah blah */
}
C.prototype.publicMethod = function(){
/* blah blah */
};
var cObj = new C();
I find these definitions of "privileged" and "public" very confusing. I think the "privileged" method is nothing more than actually a public method as we know it from object oriented programming. And I think the "public" method is the one that should be named as something else. If you think about it, it's a weird type of function, it's a member of the object but it cannot access any other private variables, which means it doesn't contribute to encapsulation. It's almost like an independent helper method for the object.
So I was wondering, why did Douglas Crockford come up with these confusing terms? And why have the javascript community adopted these terminologies? Or if I'm wrong about something, please correct me.
Since there are no scope modifiers like public/private/protected in JavaScript, in order to come close to the OOP world, Douglas Crockford is using such names, not to confuse anyone coming from, lets say Java
The privileged method can see variables, defined inside the function (An important note here - in JavaScript, the only scope is function scope. There's no block scope) so they are "privileged". Yes, they can be called from an object instance, but the important thing here is, that they see all the stuff, declared with var
(the real private stuff)
On the other hand, public methods, that are attached to the prototype of the object have one more important thing - they are evaluated once and seen for all instances of the given object.
If you use the this
keyword inside a prototype method, it will point to the current instance of the Object but you will be able to see only things, that are defined within this
.
I don't know if it gets clear, but the main thing here is that JavaScript is prototype based language and the prototype chain was introduced in the language in order to make inheritence possible.
Vlad, I agree with you : I am confused too! Look here (from http://javascript.crockford.com/private.html):
function Container(param) {
// methode privee
function dec() {
console.log('private method is looking for private member secret : ' + secret);
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
// membres privées
var secret = 3;
var that = this;
// méthode privilégiée
this.service = function () {
console.log('priviligied method is looking for private member secret : ' + secret);
return dec() ? that.member : null;
};
// membres publiques
this.member = param;
}
var myContainer = new Container('abc');
Container.prototype.stamp = function (string) {
console.log('public method is looking for private member secret : ' + this.secret);
return this.member + string;
}
console.log(myContainer.stamp('def'));
//for (i=0;i<4;i++)
console.log(myContainer.service());
priviliged vs public
This jsfiddle sample will display :
public method is looking for private member secret : undefined
abcdef
priviligied method is looking for private member secret : 3
private method is looking for private member secret : 3
abc
So, the answer : public methods <=> priviliged methods isn't it?
In a traditional OOP language, all of the members of a class have access to all of the other members of a class.
This is not the case in Javascript. A public method may have access to private data that none of the other members of the class (viz. constructor function) know about. Equally, other members of the class may have data that the method cannot see.
Consider below:
function TheirTrait() {
var privateData = "foo";
this.privilegedMethod = function() {
return privateData;
}
}
function MyClass() {
var privateData = undefined;
this.publicMethod = function() {
return privateData;
}
TheirTrait.apply(this, arguments);
}
var myObject = new MyClass();
myObject.privilegedMethod() // returns "foo"
myObject.publicMethod() // returns undefined
As you can see, both publicMethod
and privilegedMethod
are public in the sense that they can both be accessed externally, but privilegedMethod
has access to additional data.