I'm trying to get a deeper hold on prototypal inheritance and class creation (I know, there are other ways, but for the purpose of this I'm trying to grasp prototypes.) My question is: Using the following code example, is there a way to create private variables inside of Tree
and Fruit
that will not be returned with the function, but is still accessible to the prototype functions genus
and bulk
?
var Tree = function ( name, size ) {
this.name = name;
this.size = size;
};
Tree.prototype.genus = function(){
return ((typeof this.name !== 'undefined') ? this.name : 'Hybridicus Maximus');
};
Tree.prototype.bulk = function(){
return ((typeof this.size !== 'undefined') ? this.size : '8') + ' ft';
};
var Fruit = function( name, size ) {
this.name = name;
this.size = size;
};
Fruit.prototype = new Tree();
// Fruit.prototype = Tree.prototype; -- I know this can be used, too.
Fruit.prototype.bulk = function(){
return ((typeof this.size !== 'undefined') ? Math.floor(this.size / 2) : '4') + ' lbs';
};
var pine = new Tree('Pine', 9);
var apple = new Fruit('Apple', 6);
console.log(pine.genus(), pine.bulk()); // Outputs: "Pine 9 ft"
console.log(apple.genus(), apple.bulk()); // Outputs: "Apple 3 lbs"
EDIT: I'm trying to replace this.name
and this.size
with private variables that can be accessed in the prototype functions. Sorry for the lack of clarity!
We can access a private variable in a different class by putting that variable with in a Public method and calling that method from another class by creating object of that class.
So the private variable cannot been seen and accessed from outside the scope of the constructor. But inside it you can alter it, log it, pass it to a function, reassingn it like you want.
We cannot access a private variable of a class from an object, which is created outside the class, but it is possible to access when the same object is created inside the class, itself.
Private: The class members declared as private can be accessed only by the functions inside the class. They are not allowed to be accessed directly by any object or function outside the class.
Yes. You can do this:
(function() {
var private = "hi";
Tree.prototype.genus = function(){
return ((typeof this.name !== 'undefined') ? this.name : 'Hybridicus Maximus');
};
Tree.prototype.bulk = function(){
return ((typeof this.size !== 'undefined') ? this.size : '8') + ' ft';
};
})();
Now, that'll provide a private variable that those functions can see, but it'll be a private "class" variable - all instances will share the same variable, in other words. If you want a private variable per instance, you have to do that in the constructor (or "init" method, or whatever), meaning the methods that share those privates would also have to be created there. (You could of course put a function on the prototype that would create the instance methods at construction time.)
edit — One thing you could do is use a technique like this to build a mechanism like jQuery's ".data()", so that you'd have a class variable that acts as a place to keep per-instance values. It'd be kind-of clunky, but it'd be workable.
This is what I wrote about in a blog post about Classes, Private Members, & Prototypal Inheritance in JavaScript. Basically you want to create a private variable accessor function unique to every object and then have those prototype methods call that private accessor function, supplying it with the key that is only available within the closure:
(function(_) {
Tree = function ( name, size ) {
var hidden = {
name: name,
size: size
};
this._ = function($) {
return _ === $ && hidden;
};
};
Tree.prototype.genus = function(){
return ((typeof this._(_).name !== 'undefined') ? this._(_).name : 'Hybridicus Maximus');
};
Tree.prototype.bulk = function(){
return ((typeof this._(_).size !== 'undefined') ? this._(_).size : '8') + ' ft';
};
Fruit = function( name, size ) {
Tree.apply(this, arguments);
};
Fruit.prototype = new Tree();
// Fruit.prototype = Tree.prototype; -- I know this can be used, too.
Fruit.prototype.bulk = function(){
return ((typeof this._(_).size !== 'undefined') ? Math.floor(this._(_).size / 2) : '4') + ' lbs';
};
})({});
var pine = new Tree('Pine', 9);
var apple = new Fruit('Apple', 6);
console.log(pine.genus(), pine.bulk()); // Outputs: "Pine 9 ft"
console.log(apple.genus(), apple.bulk()); // Outputs: "Apple 3 lbs"
console.log(pine._(), pine._({})); // Outputs: "false false" because outside of closure
You will notice that the last line shows that private variables are not accessible outside of the closure and thusly can't be retrieved by third-party code unless made available by an accessor function.
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