JavaScript return types

I'm actually learning Crockford Javascript: the good parts. I'm new to JavaScript, so it's hard for me to understand how this code works:

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

That's what I think:

Being a method (function inside an object), this points to a Function object, but why do I need to return an object, since I have access to it from inside the method? If I'm right, this is a link, not a local copy, so:

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

Should also work.

In JavaScript, on the other hand, a function without a return statement returns undefined and assigns it to Function.prototype.method .

Question

What is the return point of this ?


Working example # 1

 Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; }; var add = function(a, b) { return a+b; }; Function.method('add', add); var f = function() {}; print(f.add(1,2)); Number.method('integer', function () { return Math[this < 0 ? 'ceil' : 'floor'](this); }); print((-10/3).integer()); 

Output:

-3 3


Working example # 2

 Function.prototype.method = function (name, func) { this.prototype[name] = func; }; var add = function(a, b) { return a+b; }; Function.method('add', add); var f = function() {}; print(f.add(1,2)); Number.method('integer', function () { return Math[this < 0 ? 'ceil' : 'floor'](this); }); print((-10/3).integer()); 

Output:

-3 3

+7
source share
3 answers

Let me try to explain this. I have not read this book, but Douglas Crockford's classic JavaScript inheritance article has one important suggestion related to this example about Function.prototype.method:

He returns it. When I write a method that does not need to return a value, I usually return it. This allows for cascading programming style.

Actually, I am not familiar with this term, I think the well-known term is “ Free interface ” or “Method chain”, read this wiki page, there are examples in different languages, so you will understand this.

PS. @Gianluca Bargelli was a little faster to provide an example of using Function.prototype.method in this way, so I don't post it in my answer

ADDON: how can you use it in terms of your example:

 Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; } Number.method('integer', function () { // you add 'integer' method return Math[this < 0 ? 'ceil' : 'floor'](this); }) .method('square', function () { // you add 'square' method with help of chaining return this * this; }); console.info( (-10/3).integer().square() ); // <- again chaining in action 

you see, integer () returns a Number object, so you can call another method instead of writing:

 var a = (-10/3).integer(); console.info( a.square() ); 

and a few words about my method of use, most of the time I prefer to write "each method is a new line with indentation, for me this method is more readable:

 Function.method('add', add) .method('sub', sub) .method('mul', mul) .method('div', div); 

so I see where I start, and the “new line / indent” tells me that I am still modifying this object. Compare it with a long string:

 Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div); 

or typical approach:

 Function.method('add', add); Function.method('sub', sub); Function.method('mul', mul); Function.method('div', div); 

ADDON2: I usually use this approach (Fluent interface pattern) when I work with objects, for example. Java Code:

 public class Person { private String name; private int age; .. public String getName() { return this.name; } public Person setName( String newName ) { this.name = newName; return this; } public int getAge() { return this.age; } public Person setAge( int newAge ) { this.age = newAge; return this; } .. } 

it allows me to easily build a Person object:

 Person person = new Person().setName("Leo").setAge(20); 

Some people do this a little differently, they add a new type of methods to set / get and call it with :

 public class Person { private String name; private int age; .. public String getName() { return this.name; } public void setName( String newName ) { this.name = newName; } public Person withName( String newName ) { this.setName( newName ); // or this.name = newName; up to you return this; } public int getAge() { return this.age; } public void setAge( int newAge ) { this.age = newAge; } public Person withAge( int newAge ) { this.setAge( newAge ); // or this.age = newAge; up to you return this; } .. } 

Now my previous example looks like this:

 Person person = new Person().withName("Leo").withAge(20); 

Thus, we do not change the value of the set method (I mean that we do not improve it, so it works as expected by most developers), at least people do not expect the set method to return anything; )). The interesting thing about these special methods is that they can lose their self-documentation, but they improve readability when you use them (for example, in the example with Person creation, withName very well about what exactly we are doing.

To find out more:
FluentInterface - a description of this pattern by Martin Fowler
Free interfaces in PHP
The weekly source code 14 - Fluent Interface Edition - is short and good enough for me to see the pros and cons (as well as links to other resources)

+5
source

Today I sent an email to Douglas Crockford with this question, and his answer was as follows:

F.method (a) .method (b) .method (c)

I am not kidding. That was just the thing he wrote.

In any case, my personal intuition of his (mysterious) answer Creating a chaining method :

 Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; //This returns the same Function object into the chain below }; var add = function (a, b) { return a+b; }; var sub = function (a, b) { return ab; }; var mul = function (a, b) { return a*b; }; var div = function (a, b) { return a/b; }; Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div); 

That is, instead of creating new methods using a one- time string, you can reapply the next method in the chain on the return object of the previous one, Function .

In this example, the chain goes from left to right:

 |Function|--method-->|add|--returns-->|Function|--method-->|sub|--returns-->|Function|--method-->|mul|--returns-->|Function|--method-->|div|-->returns-->|Function| 
+5
source

I don’t understand exactly what you are asking, but if you do not return anything, you are not assigning anything to the .prototype.method function, because this sentence is useless, what do you think?

0
source

All Articles