Closure Compiler - obfuscate public methods - inconsistent behavior? - javascript

I just started using Closure Compiler, and I'm seeing some inconsistent behavior regarding obfuscation of public object methods.
I'm using grunt-closure-compiler - here's my grunt config:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
'closure-compiler': {
app: {
closurePath: 'closure-compiler',
js: 'src/app.js',
jsOutputFile: 'js/app.min.js',
maxBuffer: 500,
options: {
compilation_level: 'ADVANCED_OPTIMIZATIONS',
language_in: 'ECMASCRIPT5_STRICT',
formatting: 'PRETTY_PRINT'
}
}
}
});
grunt.loadNpmTasks('grunt-closure-compiler');
};
And here's app.js the file I want to obfuscate:
(function() {
/**
* #constructor
*/
function MyClass() {
var map = {};
this.put = function(name, val) {
map[name] = val;
};
this.get = function(name) {
return map[name];
};
}
var mapper = new MyClass();
mapper.put("first", 123);
alert(mapper.get("first"));
})();
(function() {
/**
* #constructor
*/
function Foo() {
var private_member_1 = 'bla';
this.someMethod = function(param1, param2) {
// do some stuff
console.log('abc');
return private_member_1;
};
// etc...
}
var foo = new Foo();
var value = foo.someMethod();
console.log(value + value);
})();
And this is the output after running grunt closure-compiler:app
'use strict';(function() {
var a = new function() {
var a = {};
this.put = function(b, c) {
a[b] = c;
};
this.get = function(b) {
return a[b];
};
};
a.put("first", 123);
alert(a.get("first"));
})();
(function() {
var a = (new function() {
this.a = function() {
console.log("abc");
return "bla";
};
}).a();
console.log(a + a);
})();
Notice that in the first closure the methods put and get were not obfuscated, while in the second closure the method someMethod was obfuscated.
Why does this happen? And how can I cause all public methods in all of my classes (like put and get) to be obfuscated as well?
Please note -
I am willing to use a different tool other than Closure Compiler to achieve this.
I want to use this with TypeScript, i.e. obfuscate the compiled TypeScript code, this is why I have many public methods.
Some specific methods are API methods that should not be obfuscated. So I need a way to tell the obfuscator which methods to skip.

Update
As of the 20150315 release of Closure-compiler, the type based optimizations are enabled by default.
This is actually covered in the project FAQ.
The option you want is use_types_for_optimization. This will enable property renaming even if a property of the same name is defined on an unrelated object.
The comprehensive list of properties which can only be renamed with this flag is huge: any property name defined on any object in an extern file.

I figured it out - get and put are considered reserved words, and closure compiler ignores them on purpose.
I ran across a list of these reserved words earlier, but I can't find it now... would appreciate if someone posts a link to the complete list.

Related

is this a new javascript factory pattern?

Fair warning - a long time ago I wrote a lot of C++ and can't help the temptation to coerce javascript into design patterns I was familiar with back then. It's ok to accuse me of atavism in any replies ;-)
In my current project, I want to create objects by name, which indicates the factory pattern. So I read the top page of google hits for 'javascript factory pattern'. They all have this ugly thing in common:
if (name === 'FactoryPartA') {
parentClass = PartA;
} else if (name === 'FactoryPartB') {
parentClass = PartB;
} else if ...
parentClass = PartZ;
}
return new parentClass();
Which has 2 problems:
Every time I create a new part for the factory to make, I have to edit the factory's implementation and I'd prefer to avoid both the work & the bug-insertion opportunity.
It's a hard-coded, linear search which hardly screams "efficiency!"
So here's what I came up with - a combination of the module and factory patterns with the info hiding merits of the module pattern provided by the tactic of defining the classes of factory parts inside the factory's register closure.
Finally getting to my question: I can't believe that this hasn't been done before by better coders than me so please share a link to the canonical version of this twist on the factory pattern if you know of one.
N.B. For this example I've run all my code together. In my project the factory, FactoryPartA, FactoryPartB, and client code are all in separate files.
namespace('mynamespace');
// object factory
mynamespace.factory = (function () {
'use strict';
var api = {};
var registry = [];
// register an item
api.register = function (item) {
if (registry.some (function (r) {return r.name === item.name;})) {
throw new Error ('factory.register(): name collision detected: ' + name);
} else {
registry.push(item);
}
};
// make an item given its name
api.make = function (name) {
var item = null;
var idx = registry.findIndex (function (r) {
return r.name === name;
});
if (idx >= 0) {
item = new registry[idx].make();
}
return item;
};
return api;
})();
// define a module & register it with factory
mynamespace.factory.register ({
name: 'FactoryPartA',
make: function FactoryPartA () {
'use strict';
var label = 'Factory Part A'; // private property
this.test = undefined; // public property
this.label = function () { // public method
return label;
};
return this;
}
});
// define a different module & register it with factory
mynamespace.factory.register ({
name: 'FactoryPartB',
make: function FactoryPartB () {
'use strict';
var label = 'Factory Part B';
this.test = undefined;
this.label = function () {
return label;
};
return this;
}
});
// client code
var aPart = mynamespace.factory.make('FactoryPartA');
var bPart = mynamespace.factory.make('FactoryPartB');
console.log (aPart.label()); // logs 'Factory Part A'
console.log (bPart.label()); // logs 'Factory Part B'
var anotherPart = mynamespace.factory.make('FactoryPartA');
aPart.test = 'this one is not';
anotherPart.test = 'the same as this one';
console.log (aPart.test !== anotherPart.test); // logs true
To answer the fundamental question - is this a new Javascript factory pattern - no, it is not. (Check out ES6/ES2015, Typescript, and Aurelia's dependency injection module.)
Now, to answer the overall statement - what you're essentially doing is trying to add metadata to a "class" type in Javascript. The thing is, it looks like you're trying to create a factory of factories - which I'm not sure you need. (Perhaps you've simplified your example.)
With your example, I'd do something more like this:
namespace('mynamespace');
// object factory
mynamespace.factory = (function () {
'use strict';
var api = {};
var registry = {};
// register an item
api.register = function (name, item, overwrite) {
if (!overwrite || registry.hasOwnProperty('name')) {
throw new Error ('factory.register(): name collision detected: ' + name);
}
registry[name] = item;
};
// make an item given its name
api.make = function (name) {
var item = registry[name];
return item ? new item() : null; // or better, Object.create(item);
};
return api;
})();
// define a module & register it with factory
mynamespace.factory.register ('FactoryPartA', function FactoryPartA () {
'use strict';
var label = 'Factory Part A'; // private property
this.test = undefined; // public property
this.label = function () { // public method
return label;
};
});
// define a different module & register it with factory
mynamespace.factory.register ('FactoryPartB', function FactoryPartB () {
'use strict';
var label = 'Factory Part B';
this.test = undefined;
this.label = function () {
return label;
};
});
This removes the extra factory stuff so that it's not a FactoryFactory. (Not sure why you had that.) Further, you mentioned a linear search - by using a object instead of an array, you avoid a linear lookup (object hashes are constant-time lookup). Finally - you can actually register any name without having to place it into a wrapper object. This is closer to DI.
If you really want to do the metadata-style approach, though, you can do something like the following:
namespace('mynamespace');
// object factory
mynamespace.factory = (function () {
'use strict';
var api = {};
var registry = {};
// register an item
api.register = function (item, overwrite) {
if (!overwrite || registry.hasOwnProperty(item.name)) {
throw new Error ('factory.register(): name collision detected: ' + item.name);
}
registry[item.name] = item;
};
// make an item given its name
api.make = function (name) {
var item = registry[name];
return item ? new item() : null; // or better, Object.create(item);
};
return api;
})();
// define a module & register it with factory
mynamespace.factory.register (function FactoryPartA () {
'use strict';
var label = 'Factory Part A'; // private property
this.test = undefined; // public property
this.label = function () { // public method
return label;
};
});
// define a different module & register it with factory
mynamespace.factory.register (function FactoryPartB () {
'use strict';
var label = 'Factory Part B';
this.test = undefined;
this.label = function () {
return label;
};
});
This uses the function name instead of a separate property. (Functions can be named or anonymous in Javascript. This method would not work with anonymous functions.) I mentioned Typescript above because when Typescript compiles to Javascript, it actually places a lot of its own metadata on objects, similar to what you're doing. I mentioned Aurelia's dependency injection because its #autoinject functionality actually reads this metadata to create objects, similar to what you're doing.
But really....unless you're attempting to create a dependency injection container (which would require more logic than is in your example - you'd want a container with keys that can point to instances as well) I would argue that you'll get much more functionality out of Object.create() and Object.assign() than you would with this pattern. A lot of the design patterns that you need in a statically typed, strongly typed, compiled language, aren't necessary outside of that environment. So you can do this:
function PartA () {
'use strict';
var label = 'Factory Part A'; // private property
this.test = undefined; // public property
this.label = function () { // public method
return label;
}
function PartB () {
'use strict';
var label = 'Factory Part B';
this.test = undefined;
this.label = function () {
return label;
};
}
var A = Object.create(PartA);
var B = Object.create(PartB);
This is, simply, much easier.

How to combine prototypes from closed functions?

Having a project where I have speed coded up some core functionality I would like to split it up into modules. My struggle now is how to combine prototypes from one to the next. My idea is something like this:
(function (window) {
/* Code for base module with core functions. */
function CORE () {
}
window.CORE = CORE; /* I use different naming in real code ... */
})(window);
(function (CORE) {
/* Code for module with extending functionality. */
function MODULE1 () {
}
CORE.MODULE1 = MODULE1;
})(window.CORE);
I use an approach for creation as something like:
(function (window) {
var Core = function (options) {
return new Core.prototype.init(options);
}
Core.prototype = {
init : function (options) {
this.a = options.a;
return this;
}
}
Core.prototype.init.prototype = Core.prototype;
Core.prototype.init.prototype.fun1 = function () { }
Core.prototype.init.prototype.fun2 = function () { }
...
window.Core = Core; /* Optionally = Core.init */
})(window);
And then a module like:
(function (Core) {
var Module1 = Core.Module1 = function (options) {
return new Module1.prototype.build(options);
}
Module1.prototype = {
build : function (options) {
this.a = options.a;
return this;
}
}
Module1.prototype.build.prototype = Module1.prototype;
Module1.prototype.build.prototype.fun1 = function () { }
Module1.prototype.build.prototype.fun2 = function () { }
...
Core.Module1 = Module1;
Core.Module1_XO = Module1.prototype.build;
})(window.Core);
Now a print of toString() of Core, Core.Module1 and Core.Module1_XO all yield their respective code. But there is no binding as in:
If I say:
var obj = Core({...}); , OK.
obj.Module1({...}), Fail. Object #<Object> has no method Module1
new obj.Module1_XO({...}), Fail. undefined is not a function
Core.Module1({...}), OK, but looses prototypes from Core.
new Core.Module1_XO({...}), OK, but looses prototypes from Core.
...
One way that seem to work is by updating Core by a bind function as in:
var obj = Core({...});
var mod1 = Core.Module1({...}, obj); <-- pass obj
// In Module1 constructor:
build : function (options, ref) {
this.a = options.a;
ref.bind("Module1", this);
}
// And In Core:
Core.prototype.bind(which, what) {
this[which] = what;
}
Question is how I can update Core with Module without this hack. Why doesn't Core become updated by:
window.Core.Module1 = Module1;
Is it hidden from Core?
I have also tried to bind in outer scope of module as in:
(function (Core) {
/* ... code ... for Mudule1 */
Core.bind("Module1", Module1);
}(window.Core);
But this fails as well. Core does not get updated with methods from Module.
Here is a scramble of a fiddle I have messed with, (Note that the printed text is in reverse (prepended) not appended such as newest on top.). It is not the most tidy code, and It is in midts of edits. (I try new approaches frequently.)
What you're doing right now is problematic for several reasons:
You're adding a module to the constructor (type) and not the objects.
Global state here - everyone gets one Module1.
My suggestion would be using a generic version of the builder pattern (or even a mediator).
Here is what it might look like.
Core = (function Core(){
var modules = [];
return {
setModule : function(name,value){
modules.push({name:name,value:value});
},
build : function(options){
this.a = options.a;
// now let's add all modules
modules.forEach(function(module){
this[module.name] = new module.value();
});
}
};
});
Usage would be something like:
var app = new Core.build({a:"foo"});
app.a;//"foo"
If you want to add a module it'd be something like
function Module1(){
this.name = "Zimbalabim";
}
Core.setModule("Module1",Module1);
var app = new Core.build({a:"Bar"});
app.Module1.name;//"Zimbalabim"
app.a;//"Bar"
Or course, a more generic architecture would allow creating different apps with different architectures (with dependency injection containers probably) but let's not go that far yet :)

Split module pattern javascript code into files

I am writing a javascript framework using the module pattern, which looks like this:
var EF = (function(doc) {
// Main public object
var e = {
version: "1.0.0",
doc: doc,
log: true
};
// Private methods
var method1 = function(el) {
<some code>
}
var method2 = function(el) {
<some code>
}
var method3 = function(el) {
<some code>
}
// PUBLIC METHODS ASSIGNMENT
e.method1 = method1;
e.method2 = method2;
e.method3 = method3;
return e;
}(document));
Now I decided that I should move some methods to the separate file.
During development I then would load two files one by one in the HTML file, while for deployment I would merge them in a single file.
What is the correct way move part of the methods to a separate files keeping the structure of the code that I use?
I've seen the following suggestion in one of the answers on stackoverflow:
var MODULE = (function (my) {
var privateToThisFile = "something";
// add capabilities...
my.publicProperty = "something";
return my;
}(MODULE || {}));
It looks almost like what I need, but it shows private methods for the file and for the module. But I need private methods for the module and pubic methods for the module.
What suggestions would you have?
I am not sure what exactly you want, but I guess you want to access the private function via module object. In essence it's public pointer to a private property.
Let me know further if I can help you. A problem example with a jsFiddle would be great.
var myRevealingModule = function () {
var privateCounter = 0;
function privateFunction() {
privateCounter++;
}
function publicFunction() {
publicIncrement();
}
function publicIncrement() {
privateFunction();
}
function publicGetCount(){
return privateCounter;
}
// Reveal public pointers to
// private functions and properties
return {
start: publicFunction,
increment: publicIncrement,
count: publicGetCount
};
}();
myRevealingModule.start();

How to handle circular dependencies with RequireJS/AMD?

In my system, I have a number of "classes" loaded in the browser each a separate files during development, and concatenated together for production. As they are loaded, they initialize a property on a global object, here G, as in this example:
var G = {};
G.Employee = function(name) {
this.name = name;
this.company = new G.Company(name + "'s own company");
};
G.Company = function(name) {
this.name = name;
this.employees = [];
};
G.Company.prototype.addEmployee = function(name) {
var employee = new G.Employee(name);
this.employees.push(employee);
employee.company = this;
};
var john = new G.Employee("John");
var bigCorp = new G.Company("Big Corp");
bigCorp.addEmployee("Mary");
Instead of using my own global object, I am considering to make each class its own AMD module, based on James Burke's suggestion:
define("Employee", ["Company"], function(Company) {
return function (name) {
this.name = name;
this.company = new Company(name + "'s own company");
};
});
define("Company", ["Employee"], function(Employee) {
function Company(name) {
this.name = name;
this.employees = [];
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee(name);
this.employees.push(employee);
employee.company = this;
};
return Company;
});
define("main", ["Employee", "Company"], function (Employee, Company) {
var john = new Employee("John");
var bigCorp = new Company("Big Corp");
bigCorp.addEmployee("Mary");
});
The issue is that before, there was no declare-time dependency between Employee and Company: you could put the declaration in whatever order you wanted, but now, using RequireJS, this introduces a dependency, which is here (intentionally) circular, so the above code fails. Of course, in addEmployee(), adding a first line var Employee = require("Employee"); would make it work, but I see this solution as inferior to not using RequireJS/AMD as it requires me, the developer, to be aware of this newly created circular dependency and do something about it.
Is there a better way to solve this problem with RequireJS/AMD, or am I using RequireJS/AMD for something it was not designed for?
This is indeed a restriction in the AMD format. You could use exports, and that problem goes away. I find exports to be ugly, but it is how regular CommonJS modules solve the problem:
define("Employee", ["exports", "Company"], function(exports, Company) {
function Employee(name) {
this.name = name;
this.company = new Company.Company(name + "'s own company");
};
exports.Employee = Employee;
});
define("Company", ["exports", "Employee"], function(exports, Employee) {
function Company(name) {
this.name = name;
this.employees = [];
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee.Employee(name);
this.employees.push(employee);
employee.company = this;
};
exports.Company = Company;
});
Otherwise, the require("Employee") you mention in your message would work too.
In general with modules you need to be more aware of circular dependencies, AMD or not. Even in plain JavaScript, you have to be sure to use an object like the G object in your example.
I think this is quite a drawback in larger projects where (multi-level) circular dependencies dwell undetected.
However, with madge you can print a list of circular dependencies to approach them.
madge --circular --format amd /path/src
If you don't need your dependencies to be loaded at the start (e.g., when you are extending a class), then this is what you can do: (taken from http://requirejs.org/docs/api.html#circular)
In the file a.js:
define( [ 'B' ], function( B ){
// Just an example
return B.extend({
// ...
})
});
And in the other file b.js:
define( [ ], function( ){ // Note that A is not listed
var a;
require(['A'], function( A ){
a = new A();
});
return function(){
functionThatDependsOnA: function(){
// Note that 'a' is not used until here
a.doStuff();
}
};
});
In the OP's example, this is how it would change:
define("Employee", [], function() {
var Company;
require(["Company"], function( C ){
// Delayed loading
Company = C;
});
return function (name) {
this.name = name;
this.company = new Company(name + "'s own company");
};
});
define("Company", ["Employee"], function(Employee) {
function Company(name) {
this.name = name;
this.employees = [];
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee(name);
this.employees.push(employee);
employee.company = this;
};
return Company;
});
define("main", ["Employee", "Company"], function (Employee, Company) {
var john = new Employee("John");
var bigCorp = new Company("Big Corp");
bigCorp.addEmployee("Mary");
});
I looked at the docs on circular dependencies :http://requirejs.org/docs/api.html#circular
If there is a circular dependency with a and b , it says in your module to add require as a dependency in your module like so :
define(["require", "a"],function(require, a) { ....
then when you need "a" just call "a" like so:
return function(title) {
return require("a").doSomething();
}
This worked for me
I would just avoid the circular dependency. Maybe something like:
G.Company.prototype.addEmployee = function(employee) {
this.employees.push(employee);
employee.company = this;
};
var mary = new G.Employee("Mary");
var bigCorp = new G.Company("Big Corp");
bigCorp.addEmployee(mary);
I don't think it's a good idea to work around this issue and try to keep the circular dependency. Just feels like general bad practice. In this case it can work because you really require those modules for when the exported function is called. But imagine the case where modules are required and used in the actual definition functions itself. No workaround will make that work. That's probably why require.js fails fast on circular dependency detection in the dependencies of the definition function.
If you really have to add a work around, the cleaner one IMO is to require a dependency just in time (in your exported functions in this case), then the definition functions will run fine. But even cleaner IMO is just to avoid circular dependencies altogether, which feels really easy to do in your case.
All the posted answers (except https://stackoverflow.com/a/25170248/14731) are wrong. Even the official documentation (as of November 2014) is wrong.
The only solution that worked for me is to declare a "gatekeeper" file, and have it define any method that depends on the circular dependencies. See https://stackoverflow.com/a/26809254/14731 for a concrete example.
Here is why the above solutions will not work.
You cannot:
var a;
require(['A'], function( A ){
a = new A();
});
and then use a later on, because there is no guarantee that this code block will get executed before the code block that uses a. (This solution is misleading because it works 90% of the time)
I see no reason to believe that exports is not vulnerable to the same race condition.
the solution to this is:
//module A
define(['B'], function(b){
function A(b){ console.log(b)}
return new A(b); //OK as is
});
//module B
define(['A'], function(a){
function B(a){}
return new B(a); //wait...we can't do this! RequireJS will throw an error if we do this.
});
//module B, new and improved
define(function(){
function B(a){}
return function(a){ //return a function which won't immediately execute
return new B(a);
}
});
now we can use these modules A and B in module C
//module C
define(['A','B'], function(a,b){
var c = b(a); //executes synchronously (no race conditions) in other words, a is definitely defined before being passed to b
});
In my case I solved the circular dependency by moving the code of the "simpler" object into the more complex one. For me that was a collection and a model class. I guess in your case I would add the Employee-specific parts of Company into the Employee class.
define("Employee", ["Company"], function(Company) {
function Employee (name) {
this.name = name;
this.company = new Company(name + "'s own company");
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee(name);
this.employees.push(employee);
employee.company = this;
};
return Employee;
});
define("Company", [], function() {
function Company(name) {
this.name = name;
this.employees = [];
};
return Company;
});
define("main", ["Employee", "Company"], function (Employee, Company) {
var john = new Employee("John");
var bigCorp = new Company("Big Corp");
bigCorp.addEmployee("Mary");
});
A bit hacky, but it should work for simple cases. And if you refactor addEmployee to take an Employee as parameter, the dependency should be even more obvious to outsiders.

Question about a particular pattern of Javascript class definition

Recently I saw the following code that creates a class in javascript:
var Model.Foo = function(){
// private stuff
var a, b;
// public properties
this.attr1 = '';
this.attr2 = '';
if(typeof Model.Foo._init === 'undefined'){
Model.Foo.prototype = {
func1 : function(){ //...},
func2 : function(){ //... },
//other prototype functions
}
}
Model.Foo._init = true;
}
// Instantiate and use the class as follows:
var foo = new Model.Foo(); foo.func1();
I guess the _init variable is used to make sure we don't define the prototypes again. Also, I feel the code is more readable since I am placing everything in a function block (so in oop-speak, all attributes and methods are in one place).
Do you see any issues with the code above? Any pitfalls of using this pattern if I need to create lots of classes in a big project?
This is a weird Javascript pattern that I would never use to develop object-oriented JS code. For one thing, Model.Foo._init === 'undefined' never evaluates to true if Model.Foo._init is anything but the string 'undefined'; therefore, the code
Model.Foo.prototype = {
func1 : function(){ /* ... */},
func2 : function(){ /* ... */},
//other prototype functions
}
will not run unless that condition holds true. (Perhaps the author meant to add a typeof, as in typeof Model.Foo._init === 'undefined'? I don't know.)
Addressing your concern about "[making] sure we don't define the prototypes again", this is already achieved with:
Model.Foo = function() {
// private stuff
var a, b;
// public properties
this.attr1 = '';
this.attr2 = '';
};
Model.Foo.prototype = {
func1 : function() { /* ... */},
func2 : function() { /* ... */}
//,other prototype functions
};
// Instantiate and use the class as follows:
var foo = new Model.Foo();
foo.func1();
which is along the lines of what I recommend if you aren't using a framework.
Basically, the answer to your question is: if you use this non-standard pattern for development, then other programmers, maybe even yourself a few months later, will find it difficult to extend and work with.
It just seems unnecessarily complex. You need to be disciplined to not use any parameters or local variables of Model.Foo in the implementation of the prototype extension. Its odd to overwrite the entire .prototype object and not just add individual members as well. Why not just do this the normal way?
var Model.Foo = function(){
// private stuff
var a, b;
// public properties
this.attr1 = '';
this.attr2 = '';
}
Model.Foo.prototype.func1 = function(){ //...};
Model.Foo.prototype.func2 = function(){ //... };
alternate allowing per-instance member variables private
var Model.Foo = function(){
// private stuff
var a, b;
// public properties
this.attr1 = '';
this.attr2 = '';
this.func1 = function(){ //...};
this.func2 = function(){ //... };
}
A few things stand out as potentially troublesome:
Foo.prototype is set to a simple object, which can't extend anything using this pattern.
Where is the "private stuff" used? Every time you create a new object, you create new private variables, which seemingly can only be used in the functions defined in Foo.prototype, which should only be run once.
It's kind of a mess, and there are details/examples all over the web of better was to do this.
The following example illustrates a pattern that I personally developed over time.
It exploits scoping to allow private fields and methods.
Employee = (function(){
// private static field
var staticVar;
// class function a.k.a. constructor
function cls()
{
// private instance field
var name = "";
var self = this;
// public instance field
this.age = 10;
// private instance method
function increment()
{
// must use self instead of this
self.age ++;
}
// public instance method
this.getName = function(){
return cls.capitalize(name);
};
this.setName = function(name2){
name = name2;
};
this.increment = function(){
increment();
};
this.getAge = function(){
return this.age;
};
}
// public static field
cls.staticVar = 0;
// public static method
cls.capitalize = function(name){
return name.substring(0, 1).toUpperCase() +
name.substring(1).toLowerCase();
};
// private static method
function createWithName(name)
{
var obj = new cls();
obj.setName(cls.capitalize(name));
return obj;
}
return cls;
})();
john = new Employee();
john.setName("john");
mary = new Employee();
mary.setName("mary");
mary.increment();
alert("John's name: " + john.getName() + ", age==10: "+john.getAge());
alert("Mary's name: " + mary.getName() + ", age==11: "+mary.getAge());

Categories