Problems with prototype inheritance

B

beseecher

Hi,

In my research in the javascript language I have encountered problems
with implementing prototype inheritance while preserving private
methods
functioning properly. Here is an example:

function A(){
var _this = this;
this.a = 10;
var privateFunc = function(){
alert(_this.a)
}
this.publicFunc = function(){
this.a = 20;
privateFunc();
}
}

function B(){
this.publicFunc();
}

B.prototype = new A();
b = new B();

The expected popup window produced from the following code (alert)
should show 20. Yet it shows 10.

Here we have 2 Class (or rather constructor functions): A, B;

----------------
Class (Constructor) A defines:
----------------
- _this - a private field reflecting "this". It is a local variable
necessary so that "this" can be used in private functions. Otherwise
in such private functions, "this" references to the window object
(i.e. the global javascript object);

- this.a - public field;

- privateFunc - private method of class A;

- this.publicFunc - public method of class A;

Upon instantiation, Class (Constructor) B simply calls the public
method of class A (i.e. publicFunc). publicFunc is referenced from B
through the prototype chain.

The problem, as I see it, is that in this scenario there are two
objects:

B.prototype = new A();
b = new B();

which are instances of class A and class B respectively.
When new A() is called, _this points to this instance (referenced by
B.prototype)
When new B() is called, a seperate object is created (referenced by
b).
When new B() is called, B calls this.publicFunc() where "this" is
actually
the new B object passed to publicFunc() through the prototype chain.
So this new "this", passed from B to publicFunc, is different from
"this" that
was created from the new A() expression. That is why _this (pointing
to "this"
created through new A()) does not coincide with "this" passed from
B(). That's why
this.a is created and attached to object b which is different from
this.a created
through the call of new A(), where _this points.


I see this as a problem to implementing prototype chain inheritance
and use private
methods at the same time (which helps proper encapsulation as required
by OO design).

What do you guys think about this?
 
D

Douglas Crockford

Hi,

In my research in the javascript language I have encountered problems
with implementing prototype inheritance while preserving private
methods
functioning properly. Here is an example:

function A(){
var _this = this;
this.a = 10;
var privateFunc = function(){
alert(_this.a)
}
this.publicFunc = function(){
this.a = 20;
privateFunc();
}
}

function B(){
this.publicFunc();
}

B.prototype = new A();
b = new B();

The expected popup window produced from the following code (alert)
should show 20. Yet it shows 10.

Here we have 2 Class (or rather constructor functions): A, B;

----------------
Class (Constructor) A defines:
----------------
- _this - a private field reflecting "this". It is a local variable
necessary so that "this" can be used in private functions. Otherwise
in such private functions, "this" references to the window object
(i.e. the global javascript object);

- this.a - public field;

- privateFunc - private method of class A;

- this.publicFunc - public method of class A;

Upon instantiation, Class (Constructor) B simply calls the public
method of class A (i.e. publicFunc). publicFunc is referenced from B
through the prototype chain.

The problem, as I see it, is that in this scenario there are two
objects:

B.prototype = new A();
b = new B();

which are instances of class A and class B respectively.
When new A() is called, _this points to this instance (referenced by
B.prototype)
When new B() is called, a seperate object is created (referenced by
b).
When new B() is called, B calls this.publicFunc() where "this" is
actually
the new B object passed to publicFunc() through the prototype chain.
So this new "this", passed from B to publicFunc, is different from
"this" that
was created from the new A() expression. That is why _this (pointing
to "this"
created through new A()) does not coincide with "this" passed from
B(). That's why
this.a is created and attached to object b which is different from
this.a created
through the call of new A(), where _this points.


I see this as a problem to implementing prototype chain inheritance
and use private
methods at the same time (which helps proper encapsulation as required
by OO design).

What do you guys think about this?

Constructors that introduce privileged methods are, in a sense, final.
The parasitic pattern is effective in this case.

http://javascript.crockford.com/
 
R

Richard Cornford

I see this as a problem to implementing prototype chain
inheritance and use private methods at the same time
(which helps proper encapsulation as required by OO design).

Is popper encapsulation required by OO design? Making it impossible for
people to do stupid things with objects may save them from doing stupid
things with objects, but being able to does not necessitate that they
will. You are not writing aircraft fly by wire systems or critical
business logic with javascript. A naming convention that tells
programmers using objects defined by others that they should not be
messing with particular sets of properties or methods may well provide
sufficient 'encapsulation' for most practical purposes.
What do you guys think about this?

If you want to use closures to provide objects with private instance
methods and variables you need to create one closure per object. There is
no way round that, and there are 'inheritance' schemes that accommodate
that, but most of the time you don't really need those private members,
you are not creating deep class hierarchies (so maybe don't even need the
inheritance on the objects that really need the private members).

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top