3

I'm new to JavaScript and am learning from the book JavaScript: The Good Parts. In that book, the following recipe is used to augment a method to all functions:

Function.prototype.method = function (name, func) {
 this.prototype[name] = func;
 return this;
 }

I wanted to explore this concept, so I came up with the following script, which aims to add the greet() method to the func() function:

//define how the augmentation will work
Function.prototype.method = function (name, func) {
 this.prototype[name] = func;
 return this;
}
//create a dummy function to augment
function func() {
 //do nothing
}
//create function to be added
func.method('greet', function() {
 console.log("Greetings from greet()!");
});
//access the new function
func.greet();

When I run it, though, I get the error Uncaught TypeError: undefined is not a function. Could someone please tell me what I'm doing wrong.

asked Nov 24, 2014 at 5:47
5
  • JSFiddle: jsfiddle.net/s8aed1bx Commented Nov 24, 2014 at 5:51
  • try this[name] instead of this.prototype[name] Commented Nov 24, 2014 at 5:56
  • 1
    @vp_arth That works, but I'd really like to know why. Could you explain or provide me a link I can read from? :) Commented Nov 24, 2014 at 5:57
  • @Phrogz already explained it :) Commented Nov 24, 2014 at 6:02
  • @vp_arth Yeah. I'm still don't understand it 100%, but it will help me look in the right direction. :) Commented Nov 24, 2014 at 6:04

1 Answer 1

6

In this case you want to modify the line:

this.prototype[name] = func;

to just

this[name] = func;

Demo: http://jsfiddle.net/s8aed1bx/1/

Alternatively you could use

this.constructor.prototype[name] = func;

but that would add each new method to every function, not just the one you call method on. Or you could use:

var f2 = new func();
f2.greet();

Why?

When looking up properties on an object in JavaScript, the object itself is searched, and then the prototype of the constructor of the object is searched (and so on up the chain). The .constructor of func is Function.

In this case what you have done would work if you wrote:

func.method('greet', function() {
 console.log("Greetings from greet()!");
});
var f2 = new func();
f2.greet();

The prototype of a function is used for new instances created by that function. (The objects you create have a .constructor of the creating function itself.)

answered Nov 24, 2014 at 5:53
Sign up to request clarification or add additional context in comments.

5 Comments

Wow, thanks! If it's not too much of an effort, care to explain why? :)
Learn new thing today.
@dotslash Edited with more info.
@Phrogz Superb answer! Couldn't have asked for more. :)
@Manwal I guess it'd be the Function object which serves as the prototype for all functions? My JS fundamentals are quite shaky, though. :P

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.