I have a Javascript "class" defined like so:
var Welcomer = function(name) {
var pName = name;
var pMessage = function() {
return "Hi, " + pName + "!";
};
return {
sayHi: function() {
alert(pMessage());
}
};
};
new Welcomer('Sue').sayHi();
Is there a way to "subclass" Welcomer
in such a way that I can redefine the public methods and have access to the private methods and variables? The following will give me access to the public methods, but not to the private ones:
var UnhappyWelcomer = function(name) {
var pSadMessage = function() {
// won't work, b/c I don't have access to pMessage
return pMessage() + " Miserable day, innit?";
};
return {
sayHi: function() {
alert(pSadMessage());
}
};
};
UnhappyWelcomer.prototype = Welcomer(); // failed attempt at inheritance
new UnhappyWelcomer().sayHi();
The extends keyword is used to create a child class of another class (parent). The child class inherits all the methods from another class. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.
There are two main disadvantages of overusing closures: The variables declared inside a closure are not garbage collected. Too many closures can slow down your application. This is actually caused by duplication of code in the memory.
A Closure is a combination of a function enclosed with references to its surrounding state (the lexical environment). In JavaScript, closures are created every time a function is created at run time. In other words, a closure is just a fancy name for a function that remembers the external things used inside it.
The advantage of closures in javascript is that it allows you to bind a variable to an execution context. var closedIn = {}; var f = function(){ closedIn. blah = 'blah'; // closedIn was just "closed in" because I used in the function, but it was defined outside the function. }
The simple answer to your question is No.
You can't do anything to gain access to those var
defined things, unless your function is in the same scope, or you somehow 'make public' the information (by returning it, or setting it on this
).
If you have access to edit the original function though, you could rewrite things in such a way that those functions could be "passed" into an extending function, which can alter the "protected" scope of the object. The following code should give a good idea of what I am proposing.
var Welcomer = function(name) {
var _protected = {
name: name,
message: function() {
return "Hi, " + _protected.name + "!";
}
};
return {
extendWith: function(extender) {
extender.call(this, _protected);
return this;
},
sayHi: function() {
alert(_protected.message());
}
};
};
var UnhappyWelcomer = function(name) {
var self = Welcomer(name).extendWith(function(_protected) {
_protected.sadMessage = function() {
return _protected.message() + " Miserable day, innit?";
};
// extending the public while still having scope to _protected...
this.sayHi = function() {
alert(_protected.sadMessage());
};
});
return self;
};
UnhappyWelcomer('bob').sayHi();
That "class" pattern is not a "class" pattern, it's known as a Module Pattern. It returns an object that has no ties to the function that created it other then availability of it's private variables. The returned object is NOT an instance of the function that created it.
When you call 'new Class()' it does create an instance of that function, but it also returns another object. Any further operations is actually on the returned object and not the instance.
In order to use inheritance, you really need to use prototypical inheritance properly, I suggest you read:
Further reading:
Sorry to leave you with reading material, but it seems to me you are exploring possibilities. These articles will give a deeper insight on the matter.
Once you know more on the matter, you will most likely ignore private members alltogether and use the _ prefix and just make it a public member like everyone else ;) It's just easier and private members are pointless anyways.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With