3
// base function
function Man(name) {
  // private property
  var lover = "simron";
  // public property
  this.wife = "rocy";
  // privileged method
  this.getLover = function(){return lover};
  // public method
  Man.prototype.getWife = function(){return this.wife;};
}

// child function
function Indian(){
  var lover = "jothika"; 
  this.wife = "kamala";
}

Indian.prototype = aMan;
var aMan = new Man("raja");
oneIndian = new Indian();
oneIndian.getLover();

I got answer as "simron" but I expect "jothika".

How my understanding is wrong?

Thanks for any help.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
rajakvk
  • 9,775
  • 17
  • 46
  • 49
  • 2
    It won't fix your problem, but I think you need to declare aMan before using it as the prototype for Indian. – Andy Sep 17 '09 at 09:35
  • 6
    This wins the "odd code samples of the day"-award, hands down. :) – Tomalak Sep 17 '09 at 09:35
  • 2
    @Andrew: He doesn't need to *declare* it (`var` is not an inline statement, vars are always treated as though they appear at the top of the scope), but he does need to initialize it. But you're right, that's not the basic problem, the pattern itself is the problem. – T.J. Crowder Sep 17 '09 at 09:41
  • @Tomalak Thanks for that award. :-)) – rajakvk Sep 17 '09 at 09:59
  • 1
    Javascript doesn't really have private variables because it isn't really OO. What you're really describing is variables across different _scopes_. It really is worth learning the difference as it will make understanding problems like this a lot easier. Douglas Crockford has written an excellent book on this: http://oreilly.com/catalog/9780596517748/ – Keith Sep 17 '09 at 12:41
  • @Keith: JavaScript is most definitely oo - it just isn't C++ or Java – Christoph Sep 17 '09 at 12:50
  • Maybe what this guy wants are protected identifiers (http://stackoverflow.com/questions/1015017/ok-we-can-have-private-identifiers-in-javascript-but-what-about-protected-ones). I couldn't find a good solution yet, tho... – Pablo Cabrera Sep 17 '09 at 19:01

3 Answers3

4

First of all your code doesn't work at all and it's wrong.
Here's the code that works:

// base function
function Man(name) {
  // private property
  var lover = "simron";
  // public property
  this.wife = "rocy";
  // privileged method
  this.getLover = function(){return lover};
  // public method
  Man.prototype.getWife = function(){return this.wife;};
}

// child function
function Indian(){
  var lover = "jothika"; 
  this.wife = "kamala";
  this.getLover = function(){return lover};
}

Indian.prototype = new Man();
Indian.prototype.constructor = Indian;

var oneIndian = new Indian();
document.write(oneIndian.getLover());

aMan didn't exist until you declared it.
Also you should have set the ctor to Indian.
And at last, getLover is a closure that refers to Man and not to Indian.
Declaring it again refers it to the right scope.
See here and here for further details and improvements of your code.

the_drow
  • 18,571
  • 25
  • 126
  • 193
  • 6
    A note for the OP: Each instance of `Man` and `Indian` will get its **own** copy of those functions, which can be a memory consumption issue. If you have three instances of `Man`, there are three copies of the `getLover` function in memory. – T.J. Crowder Sep 17 '09 at 09:57
  • I didn't code this to be perfect. I just wanted to show him whats wrong. +1 For the comment – the_drow Sep 17 '09 at 09:59
  • instead of this.getLover = function(){return lover}; below will do. Am i right @ T.J.Crowder Man.prototype = { getLover: function(){return lover;} } – rajakvk Sep 17 '09 at 10:05
  • @ the_drow If I have to define getLover in Indian also then what is purpose of inheritence. Can't I use parent class function to access child class's property? – rajakvk Sep 17 '09 at 10:14
  • I didn't inherit properly if I recall correctly, just read the links I gave you. – the_drow Sep 17 '09 at 10:22
  • 5
    `getWife()` should be assigned outside of the constructor: doing it inside totally defeats the purpose of assigning it to the prototype as you'll still create a new function object for each instance – Christoph Sep 17 '09 at 12:25
  • this is not correct one. just write 'Indian' function and last 2 row, you'll get the ans 'jothika'. He didn't use base function 'Man'. – KarSho Mar 08 '15 at 14:28
2

The getLover property on the instance refers to the closure you defined within the Man constructor. The lover local variable inside Man is the one in-scope for that function. The lover variable you declared inside Indian has nothing whatsoever to do with the one declared inside Man, no more than local variables declared inside other functions do.

For Indian to manipulate the private lover variable inside Man, you would have to give Indian some access to it via an accessor function -- but then everything would be able to change it via that same accessor function.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

My advice: get rid of this whole priviledged method crap and don't try to shoehorn concepts from one language into another.

For performance reasons, methods should reside in the prototype. Otherwise, a new function object (which forms a closure over the constructor's local vaiables) has to be created for each instance, which is highly inefficient.

If you want to hide properties (ie 'private' fields), add a prefix like _private_ to their name and tell the programmer not to do stupid things.

Christoph
  • 164,997
  • 36
  • 182
  • 240
  • 3
    Ever heard about Murphy's law? If it can be used incorrectly, it will! "Edward Murphy Jr. was a US Air Force engineer. He coined this infamous law after discovering a technician had systematically connected a whole row of devices upside down. Symmetric connectors permitted this avoidable mistake; afterward, he chose a different connector design." - from the book Code Craft. – Pablo Cabrera Sep 17 '09 at 12:52
  • @Pablo: Ever heard of square pegs in round holes or respecting the programmer? There just is no way to implement access protection mechanisms efficiently in JavaScript; so you can either penalize everyone or just make it clear whenever the programmer does something at his own risk; my vote is for the latter – Christoph Sep 17 '09 at 13:07
  • @Christoph: You *can* implement them efficiently in JavaScript, just not using the mechanisms in this thread (which as you know cause large per-instance overhead). For code libraries, I see a justification for doing it. For application code, though, I typically don't. – T.J. Crowder Sep 17 '09 at 13:20
  • @T.J.: How? All implementations I know either carry the large per-instance overhead or introduce side effects more severe than the original problem (eg having destructors which have to be called manually) – Christoph Sep 17 '09 at 13:28
  • @T.J.: did you mean something like this: http://stackoverflow.com/questions/483213/javascript-private-member-on-prototype/483294#483294 (as you can see, I obviously know about such implementations;)) – Christoph Sep 17 '09 at 13:43
  • You could have small functions attached to each instance that delegates to a hidden common function that actually does the job... is not that much of an overhead per instance since the delegating function is small. – Pablo Cabrera Sep 17 '09 at 13:44
  • @Christoph: For private *methods*, there are efficient ways that don't have either problem. For private *data*, I'm with you, it's either unacceptable (to me!) per-instance overhead or a destructor to release private data associated with the instance. – T.J. Crowder Sep 17 '09 at 13:46
  • @T.J.: my answer was a rant about priviledged methods, so obviously it was about instance-specific /data/; sharing static values (this includes the 'private' methods you mentioned) is trivial: just use a global and wrap the whole thing (including method definitions) in a self-executing function for namespacing – Christoph Sep 17 '09 at 13:56
  • @Pablo: you'll still have a `O(method_count * instance_count)` overhead; if you create enough instances, it might well be significant – Christoph Sep 17 '09 at 14:00
  • @Christoph: Woudn't ou have a (var_count * instance_count) anyway? What is the problem with a few more small "vars" (since functions are objects aswell in JS)? It's not that you gonna add hundreds of methods per instance... – Pablo Cabrera Sep 17 '09 at 14:06