SlideShare a Scribd company logo
Class.js (a.k.a Class.extend)
The amazing 25 line library you probably don't need
Background
What is it?
• It’s a small JavaScript library
• It was written by John Resig,
creator of jQuery, for his book
"Secrets of the JavaScript
Ninja"
• It provides a simplified API for
Class-like inheritance in
JavaScript
• Can be found at John’s site or
on NPM
Why is it interesting?
• It’s only 25 lines long (without
comments)
• It baffled me
• It’s very cleverly written
• It’s a bit of an anti-pattern
/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /b_superb/ : /.*/;
 
  // The base Class implementation (does nothing)
  this.Class = function(){};
 
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;
   
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);        
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // Populate our constructed prototype object
    Class.prototype = prototype;
   
    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;
 
    // And make this class extendable
    Class.extend = arguments.callee;
   
    return Class;
  };
})();
Got Learnt
Class.js baffled me; I pored over
it until I understood it.
Then I wrote a little about it…
Actually, I wrote a lot
• Close examination of the code
• Yielded a 3700 word article
• My brain tingled with knowledge
Deep Extra Medium dive into Class.js
Usage
• Create an object to represent your prototype
• Pass the object to Class.extend to get a constructor for your new class
• The “extend” method is attached to the new constructor
• Pass a new partial prototype to constructor’s “extend” method to extend the
class
Create a class
var Pirate = Class.extend({
" init: function(isEyepatch) {
" " this.eyepatch = isEyepatch;
" },
" eyepatch: false,
" attack: function() {
" " alert("yarrrr!");
" }
});
Extend a class
var SpacePirate = Pirate.extend({
" attack: function() {
" " this._super();
" " alert("zap!");
" }
});
Use it
var blackBeard = new Pirate,
" starLord = new SpacePirate;
"
blackBeard instanceof Pirate; // true!
starLord instanceof SpacePirate; // too true!
starLord instanceof Pirate; // also true!
starLord instanceof Class; // it's all true!
blackBeard.attack(); // yarrrr!
starLord.attack(); // yarrr! zap!
Magic
Wrapped in a self-executing function expression
(function(){
// the magic goes in here
})();
Initializing, and the function test
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /b_superb/ : /.*/;
The base constructor does nothing but show up in
your browser console
// The base Class implementation (does nothing)
this.Class = function(){};
Define the “extend” method “statically”
// Create a new Class that inherits from this class
Class.extend = function(prop) {/*...*/}
Get a reference to the parent prototype, create an
instance to serve as a new prototype
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
Copy the property definition into the prototype
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
/* ... super things happen here */ :
prop[name];
}
If prop[name] is a function containing “_super”...make
“_super” a reference to the parent method
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name])
One more time, in slow motion
• If the property to be copied is a function…
• And contains the text “_super”…
• Create a closure which returns a function…
• Which caches anything called “_super” temporarily…
• Then stores a reference to the parent prototype’s function of the same name…
• Then calls the original (not _super) function…
• Uncaching the local copy of “_super”…
• And return the results of the function
Create a new constructor which calls “init”
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
Assign the augmented prototype to the constructor
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
Attach “extend” to the new constructor, and return
the new class
// And make this class extendable
Class.extend = arguments.callee;
return Class;
Demo
Your probably don’t
need it
Remember: JavaScript ain’t Java
You can create “types” in JavaScript with
constructors and instances
But JavaScript types do not have a guaranteed interface.
• All objects can be modified regardless of type (the constructor)
• Object API can change at any time addition or deletion of properties
• Types have no guaranteed interface, only a prototype chain
• You have to test the api of unknown objects
In JavaScript…
Idiomatic JavaScript
Work with JavaScript in a JavaScripty way.
Remember
• Creating an object in JavaScript is trivial
• Copying objects in JavaScript is trivial
• In most cases, most objects in JavaScript are singletons
• Singletons can "inherit" by using a mix-in pattern
• _.assign/extend
• jQuery.extend
{}
for (x in y) {
" z[x] = y[x];
}
When do you need Class.js?
• When you must define multiple types of an object which…
• Share a common, inherited API, which…
• Needs access to the parent API
Examples…
• User management in an application with many types of users (employees,
managers, space pirates)
• Product listing with a base "product" definition inherited product types where
all products share common features / API
Alternatives…
• Object.create and Object.getPrototypeOf
• Copy Module pattern
• Mix-ins
Resources
• http://ejohn.org/blog/simple-javascript-inheritance/
• http://abouthalf.com/development/understanding-class-js/
• https://www.npmjs.org/package/class.extend
• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/
Details_of_the_Object_Model
• http://ejohn.org/blog/objectgetprototypeof/
• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/
getPrototypeOf
• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/
create

More Related Content

PPTX
Javascript Prototype Visualized
PDF
JavaScript Library Overview
PDF
Prototype
PPTX
Js: master prototypes
PDF
TypeScript for Java Developers
PDF
TypeScript 2 in action
PPTX
Bringing classical OOP into JavaScript
PDF
Javascript Design Patterns
Javascript Prototype Visualized
JavaScript Library Overview
Prototype
Js: master prototypes
TypeScript for Java Developers
TypeScript 2 in action
Bringing classical OOP into JavaScript
Javascript Design Patterns

What's hot (20)

PPTX
JRuby in Java Projects
PDF
Scalable JavaScript Application Architecture
PPTX
Node.JS error handling best practices
PDF
Object Oriented Programming in JavaScript
KEY
Agile JavaScript Testing
PPTX
JS Frameworks Day April,26 of 2014
PDF
Js fwdays unit tesing javascript(by Anna Khabibullina)
PDF
Scalable JavaScript Design Patterns
PDF
JavaScript Patterns
PDF
Testable JavaScript: Application Architecture
PDF
Connecting the Worlds of Java and Ruby with JRuby
PPTX
Object Oriented Programming In JavaScript
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
PPT
Understanding Framework Architecture using Eclipse
PDF
Intro to JavaScript
PPT
A Deeper look into Javascript Basics
PPTX
Testing Ext JS and Sencha Touch
PDF
Survive JavaScript - Strategies and Tricks
PDF
Advanced JavaScript - Internship Presentation - Week6
PDF
Javascript Module Patterns
JRuby in Java Projects
Scalable JavaScript Application Architecture
Node.JS error handling best practices
Object Oriented Programming in JavaScript
Agile JavaScript Testing
JS Frameworks Day April,26 of 2014
Js fwdays unit tesing javascript(by Anna Khabibullina)
Scalable JavaScript Design Patterns
JavaScript Patterns
Testable JavaScript: Application Architecture
Connecting the Worlds of Java and Ruby with JRuby
Object Oriented Programming In JavaScript
Intro To JavaScript Unit Testing - Ran Mizrahi
Understanding Framework Architecture using Eclipse
Intro to JavaScript
A Deeper look into Javascript Basics
Testing Ext JS and Sencha Touch
Survive JavaScript - Strategies and Tricks
Advanced JavaScript - Internship Presentation - Week6
Javascript Module Patterns
Ad

Viewers also liked (11)

DOCX
PDF
Reader's Advisory: Science Fiction
PDF
Atlanta mobile app development companies
DOCX
Sci fi (media-story)
PDF
LivePolicy Briefings Service & Prices May 2015
DOCX
Recursos naturales
DOC
Stop a la flaccidez: nota de prensa
PPTX
Chrystos, a Native American LGBT leader
PPTX
Roman Valchuk "Introducing to DevOps technologies"
DOCX
Cuadro informativo
PPTX
ทฤษฎีการเรียนรู้ของธอร์นไดค์
Reader's Advisory: Science Fiction
Atlanta mobile app development companies
Sci fi (media-story)
LivePolicy Briefings Service & Prices May 2015
Recursos naturales
Stop a la flaccidez: nota de prensa
Chrystos, a Native American LGBT leader
Roman Valchuk "Introducing to DevOps technologies"
Cuadro informativo
ทฤษฎีการเรียนรู้ของธอร์นไดค์
Ad

Similar to ClassJS (20)

PPTX
java: basics, user input, data type, constructor
PPTX
Java Constructor
PDF
Constructors in Java (2).pdf
PPTX
Modules 333333333³3444444444444444444.pptx
PPTX
Object oriented programming in java
ODP
Jquery Plugin
PDF
13 java beans
PPTX
inheritance.pptx
PPTX
Framework prototype
PPTX
Framework prototype
PPTX
Framework prototype
PDF
JAVA Object Oriented Programming (OOP)
PPTX
JavaScript Beyond jQuery
PPTX
Java For Automation
PDF
Top 50 Java Interviews Questions | Tutort Academy - Course for Working Profes...
KEY
JavaScript Coding with Class
PPTX
oop 3.pptx
PDF
Advance java kvr -satya
PDF
Adv kvr -satya
PPTX
Object Oriented Programming Concepts
java: basics, user input, data type, constructor
Java Constructor
Constructors in Java (2).pdf
Modules 333333333³3444444444444444444.pptx
Object oriented programming in java
Jquery Plugin
13 java beans
inheritance.pptx
Framework prototype
Framework prototype
Framework prototype
JAVA Object Oriented Programming (OOP)
JavaScript Beyond jQuery
Java For Automation
Top 50 Java Interviews Questions | Tutort Academy - Course for Working Profes...
JavaScript Coding with Class
oop 3.pptx
Advance java kvr -satya
Adv kvr -satya
Object Oriented Programming Concepts

ClassJS

  • 1. Class.js (a.k.a Class.extend) The amazing 25 line library you probably don't need
  • 3. What is it? • It’s a small JavaScript library • It was written by John Resig, creator of jQuery, for his book "Secrets of the JavaScript Ninja" • It provides a simplified API for Class-like inheritance in JavaScript • Can be found at John’s site or on NPM
  • 4. Why is it interesting? • It’s only 25 lines long (without comments) • It baffled me • It’s very cleverly written • It’s a bit of an anti-pattern /* Simple JavaScript Inheritance  * By John Resig http://ejohn.org/  * MIT Licensed.  */ // Inspired by base2 and Prototype (function(){   var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /b_superb/ : /.*/;     // The base Class implementation (does nothing)   this.Class = function(){};     // Create a new Class that inherits from this class   Class.extend = function(prop) {     var _super = this.prototype;         // Instantiate a base class (but only create the instance,     // don't run the init constructor)     initializing = true;     var prototype = new this();     initializing = false;         // Copy the properties over onto the new prototype     for (var name in prop) {       // Check if we're overwriting an existing function       prototype[name] = typeof prop[name] == "function" &&         typeof _super[name] == "function" && fnTest.test(prop[name]) ?         (function(name, fn){           return function() {             var tmp = this._super;                         // Add a new ._super() method that is the same method             // but on the super-class             this._super = _super[name];                         // The method only need to be bound temporarily, so we             // remove it when we're done executing             var ret = fn.apply(this, arguments);                     this._super = tmp;                         return ret;           };         })(name, prop[name]) :         prop[name];     }         // The dummy class constructor     function Class() {       // All construction is actually done in the init method       if ( !initializing && this.init )         this.init.apply(this, arguments);     }         // Populate our constructed prototype object     Class.prototype = prototype;         // Enforce the constructor to be what we expect     Class.prototype.constructor = Class;       // And make this class extendable     Class.extend = arguments.callee;         return Class;   }; })();
  • 5. Got Learnt Class.js baffled me; I pored over it until I understood it. Then I wrote a little about it…
  • 6. Actually, I wrote a lot • Close examination of the code • Yielded a 3700 word article • My brain tingled with knowledge
  • 7. Deep Extra Medium dive into Class.js
  • 8. Usage • Create an object to represent your prototype • Pass the object to Class.extend to get a constructor for your new class • The “extend” method is attached to the new constructor • Pass a new partial prototype to constructor’s “extend” method to extend the class
  • 9. Create a class var Pirate = Class.extend({ " init: function(isEyepatch) { " " this.eyepatch = isEyepatch; " }, " eyepatch: false, " attack: function() { " " alert("yarrrr!"); " } });
  • 10. Extend a class var SpacePirate = Pirate.extend({ " attack: function() { " " this._super(); " " alert("zap!"); " } });
  • 11. Use it var blackBeard = new Pirate, " starLord = new SpacePirate; " blackBeard instanceof Pirate; // true! starLord instanceof SpacePirate; // too true! starLord instanceof Pirate; // also true! starLord instanceof Class; // it's all true! blackBeard.attack(); // yarrrr! starLord.attack(); // yarrr! zap!
  • 12. Magic
  • 13. Wrapped in a self-executing function expression (function(){ // the magic goes in here })();
  • 14. Initializing, and the function test var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /b_superb/ : /.*/;
  • 15. The base constructor does nothing but show up in your browser console // The base Class implementation (does nothing) this.Class = function(){};
  • 16. Define the “extend” method “statically” // Create a new Class that inherits from this class Class.extend = function(prop) {/*...*/}
  • 17. Get a reference to the parent prototype, create an instance to serve as a new prototype var _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = new this(); initializing = false;
  • 18. Copy the property definition into the prototype // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? /* ... super things happen here */ : prop[name]; }
  • 19. If prop[name] is a function containing “_super”...make “_super” a reference to the parent method (function(name, fn){ return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name])
  • 20. One more time, in slow motion • If the property to be copied is a function… • And contains the text “_super”… • Create a closure which returns a function… • Which caches anything called “_super” temporarily… • Then stores a reference to the parent prototype’s function of the same name… • Then calls the original (not _super) function… • Uncaching the local copy of “_super”… • And return the results of the function
  • 21. Create a new constructor which calls “init” // The dummy class constructor function Class() { // All construction is actually done in the init method if ( !initializing && this.init ) this.init.apply(this, arguments); }
  • 22. Assign the augmented prototype to the constructor // Populate our constructed prototype object Class.prototype = prototype; // Enforce the constructor to be what we expect Class.prototype.constructor = Class;
  • 23. Attach “extend” to the new constructor, and return the new class // And make this class extendable Class.extend = arguments.callee; return Class;
  • 24. Demo
  • 25. Your probably don’t need it Remember: JavaScript ain’t Java
  • 26. You can create “types” in JavaScript with constructors and instances But JavaScript types do not have a guaranteed interface.
  • 27. • All objects can be modified regardless of type (the constructor) • Object API can change at any time addition or deletion of properties • Types have no guaranteed interface, only a prototype chain • You have to test the api of unknown objects In JavaScript…
  • 28. Idiomatic JavaScript Work with JavaScript in a JavaScripty way.
  • 29. Remember • Creating an object in JavaScript is trivial • Copying objects in JavaScript is trivial • In most cases, most objects in JavaScript are singletons • Singletons can "inherit" by using a mix-in pattern • _.assign/extend • jQuery.extend {} for (x in y) { " z[x] = y[x]; }
  • 30. When do you need Class.js? • When you must define multiple types of an object which… • Share a common, inherited API, which… • Needs access to the parent API
  • 31. Examples… • User management in an application with many types of users (employees, managers, space pirates) • Product listing with a base "product" definition inherited product types where all products share common features / API
  • 32. Alternatives… • Object.create and Object.getPrototypeOf • Copy Module pattern • Mix-ins
  • 33. Resources • http://ejohn.org/blog/simple-javascript-inheritance/ • http://abouthalf.com/development/understanding-class-js/ • https://www.npmjs.org/package/class.extend • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/ Details_of_the_Object_Model • http://ejohn.org/blog/objectgetprototypeof/ • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/ getPrototypeOf • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/ create