2

I've created an array of 1000 cars. When I call run on the first car, I want it to run as normal. When I call run on any of the others and any cars created in the future, I want it to run as normal, but also log The {color} car is now running. to the console.

Solution:

`cars[0].run = cars[0].run;

var oldRun = Car.prototype.run;
Car.prototype.run = function () {
    console.log("The " + this.color + " car is now running");
    return oldRun.apply(this, arguments);
};

Could someone explain how this function works?It is from javacript interview question list.

3
  • Car[0] calls the run function bound to its own run property which was copied from the prototype before it was altered. The others use the function bound to the prototype. cars[0].hasOwnProperty('run') == true the others will return false. Commented May 26, 2016 at 18:29
  • the main part got me confused is how 'cars[0.run = cars[0].run' works here?plus,why 'apply' is used here? Commented May 26, 2016 at 18:48
  • 1
    cars[0].run = cars[0].run could have been written cars[0].run = Car.prototype.run or even cars[0].run = oldRun. Commented May 26, 2016 at 18:54

1 Answer 1

1

Lets dissect this one line at a time:

cars[0].run = cars[0].run;

I assume that the run method was originally a prototype function. By assigning the cars run method to its own run method name we are essentially just returning a regular function and not a prototype function for the Car object. This means it won't be affected by any changes made to the prototype function which later gets a new definition.

var oldRun = Car.prototype.run;

Same thing as above except we are storing it in its own function name as opposed to assigning to a specific car. This can be used globally now.

Car.prototype.run = function () {

Ok now we are redefining the prototype method named run to all Cars. The first car is unaffected by this because its run method is just a normal function now that belongs only to that car.

console.log("The " + this.color + " car is now running");

pretty straight forward.

return oldRun.apply(this, arguments);

since we stored the original run method call to oldRun, we can now call it and return anything that this function returns. Instead of just calling it like this oldRun(); we use the apply method call so we can pass in a 'this' reference which is referring to the car we are calling this from. Here is a link to MDN for more info on 'apply':

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

So why do we have to pass 'this'. Its because the oldRun function doesn't belong to any object and is completely detached from it. The new 'run' prototype method does have a reference to the car and already has use of 'this' so we just pass that reference down to the new function oldRun. That way if oldRun ever uses the keyword 'this' it will know what its referring to now.

arguments is an object referring to the arguments passed through the function prototype run. All functions have access to this. So if you run cars[1].run(param1, param2) both parameters get passed down to the oldRun function.

I was in a bit of a rush when writing this so if I missed anything or did a bad job explaining anything let me know in the comments.

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

1 Comment

Thanks very much,i totally got your idea.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.