Reputation: 6054
I have this:
function Book (){
this.width = 7;
this.height = 10;
var pages = 100;
this.tear_page = function(){
return --pages;
}
}
function TechBook () {
var pages = 50;
this.open_book = function(){ return "Opened in page "+(pages/2); };
return this;
}
var bBook = Object.create(new Book(), new TechBook());
console.log(bBook);
console.log(bBook.tear_page());
console.log(bBook.open_book());
I can't get this to work. I got as far as getting TechBook to inherit the access to local/private variables from Book but only from the Book functions. If I add new methods or overwrite them, they can't get those variables any more. I wonder if there is a way to still have access to those variables from methods of the subclass and to create new private variables inside the subclass.
If this is not posible in any way, that would mean that you can't have private variables if you want inheritage, or viceversa. Oh, and btw, I know that chrome can now (thanks to ES6) implement classes naturally with: class TechBook extends Book (){} as many other languages, but as support is limited to last versions of chrome at this time... I wonder if there is any other way to solve this problem.
Upvotes: 3
Views: 1374
Reputation: 2865
Reference to fundamentals of prototype inheritance and Object.create property arguments.
Implemented based on your example
function Book (){
this.width = 7;
this.height = 10;
this.pages = 100;
this.tear_page = function(){
return --this.pages;
}
this.init = function() {
return this
}
}
Book.prototype = {
open_book: function(){ return "Opened in page "+(this.pages/2) }
}
var bBook = Object.create(new Book(), {pages: { value: 50 } }).init();
console.log( new Book()) // { width: 7, height: 10, pages: 100, tear_page: [Function], init: [Function] }
console.log( bBook ) //{}
console.log( bBook.width ) //->7
console.log( bBook.height ) //-> 10
console.log( bBook.pages ) // -> 50
console.log( bBook.tear_page()) //-> 49
console.log(bBook.open_book()) //-> Opened in page 25
Upvotes: 1
Reputation: 2809
You can't inherit private in any language, only protected or public can be inherited.
That concept does not exist in javascript but u can emulate when creating an object (properties = public, scope things = private);
A work around could be add a property that execute a function that return the private variable/function of the object scope.
If expose a method that return a private object it can be modified because u have the returned reference.
I like to do it like this:
var SomeObject = function() {
//private var one, can't access it outside of this scope
var one = 1;
/*private object anotherObject, can't access it directly
but if you return it with a public function you can modify it.*/
var anotherObject = {
a : 'somevalue'
};
//public prop two, can access it outside of this scope.
this.two = 2;
//public method getOne, you can access it.
this.getOne = function() {
return one;
};
/* return private var anotherObject */
this.getAnotherObject = function() {
return anotherObject;
};
};
var someObject = new SomeObject();
console.log(someObject.two); // print in console 2
console.log(someObject.getOne()); // print in console 1
var referencedObject = someObject.getAnotherObject();
console.log(referencedObject);
referencedObject.a = 'anotherValue';
console.log(someObject.getAnotherObject());
Upvotes: 5
Reputation: 66334
Here is an example of how you might pass data by knowing a secret
function Book(secret) {
secret = secret || {};
var env = {}; // `env` to hold data requiring `secret`
this.width = 7;
this.height = 10;
env.pages = 100;
this.getEnv = function (s) { // give access to `env` if you know the secret
if (s === secret) return env;
};
this.tear_page = function () {
return --env.pages;
};
}
function TechBook(secret) {
secret = secret || {};
Book.call(this, secret); // construct from Book
var env = this.getEnv(secret); // get references via secret
this.open_book = function () {
return "Opened in page " + (env.pages/2);
};
}
TechBook.prototype = Object.create(Book.prototype); // set up inheritance
Using an Object reference as the secret will be more secure than using a primitive as you'll need the original reference for access.
Now you have
var bBook = new TechBook();
console.log(bBook); // instance of TechBook
console.log(bBook.tear_page()); // 99
console.log(bBook.open_book()); // Opened in page 49.5
Upvotes: 2