Adobe
Products

Top destinations

  • Adobe Creative Cloud
  • Creative Suite
  • Adobe Marketing Cloud
  • Acrobat
  • Photoshop
  • SiteCatalyst
  • Students
  • Elements family

Adobe Creative Cloud

  • What is Adobe Creative Cloud?
  • Design
  • Web
  • Photography
  • Video
  • Students
  • Teams
  • Enterprise
  • Educational institutions

Design and photography

  • Photoshop
  • Illustrator
  • InDesign
  • Adobe Muse
  • Lightroom

Video

  • Adobe Premiere
  • After Effects

Web development and HTML5

  • Edge Tools & Services [opens in a new window]
  • Dreamweaver
  • Gaming [opens in a new window]

Adobe Marketing Cloud

  • What is Adobe Marketing Cloud?
  • Digital analytics
  • Social marketing
  • Web experience management
  • Testing and targeting
  • Media optimization

Analytics

  • SiteCatalyst
  • Adobe Discover
  • Insight

Social

  • Adobe Social

Experience Manager

  • CQ
  • Scene7

Target

  • Test&Target
  • Recommendations
  • Search&Promote

Media Optimizer

  • AdLens
  • AudienceManager
  • AudienceResearch

Document services

  • Acrobat
  • EchoSign [opens in a new window]
  • FormsCentral [opens in a new window]
  • SendNow [opens in a new window]
  • Acrobat.com [opens in a new window]

Publishing

  • Digital Publishing Suite

  • See all products
Business solutions

By business need

  • Digital analytics
  • Digital publishing
  • Document management
  • Media optimization
  • Social marketing
  • Testing and targeting
  • Video editing and serving
  • Web development [opens in a new window]
  • Web experience management
  • See all business needs

By industry

  • Broadcast
  • Education
  • Financial services
  • Government
  • Publishing
  • Retail
  • See all industries
Support & Learning

I need help

  • Products
  • Adobe Creative Cloud
  • Adobe Marketing Cloud
  • Forums [opens in a new window]

I want to learn

  • Training and tutorials
  • Certification [opens in a new window]
  • Adobe Developer Connection
  • Adobe Design Center
  • Adobe TV [opens in a new window]
  • Adobe Marketing Center
  • Adobe Labs [opens in a new window]
Download
  • Product trials
  • Adobe Flash Player
  • Adobe Reader
  • Adobe AIR
  • See all downloads
Company
  • Careers at Adobe
  • Investor Relations
  • Newsroom
  • Privacy
  • Corporate Social Responsibility
  • Customer Showcase
  • Contact us
  • More company info
Buy
  • For personal and professional use
  • For students, educators, and staff
  • For small and medium businesses
  • Volume Licensing
  • Special offers
  • Adobe Marketing Cloud sales [opens in a new window]
Search
 
Info Sign in
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Welcome,
My Adobe
My orders
My information
My preferences
My products and services
Sign out
My cart
Privacy My Adobe
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out Privacy My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Promotions
Estimated shipping
Tax
Calculated at checkout
Total
Review and Checkout
Adobe Developer Connection / HTML5, CSS3, and JavaScript /

Pseudo-classical object-oriented programming in JavaScript with Minion

by Brian Rinaldi

Brian Rinaldi
  • remotesynthesis.com

Content

  • Installing Minion
  • Creating classes with Minion
  • Inheritance in Minion
  • Composition in Minion
  • Putting it all together
  • Where to go from here

Created

27 March 2012

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
HTML5inheritanceJavaScriptOOP
Was this helpful?
Yes   No

By clicking Submit, you accept the Adobe Terms of Use.

 
Thanks for your feedback.

Requirements

Prerequisite knowledge

A general understanding of coding in JavaScript as well as object-oriented design principles in programming will help you make the most of this article.

 

Additional required other products

Node.js

  • Download

User level

Intermediate

Sample files

  • minion_sample.zip

One of the difficulties in learning JavaScript for anyone coming from a classical object-oriented programming (OOP) language background is adjusting to how objects are defined and extended. Obviously, JavaScript has neither a traditional concept of classes nor classical inheritance. Many JavaScript frameworks try to overcome this deficiency by providing a syntax for defining classes and methods for handling inheritance and composition. CoffeeScript and similar languages that compile to JavaScript also provide a more traditional syntax for handling this as well. Clearly, despite assertions that trying to force JavaScript into a classical object model isn't really a good idea, the issue keeps coming up.

I recently came across Minion, a solution created by Taka Kojima. It is a lightweight JavaScript library for defining classes with support for classical style object-oriented inheritance and composition, among other features. While it currently requires Node.js to compile and can work out of the box with Node, you can use Minion in the browser. In this tutorial, I revisit the simple example and model that I created for a JavaScript prototype inheritance tutorial that I posted previously on my blog. I recommend that you read this post, in which I describe how I built simple Portal turret objects, because it will help you better understand the example used in this article. This article covers how I rebuilt the example with Minion and how this approach compares with a straight JavaScript (that is, framework-less) solution.

Installing Minion

To use Minion in your browser-based application, you first need to download it via the Node Package Manager ( npm ) and compile it via Node.js. Now that npm comes with Node and Node has easy-to-use installers even for Windows, this is pretty simple to accomplish.

  1. If you don't already have it, download and install Node. (note: in some cases, you may need to add node and npm to your path/environment variables)
  2. Once you have Node installed, get to the command line and use npm to download Minion:
npm install minion -g
  1. Now navigate into the directory where the code was downloaded, which is not always obvious. On my Windows 7 machine the default location for the download was C:\Users\[username]\AppData\Roaming\npm.
  2. Once you have changed to that directory, simply type the following at the command line:
minion src minion.js

This will generate the JavaScript file, minion.js (a non-minified version), that you can copy to your scripts folder and include in your web application. See the Minion getting started guide for additional details, including how to generate a minified version. Minion also gives you the option to minify the JavaScript containing your classes when finished, though I do not cover that in this tutorial.

Creating classes with Minion

The most basic class syntax in Minion simply has a property, an initialization method, and another basic method. The following class (Weapon.js) doesn't do much but it will serve as a basis for demonstrating how Minion handles inheritance later on.

minion.define("portal", { Weapon : minion.extend("minion.Class", { fireType : "auto", init: function(){ }, getFireType: function(){ return this.fireType; } }) });

Classes are created using the minion.define() function in which you define the namespace (in this case it is "portal" ) and then the class. Every class in Minion must, at some level, extend the base class, which is named minion.Class. Inside the minion.extend() call, you see a fairly typical way of writing pseudo-classes in JavaScript. Much like traditional OO languages, Minion expects that every class is written in its own file and provides mechanisms to let you organize these in folders much the way you might see classes organized in ActionScript or Java.

Inheritance in Minion

As I said, at some level, every class needs to inherit from minion.Class, but your classes can inherit from each other provided this requirement is fulfilled somewhere up the chain. For example, my MachineGun.js and HeatSeekingMissile.js classes, which provide the weaponry of my Portal turrets, both inherit from Weapon.js above. Here is my MachineGun.js class:

minion.define("portal", { MachineGun : minion.extend("portal.Weapon", { weaponType : "machine gun", init: function(){ this.__super(); this.getFireType(); this.weaponType += " (" + this.fireType + ")"; }, getFireType: function(){ this.fireType = this.__super(); } }) });

Note that not much changed from the prior class example except that this class extends portal.Weapon. To access the super class, you call the __super() method from within your class methods. In init() this will invoke the init() method of the super class; in getFireType() it will invoke getFireType() of the super class and so on. You can pass arguments with your __super() call as well. I didn't find a means of directly accessing the super properties other than via a method call nor a way to call a super method other than the one of the same name. Still there are some fairly easy and obvious workarounds to this by building accessor methods for the values you require.

Composition in Minion

Minion can also handle classes that have a or have many instances of another class. For example, my Turret.js class comprises a weapon, which by default is a machine gun (MachineGun.js). Here is the code for this class:

minion.define("portal", { require : [ "portal.MachineGun" ], Turret : minion.extend("minion.Class", { laserEye : true, isEnemyInSight : false, isFiring : false, isKnockedOver : false, motionDetectedArr : ["Target acquired","There you are","I see you","Preparing to dispense product","Activated"], knockedOverArr : ["Critical error","Shutting down","I don't hate you","Hey, hey, hey","Malfunctioning"], ignoredArr : ["Are you still there"], machineGun : null, init: function(){ this.machineGun = new this.__imports.MachineGun(); }, arm: function() { return this.machineGun.weaponType + " armed"; }, fire : function(){ this.isFiring = true; console.log("firing"); }, motionDetected : function(){ this.isFiring = false; this.isEnemyInSight = false; this.isKnockedOver = true; return this.knockedOverArr[Math.floor(Math.random() * this.knockedOverArr.length)]; }, knockedOver : function() { this.isFiring = false; this.isEnemyInSight = false; this.isKnockedOver = true; return this.knockedOverArr[Math.floor(Math.random() * this.knockedOverArr.length)]; }, ignored : function(){ if (this.isKnockedOver) { return "I am knocked over"; } this.isEnemyInSight = false; this.isFiring = false; return this.ignoredArr[Math.floor(Math.random() * this.ignoredArr.length)]; } }) });

While the code for this class is rather long, it really doesn't stray much from the prior examples and is, in fact, quite similar to the code from my framework-less sample. Because Turret is composed of MachineGun, I needed to add the snippet near the top that tells Minion to require the portal.MachineGun class. You can specify any number of required classes here in the same manner. Once this is done, I can access a special scope named __imports that contains the imported classes. You can see that I assign this.machineGun as a new MachineGun() in this way within the init() function:

this.machineGun = new this.__imports.MachineGun();

Putting it all together

Now that my classes are complete, I want to use them in the same sample page as my framework-less example. Most everything about the code remains the same except for loading in the classes via Minion. Here is the HTML:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Minion Sample</title> <script src="js/minion.js"></script> <script> var rTxt, turret, heatSeekingMissile; function load() { rTxt = document.getElementById('responseTxt'); minion.configure({ classPath : "com" }); minion.require( ["portal.Turret", "portal.HeatSeekingMissile"], function(Turret, HeatSeekingMissile){ turret = new Turret(); rTxt.value = turret.arm(); heatSeekingMissile = new HeatSeekingMissile(); } ); } function motionDetected() { rTxt.value = turret.motionDetected(); } function knockedOver() { rTxt.value = turret.knockedOver(); } function ignored() { rTxt.value = turret.ignored(); } function modTurret() { turret.heatSeekingMissile = heatSeekingMissile; turret.arm = function() { return this.heatSeekingMissile.weaponType + " and " + this.machineGun.weaponType + " armed"; }; rTxt.value = turret.arm(); } </script> </head> <body onload="load()"> Response: <input name="responseTxt" id="responseTxt" type="text" size="60" /><br /> <input type="button" name="motionBtn" value="Motion Detected" onclick="motionDetected()"/>&amp;nbsp; <input type="button" name="knockedBtn" value="Knocked Over" onclick="knockedOver()"/>&amp;nbsp; <input type="button" name="ignoredBtn" value="Ignored" onclick="ignored()" />&amp;nbsp; <input type="button" name="missilesBtn" value="Heat Seeking Missiles!"onclick="modTurret()" /> </body> </html>

Take a look at the load() function. It defines for Minion the classpath for my JavaScript files, which is just the relative location of the base file folder containing all my class scripts. In this case, I've placed them in a folder named com. Next, it informs Minion to require any classes that my application needs, which in this case is simply the Turret and HeatSeekingMissile classes (the latter for reasons I'll cover momentarily).

Now, despite being a more classical object-oriented way of defining classes, inheritance, and composition, Minion does not change the dynamic nature of JavaScript. In my prior example, I illustrated this by modding a heat seeking missile onto my Turret. As you can see in the modTurret() function above, I can still dynamically add heatSeekingMissile objects to my class defined via Minion.

In my testing I ran into an interesting issue. Specifically, the loaded JavaScript was cached by the browser (Chrome) and not reflecting my changes. I regularly needed to clear the cache after changes to the JavaScript classes for them to be reflected. This can be corrected, however, by appending a timestamp to file calls via the configure() method. Simply modify the configure method shown above as follows:

minion.configure({ classPath : "com", fileSuffix : Date.now() });

Where to go from here

This article has not touched on all the features of Minion, just the basics you'd need to build your classes. The framework provides a means of defining static properties and methods, creating singletons and static classes, and publishing and subscribing to events and notifications triggered within your model. You can get more details about these in the getting started guide. While Minion is relatively new, it seems pretty robust as a start and the author informs me that it is in use in some large projects, including one for Toyota. Still, the documentation was limited as I developed these classes, so even this simple example did take some trial and error. I do think it is worth checking out if you are looking for a way to structure your JavaScript application in a more classical OO manner, though I am staying out of the debate on the value of this.

If you would like to run the example from this tutorial, you can find it on my site here. The source code is available with the sample files for this article.

Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License+Adobe Commercial Rights

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

More Like This

  • Using CSS3 transitions: A comprehensive guide
  • The pursuit of simplicity
  • An Overview of Brackets' Code Architecture
  • Backbone.js Wine Cellar tutorial – Part 1: Getting started
  • JavaScript design patterns – Part 1: Singleton, composite, and façade
  • Getting started with PhoneGap in Eclipse for Android
  • Using the Geolocation API
  • Unit test JavaScript applications with Jasmine
  • Backbone.js Wine Cellar tutorial – Part 2: CRUD
  • Build a Hangman game with HTML5 Canvas, JavaScript, and CSS – Part 1: Creating the interface

Products

  • Adobe Creative Cloud
  • Creative Suite
  • Adobe Marketing Cloud
  • Acrobat
  • Photoshop
  • Digital Publishing Suite
  • Elements family
  • SiteCatalyst
  • For education

Download

  • Product trials
  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR

Support & Learning

  • Product help
  • Forums

Buy

  • For personal and professional use
  • For students, educators, and staff
  • For small and medium businesses
  • Volume Licensing
  • Special offers

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2013 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy | Cookies

Ad Choices

Reviewed by TRUSTe: site privacy statement