5

The following is a code snippet from Crockford's JavaScript: The Good Parts:

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

Crockford goes onto explain that

"By augmenting Function.prototype with a method method, we no longer have to type the name of the prototype property. That bit of ugliness can now be hidden."

I'm basically at a loss to understand this point. What did we have to do before that we no longer have to do now?

John Powell
  • 12,253
  • 6
  • 59
  • 67
George
  • 6,927
  • 4
  • 34
  • 67
  • 3
    Touching the prototype of something you don't own is a terrible idea (you open the door to all kinds of conflicts). This is a astoundingly ill-advised bit of laziness on Crockford's part. – ssube Jan 26 '15 at 20:56
  • 1
    The "improvement" being made there is not really of much practical importance; I think it's more of a teaching example. – Pointy Jan 26 '15 at 20:56
  • @ssube: Crockford "ill-advised"? meh. if it's a problem, show us instead of telling us... – dandavis Jan 26 '15 at 21:04
  • @dandavis, if everyone's going to touch the `prototype` of an object she's not implementing, since you can do that *anywhere* in the code, it's very likely other people won't be aware of that edit. Say that at line 742, someone writes `String.prototype.toLowerCase = String.prototype.toUpperCase;` Sooner or later something odd happens, and hackers who will debug it won't suspect that errors come from expecting a different behaviour from `String.prototype.toLowerCase`... Course, just my 2 cents. – Giuseppe Crinò Jan 26 '15 at 21:12
  • It is considered best practice to not modify native objects' prototypes because it may create naming conflicts in the future if a new method or property with the same name is added – Trash Can Jan 26 '15 at 21:24
  • @ssube this is from a book published in 2008. His guidance has changed significantly since then. – Evan Davis Jan 27 '15 at 00:04
  • @giuscri: i always find examples a bit contrived, but point made better than just saying so. if you dig back far enough, Doug put out some stuff that modified Object.prototype, so he's not flawless by any means. Still it depends on what you're doing and who's writing the code. I do think in some cases modifying Function.prototype and Array.prototype can be really handy, and if it's for a node box running your own custom code, you shouldn't have "surprises" anyway... – dandavis Jan 27 '15 at 23:35

3 Answers3

9

He's saying that instead of writing:

MyType.prototype.myMethod = function() {
    ..
};

you can write this:

MyType.method("myMethod", function() {
    ...
});

with the possibility (given the return this) of dot-chaining another call:

MyType.method("method1", function() {
    ...
}).method("method2", function() {
    ...
});

Meh.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
2

Code break down:

Function.prototype.method

Every object in JavaScript allows prototypes. It's JavaScript way of inheritance. Function is the master object from which all other functions are created. When you set a prototype on it all Function objects inherit that property. In this case the function method.

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

If you wanted the expand your own functions with other methods you need to type:

  somefunction.prototype.name = function(){}

With this method you can do just this:

  somefunction.method(name, function)

This funky bit does that:

  this.prototype[name] = func;

It refers to the Function object using the this keyword. The proceeds to the prototype for inheritance. Sets the function to the prototype using [name]. This converts the string name to a property. Why so? Because:

 this.prototype.name 

would not work properly. If you use the code above, every time a new method is added it will be referenced by name and not the name you'sve chosen.

Why is prototype[example] the same as prototype.example. Because in JavaScript every property is stored in a arrayish list on the object and can be called like you call an item from an array using Object[].

Mouser
  • 13,132
  • 3
  • 28
  • 54
1

Lets prove corckford's statement:

"By augmenting Function.prototype with a method method, we no longerhave to type the name of the prototype property. That bit of ugliness can now be hidden."

Here crockford wanted to say you can manipulate Function.prototype to achieve many different functionality for your personal usage.It is a functionality added to the function.prototype to add new method/property to any function.Functions in javascript inherits form Function.prototype.lets break down your code.

Function.prototype.method = function (name, func) {

in this line Function.prototype is added a new method.This method receive two arguments.name satands for a new methods name .And func stands for its functionality.I think you are familiar with what is methods and properties are.Functions are first class object in javascript.So they can be added new properties and methods during runtime.

this.prototype[name] = func;

Here this refers to the function which calls it.[name] is method name and func is the method's functionality It adds a new method to passed function using array notation. Then finally

return this;

with this statement passed function is returned with a new method added to it.

Here i have a practical example for you:

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

function Myfunction(){       // a constructor function called Myfunction
    this.name='robin';      // it has a name property
}

Myfunction.method('mymethod',function (){ console.log(' i am available')});  //adds a method named 'mymethod to Myfunction constructor

var newObj=new Myfunction();     // creates a new instance  of Myfunction class
console.log(newObj.mymethod());  //calls mymethod() of newObj

Here myfunction is a constructor.We can add inherited methods to this constructor's prototype usind Myfunction.prototype.mymethod=function(){ ..}

If you use myfunction as a constructor this is the way you add method to it.But As you've added a new functionality to Function.prototype,you can simply call it like

Myfunction.method('mymethod',function (){console.log('i am available'}); //it will add a method named mymethod to Myfunction's prototype 

This statement will add a new method called mymethod to Myfunction()'s prototype implicitly.

so you don't have to write Myfunction.prototype.mymethod=function(){ console.log('i am available'); .Instead you can write Myfunction.method('mymethod',function (){ console.log('i am available'});

So it proves it will relieve you from writing Myfunction.prototype again and again every time you want to add new methods to Myfunction constructor.

So it proves crockford's statement .

Community
  • 1
  • 1
AL-zami
  • 8,902
  • 15
  • 71
  • 130