2

My intend:

  • With an object o with a method work
  • Print "Hello" before o.work()
  • Print "Bye" after o.work()
  • o.work() will be called by a 3rd party

My attempt:

// sample library object
var o = {
     score: 5,
     work: function() {
                     console.log(this.score);
                }
};

// my code
var cons = function () {
     this.score = 10;
     this.work = function () {
          console. log("Hello");
           // how to call parent's work() ?
           // if I do this.prototype.work() -> prints 5
           // But parent's work should be called when this.score is 10
          console. log("Bye");
     };
 };
 cons.prototype = o;
 my_o = new cons();

 // my_o will be passed to 3rd party instead of o

In short:

  • I am attempting to decorate inherited method.
  • Its easy with super but JavaScript doesn't have super.

They say prototypal inheritance is supirior.

Update:

  • work() uses this.score, which is overridden after inheritance.

Update 2:

  • Expectation is o.work() should print 5
  • Expectation is my_o.work() should print 10
3
  • NB: if you write this.work = function ... you are not using prototypical inheritance, you've added that method directly to the current instance of cons. Commented Dec 24, 2013 at 8:28
  • I am updating the question. Commented Dec 24, 2013 at 8:57
  • o.work() would do just fine. Usually you would not have instance specific values for Parent and Child on prototype, if so needed it's better the Child holds an instance of Parent. More on constructor functions and prototype can be found here: stackoverflow.com/a/16063711/1641941 Commented Dec 24, 2013 at 14:16

5 Answers 5

2

It's a bit ugly, but you can call cons.prototype.work;

var Cons = function () {
     this.work = function () {
         alert('Hello');
         cons.prototype.work.call(this); // <= here
         alert('Bye');
     };
 };

Or more generic:

var Cons = function () {
     this.parentwork = arguments.callee.prototype.work;
     this.work = function () {
         alert('Hello');
         this.parentwork.call(this);
         alert('Bye');
     };
};

See this jsFiddle

Sign up to request clarification or add additional context in comments.

6 Comments

Updated the question - Please check !
You mis-read the update. The point being parent has a different value for score and child has a different value. The new value of score is what is defined by the child.
You answered it well. but your (not-required) alert code made it all confusing.
See the updated jsFiddle. The alert replacement is for convenience
Great job, it worked. alert : Have it as a external lib to jsfiddle so that it doesn't gets in between.
|
0

You need to either know exactly who the parent you are trying to call is, and call it directly (passing the local this value using the .call method) or you need to use an OOP library that implements such abilities at the cost of requiring a rather convoluted code design.

1 Comment

Updated the question - Please check !
0

No, you would need to give the do function in the constructor and the do function in the prototype different names.

Instance members created inside a constructor will occlude properties of the same name defined in the prototype

Have a look at this pic from john resig book :

enter image description here

When we run the test by loading the page into the browser, we see that the test passes! This shows that instance members created inside a constructor will occlude properties of the same name defined in the prototype.

The precedence of the initialization operations is important and goes as follows:

  • 1 Properties are bound to the object instance from the prototype.
  • 2 Properties are added to the object instance within the constructor function.

1 Comment

Updated the question - Please check !
0

replace the line

 // how to call parent's work() ?

with

cons.prototype.work();

as simple as that:)

1 Comment

Updated the question - Please check !
0

Figured it out :

// sample library object
var o = {
     score: 5,
     work: function() {
                     console.log(this.score);
                }
};

// my code
var cons = function () {
     this.score = 10;
     this.parent = arguments.callee.prototype;
     this.work = function () {
          console. log("Hello");
           // this.prototype.work() // Doesn't work since 'this' is an object
           // objects don't contain a link to prototype.
           // ###### With direct reference to `cons` ###### //
           // cons.prototype.work(); // (No Context) -> prints 5
                    // OR
           cons.prototype.work.call(this); // (With 'this' context) -> prints 10
           // ###### Without direct reference to `cons` [ Preferred ] ###### //
           // this.parent.work(); // (No Context) -> prints 5
                    // OR
           this.parent.work.call(this); // (With 'this' context) -> prints 10
          console. log("Bye");
     };
 };
 cons.prototype = o;
 my_o = new cons();

 my_o.work();

Expectations Met:

  • o.work() prints 5
  • my_o.work() prints 10

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.