Last active
August 29, 2015 14:12
-
-
Save widged/a000c723065d05659a3d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Person Module | |
var Person = (function ( ) { | |
'use strict'; | |
// Any static variable can be declared here. | |
var Class = function Person() { | |
if(!this instanceof Person) { return new Person(); } | |
var instance = this; | |
// Private variables and functions that only | |
// ..other private or public functions may access | |
// ..and cannot be accessed outside this Module | |
var age = 0, | |
maxAge = 30, | |
maxWeight = 80, | |
isAlive = true, | |
weight = 20, | |
name = 'Un-named'; | |
function growOld() { | |
if ( age++ >= maxAge ) { | |
die(); | |
} | |
} | |
function gainWeight() { | |
weight++; | |
if ( weight >= maxWeight ) { | |
die(); | |
} | |
} | |
function loseWeight() { | |
weight--; | |
if ( weight <= 0 ) { | |
die(); | |
} | |
} | |
function die() { isAlive = false; } | |
// All the properties and methods attached to `instance` | |
// will be public and will be accessible in the global scope. | |
// Public Accessors | |
instance.name = function(_) { | |
if(!arguments.length) { return name; } | |
name = _; | |
return instance; | |
} | |
instance.age = function(_) { | |
if(!arguments.length) { return age; } | |
if(_ > maxAge && age < 0) { throw 'illegal age value' } | |
age = _; | |
return instance; | |
} | |
instance.weight = function(_) { | |
if(!arguments.length) { return weight; } | |
if(_ > maxWeight && weight < 0) { throw 'illegal weight value' } | |
weight = _; | |
return instance; | |
} | |
// Public Methods | |
instance.speak = function () { | |
if ( !isAlive ) { | |
alert('Dead man can\'t speak.'); | |
} else { | |
alert('Speaking...'); | |
growOld(); | |
} | |
return instance; | |
}, | |
instance.walk = function () { | |
if ( !isAlive ) { | |
alert('Dead man can\'t walk.'); | |
} else { | |
alert('Walking...'); | |
growOld(); | |
loseWeight(); | |
} | |
return instance; | |
}, | |
instance.eat = function () { | |
if ( !isAlive ) { | |
alert('Dead man can\'t eat'); | |
} else { | |
alert('Eating...'); | |
gainWeight(); | |
} | |
return instance; | |
} | |
instance.toString = function() { | |
return '' + Class.name + ' ' + JSON.stringify({name: name, age: age, weight: weight}); | |
} | |
return instance; | |
} | |
return Class; | |
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var bill = new Person().name('Bill').age(40).weight(30); | |
console.log(bill.eat().weight()) | |
console.log(bill.walk().age()) | |
console.log(bill.toString()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Motivations for differences with the code shown at http://kamranahmed.info/blog/2015/01/03/private-and-public-scopes-in-javascript/ are:
(1) Introducing an instance variable let me write functions the normal way. I don't need a different syntax for private and public functions, which makes it slightly easier when refactoring.
(2) Introducing an instance variable provides support for a chainable interface
var bill = new Person().name('Bill').age(40).weight(30);
. The convention then is for any function that doesn't return a value to return the instance.(3) Opting for Class = new FactoryName() creates a factory that creates typed instanced (try
console.log(new Person())
).(4) Wrapping the code into a module (IIFE, AMD, or Commonjs) protects against global scope pollution
(5) The extra module level gives an opportunity to declare static values if necessary (values that are constant across all Person instances) at the top of the module. Static methods can also be defined by attaching them to the
Class
object (Class really is a no more than an instance factory).