6

I have been looking into design patterns in Javascript and found http://tcorral.github.com/Design-Patterns-in-Javascript/Template/withoutHook/index.html to be a great source.

Can anyonne explain the significance of using ParentClass.apply(this)

var CaffeineBeverage = function(){

};
var Coffee = function(){
    CaffeineBeverage.apply(this);
};
Coffee.prototype = new CaffeineBeverage();

PS: I tried commenting the CaffeineBeverage.apply(this), but no effect was there. Here is a link to jsfiddle http://jsfiddle.net/pramodpv/8XqW9/

5 Answers 5

13

It simply applies the parent constructor to the object being constructed. Try adding some stuff to the CaffeineBeverage constructor and you'll see what I mean.

var CaffeineBeverage = function(){
    this.tweakage = '123';
};

var Coffee = function(){
    CaffeineBeverage.apply(this);
};

Don't do this: Coffee.prototype = new CaffeineBeverage(). Do this instead:

Coffee.prototype = Object.create(CaffeineBeverage.prototype);

For more information on that, see this article, which also provides a shim for older browsers, which don't have Object.create.

Testing it out:

var drink = new Coffee();
console.log(drink.tweakage); // 123
Sign up to request clarification or add additional context in comments.

4 Comments

wow!! that is great. on a side note.. why do you go for Object.create(CaffeineBeverage.prototype) instead of .prototype = new CaffeineBeverage()
doing Object.create is actually slower than prototype dance. jsperf.com/object-create-vs-crockford-vs-jorge-vs-constructor/… One should use some kind of CoffeeScript __extend functionality or direct dance with prototype + helper function in order to inherit shared properties, performance wise.
@gryzzly very interesting, I've never checked. I personally always do the prototype dance; I'm just oldschool like that. I wonder why this is though.
@PramodSyneITY because generally don't want to invoke the constructor in order to get a copy of its prototype. In some cases you won't be able to. What if the constructor has mandatory arguments?
5

Instead of looking at that example, let's flesh out our own:

var Room = function()
{
  this.doors = 1;
};

Much like call, apply will execute the function, but allow you to specify what this is. In the example above, I'm specifying this.doors = 1, which makes doors a member when we've created our instance of Room.

Now, if I do this:

var ComputerRoom = function() 
{
  Room.apply(this);
  // I can now access the this.doors member:

  this.doors = this.doors + 1;
};

I'm actually saying that this in the context of the Room constructor, is actually the instance of ComputerRoom, which is why I pass it into the apply command: Room.apply(this).

1 Comment

wow!! i have been reading for hours but nothing has been getting into my brain. Thanks for the simple answer... However i can't mark this as answer since @GGG beat it in 2 mins!!
4

The reason you are calling apply in the sub-"class" constructor is to inherit all instance properties.

Here's an example:

var CaffeineBeverage = function (caffeine) {
    this.caffeineContent = caffeine || "100"; // 100mg / cup is an average
};

var Espresso = function (caffeine) {
    // inherit instance properties
    CaffeineBeverage.apply( this, arguments );
};

// do prototype dance to inherit shared properties
var protoCarrier = function () {};
protoCarrier.prototype = CaffeineBeverage.prototype;
Espresso.prototype = new protoCarrier;

var espressoCup = new Espresso(50); 
espressoCup.caffeineContent; // 50

This is why you call apply. Also, apply allows you to send the arguments (with our example of caffeine). Arguments are put in array-like object in JavaScript, and apply accepts an array to pass arguments to the function that is being invoked. This explains why to use apply over call in this case (otherwise, call is faster and should be used when your code doesn't require array of arguments).

3 Comments

Interesting. But how does it know that there is a caffeine argument in the arguments? arguments is an array, right, [50]? It is not a an object {caffeine: 60}. So, how does it possible this.caffeineContent = caffeine || "100";? There is no caffeine variable, there is only arguments[0]
@Green that is how apply method works. It will: receive an array of values as an argument and use these values as arguments on the function that apply is being called on. It’s practically the same as doing new CaffeineBeverage(arguments[0]), while also binding the execution context of the constructor to this which is the first argument of the apply method.
that is also simply how function arguments work – in the calling scope you have variables that you can use to invoke functions with named arguments: var args = [1, 2]; function add(a, b) { return a + b } add(args[0], args[1]); – we are referring to values as items of an array, but inside the function body the arguments are available as named variables.
1

This could help you: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

Comments

0

Apply calls a function with a given this value and arguments provided as an array.

In your example you will be calling the CaffeineBeverage function, but when this is referenced within that function it will be the same Object as the this which is passed to it.

Source

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.