Object oriented javascript with anti-closure prototypes

I am curious what is the difference between the following Javascript OOP methods. They seem to end up doing the same, but are considered better than others?

function Book(title) { this.title = title; } Book.prototype.getTitle = function () { return this.title; }; var myBook = new Book('War and Peace'); alert(myBook.getTitle()) 

against

 function Book(title) { var book = { title: title }; book.getTitle = function () { return this.title; }; return book; } var myBook = Book('War and Peace'); alert(myBook.getTitle()) 
+56
javascript oop
Aug 25 '10 at 8:56
source share
5 answers

The second one does not instantiate, it just returns an object. This means that you cannot use operators such as instanceof . For example. with the first case, you can do if (myBook instanceof Book) to check if the variable is a type of book, but in the second example it will fail.

If you want to specify your object methods in the constructor, this is the right way to do this:

 function Book(title) { this.title = title; this.getTitle = function () { return this.title; }; } var myBook = new Book('War and Peace'); alert(myBook.getTitle()) 

In this example, both behave exactly the same, there are differences. In a closure-based implementation, you can have private variables and methods (just don't expose them to the this object). So you can do something like:

 function Book(title) { var title_; this.getTitle = function() { return title_; }; this.setTitle = function(title) { title_ = title; }; // should use the setter in case it does something else than just assign this.setTitle(title); } 

Code outside the Book function cannot directly access a member variable; they must use accessors.

Another big difference is performance; Classification based on the prototype is usually much faster, due to some overhead associated with the use of closures. You can read about performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx

+41
Aug 25 '10 at 9:02
source share

The first method is how JavaScript was supposed to be used. The latter is a more modern technique, partially popularized by Douglas Crockford. This method is much more flexible.

You can also do:

 function Book(title) { return { getTitle: function () { return title; } } } 

There will be only one accessor in the returned object, called getTitle , which will return the argument contained in the closure.

Crockford has a nice Private Members page in JavaScript - definitely worth a read to see the various options.

+10
Aug 25 '10 at 9:03
source share

It is also a little about the possibility of reuse under the hood. In the first example, using the Function.prototype property, all instances of the Book function function will have the same copy of the getTitle method. While the second fragment does the execution of the Book create function and saves different copies of the local Book object being closed on the bookshelf heap.

 function Book(title) { var book = { title: title }; book.getTitle = function () { return this.title += '#'; }; return book; } var myBook = Book('War and Peace'); var myAnotherBook = Book('Anna Karenina'); alert(myBook.getTitle()); // War and Peace# alert(myBook.getTitle()); // War and Peace## alert(myAnotherBook.getTitle()); // Anna Karenina# alert(myBook.getTitle());// War and Peace### 

Prototype elements exist in a single copy for all instances of a new object, on the other hand. So this is another subtle difference between the two, which is not very obvious due to the first sigh due to the closing trick.

+4
Jun 06 '13 at 8:52
source share

Which is better sometimes can be determined by the context of their use.

Three limitations of how I choose Prototype and Closing coding methods (I actively use both):

  • Productivity / Resources
  • Compression Requirements
  • Project management

1. Productivity / Resources

For a single instance of an object, any method is fine. Any speed benefits are likely to be negligible.

If I create 100,000 of them, for example, by creating a library of books, the Prototype method is preferable. The whole .prototype. functions will be created only once, instead of these functions being created 100,000 times using the Closure Method . The resources are not endless.

2. Compression

Use the Closure Method if compression efficiency is important (for example, most browser libraries / modules). For explanation see below:

Compression - Prototype Method

 function Book(title) { this.title = title; } Book.prototype.getTitle = function () { return this.title; }; 

Is YUI compressed

 function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title}; 

Save about 18% (all spaces / tabs / returns). This method requires the mapping of variables / functions (this.variable = value) so that each prototype function can access them. Therefore, these variables / functions cannot be optimized during compression.

Compression - Close Method

 function Book(title) { var title = title; // use var instead of this.title to make this a local variable this.getTitle = function () { return title; }; } 

Is YUI compressed

 function Book(a){var a=a;this.getTitle=function(){return a}}; 

Save about 33%. Local variables can be optimized. In a large module with many auxiliary functions, this can have significant compression savings.

3. Project Management

In a project with several developers who can work on the same module, I prefer the Prototype Method for this module, if not limited to performance or compression.

For browser development, I can override producton.prototype.aFunction from "production.js" in my own "test.js" (read in words) for testing or development purposes without the need to modify the "production" .js ", which may be active developed by another developer.

I'm not a big fan of the complex GIT repository checkout / branch / merge / conflict flow. I prefer it simply.

In addition, the ability to override or "capture" a module function with a test node may be useful, but too complex to address here ...

+4
Jan 25 '17 at 15:15
source share

Here is an article about it in general. Book of a book from Book.prototype. In the first example, you add a function to getTitle Book.prototype

0
Aug 25 '10 at 9:13
source share



All Articles