{"_id":"declare.js","_rev":"31392","name":"declare.js","description":"OO system from node and browser","dist-tags":{"latest":"0.0.8"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"time":{"modified":"2021-06-03T10:05:15.000Z","created":"2012-10-01T05:53:44.291Z","0.0.8":"2014-04-01T18:07:45.330Z","0.0.7":"2013-06-17T22:30:29.641Z","0.0.6":"2013-06-06T02:13:08.887Z","0.0.4":"2013-01-25T20:38:01.319Z","0.0.3":"2013-01-19T20:15:09.617Z","0.0.2":"2012-11-28T06:28:01.285Z","0.0.1":"2012-10-01T05:53:44.291Z"},"users":{"ericteng177":true},"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"versions":{"0.0.8":{"name":"declare.js","version":"0.0.8","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz"],"testling":{"files":"test/browserling.js","browsers":["ie/8..latest","chrome/20..latest","firefox/14..latest","safari/latest","iphone/6","ipad/6"]},"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.2.0","grunt-it":"~0.3.1","grunt-contrib-uglify":"~0.2.2","grunt-contrib-jshint":"~0.6.0","grunt":"~0.4.1"},"dependencies":{},"bugs":{"url":"https://github.com/doug-martin/declare.js/issues"},"homepage":"https://github.com/doug-martin/declare.js","_id":"declare.js@0.0.8","dist":{"shasum":"0478adff9564c004f51df73d8bc134019d28dcde","size":29708,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.8.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.8.tgz"},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1396375665330,"_cnpm_publish_time":1396375665330,"_hasShrinkwrap":false},"0.0.7":{"name":"declare.js","version":"0.0.7","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"testling":{"files":"test/browserling.js","browsers":["ie/8..latest","chrome/20..latest","firefox/14..latest","safari/latest","iphone/6","ipad/6"]},"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.2.0","grunt-it":"~0.3.1","grunt-contrib-uglify":"~0.2.2","grunt-contrib-jshint":"~0.6.0"},"dependencies":{"grunt":"~0.4.1"},"readmeFilename":"README.md","bugs":{"url":"https://github.com/doug-martin/declare.js/issues"},"_id":"declare.js@0.0.7","dist":{"shasum":"fe782fd34d4ddd5b4b1823c140921c53c2d79070","size":29748,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.7.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.7.tgz"},"_from":".","_npmVersion":"1.2.25","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1371508229641,"_cnpm_publish_time":1371508229641,"_hasShrinkwrap":false},"0.0.6":{"name":"declare.js","version":"0.0.6","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"testling":{"files":"test/browserling.js","browsers":["ie/8..latest","chrome/20..latest","firefox/14..latest","safari/latest","iphone/6","ipad/6"]},"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.2.0","grunt-it":"~0.3.1","grunt-contrib-uglify":"~0.2.2","grunt-contrib-jshint":"~0.6.0"},"dependencies":{"grunt":"~0.4.1"},"readmeFilename":"README.md","bugs":{"url":"https://github.com/doug-martin/declare.js/issues"},"_id":"declare.js@0.0.6","dist":{"shasum":"94a7756e21b8ef6ce9bf5d652088f77e2b122af7","size":25303,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.6.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.6.tgz"},"_from":".","_npmVersion":"1.2.23","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1370484788887,"_cnpm_publish_time":1370484788887,"_hasShrinkwrap":false},"0.0.4":{"name":"declare.js","version":"0.0.4","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"testling":{"files":"test/browserling.js","browsers":{"ie":[6,7,8,9],"chrome":[4,23,"canary"],"firefox":[3,3.5,3.6,4,17,"nightly"],"opera":[10,10.5,11,11.5,11.6,12,"next"],"safari":["5.0.1",5.1]}},"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.2.0"},"readmeFilename":"README.md","_id":"declare.js@0.0.4","dist":{"shasum":"e5fb33224cff8f7b696be397de1979e057170755","size":23676,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.4.tgz"},"_npmVersion":"1.2.0","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1359146281319,"_cnpm_publish_time":1359146281319,"_hasShrinkwrap":false},"0.0.3":{"name":"declare.js","version":"0.0.3","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.1.0"},"readmeFilename":"README.md","_id":"declare.js@0.0.3","dist":{"shasum":"666357c04766ee59508c8942c114b2ff27658030","size":20048,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.3.tgz"},"_npmVersion":"1.2.0","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1358626509617,"_cnpm_publish_time":1358626509617,"_hasShrinkwrap":false},"0.0.2":{"name":"declare.js","version":"0.0.2","description":"OO system from node and browser","main":"index.js","scripts":{"test":"export NODE_PATH=. && it -r dotmatrix"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.1.0"},"readmeFilename":"README.md","_id":"declare.js@0.0.2","dist":{"shasum":"72736adf56ca5e8bb69355ceffb53cd8203ca243","size":15825,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.2.tgz"},"_npmVersion":"1.1.65","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1354084081285,"_cnpm_publish_time":1354084081285,"_hasShrinkwrap":false},"0.0.1":{"name":"declare.js","version":"0.0.1","description":"OO system from node and browser","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git@github.com:doug-martin/declare.js.git"},"keywords":["OO","class","object","clazz",""],"author":{"name":"Doug Martin","url":"doug@dougamartin.com"},"license":"MIT","devDependencies":{"it":"0.0.5"},"_id":"declare.js@0.0.1","dist":{"shasum":"d77c01d019c8596dc7cc6e1371b7eb28113d97e7","size":10840,"noattachment":false,"key":"/declare.js/-/declare.js-0.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/declare.js/download/declare.js-0.0.1.tgz"},"_npmVersion":"1.1.61","_npmUser":{"name":"damartin","email":"doug@dougamartin.com"},"maintainers":[{"name":"damartin","email":"doug@dougamartin.com"}],"directories":{},"publish_time":1349070824291,"_cnpm_publish_time":1349070824291,"_hasShrinkwrap":false}},"readme":"[![Build Status](https://travis-ci.org/doug-martin/declare.js.png?branch=master)](https://travis-ci.org/doug-martin/declare.js)\n\n[![browser support](https://ci.testling.com/doug-martin/declare.js.png)](https://ci.testling.com/doug-martin/declare.js)\n\n<a name=\"top\"></a>\n\n\nDeclare is a library designed to allow writing object oriented code the same way in both the browser and node.js.\n\n##Installation\n\n`npm install declare.js`\n\nOr [download the source](https://raw.github.com/doug-martin/declare.js/master/declare.js) ([minified](https://raw.github.com/doug-martin/declare.js/master/declare-min.js))\n\n###Requirejs\n\nTo use with requirejs place the `declare` source in the root scripts directory\n\n```javascript\n\ndefine([\"declare\"], function(declare){\n     return declare({\n         instance : {\n             hello : function(){\n                 return \"world\";\n             }\n         }\n     });\n});\n\n```\n\n\n##Usage\n\ndeclare.js provides\n\nClass methods\n\n* `as(module | object, name)` : exports the object to module or the object with the name\n* `mixin(mixin)` : mixes in an object but does not inherit directly from the object. **Note** this does not return a new class but changes the original class.\n* `extend(proto)` : extend a class with the given properties. A shortcut to `declare(Super, {})`;\n\nInstance methods\n\n* `_super(arguments)`: calls the super of the current method, you can pass in either the argments object or an array with arguments you want passed to super\n* `_getSuper()`: returns a this methods direct super.\n* `_static` : use to reference class properties and methods.\n* `get(prop)` : gets a property invoking the getter if it exists otherwise it just returns the named property on the object.\n* `set(prop, val)` : sets a property invoking the setter if it exists otherwise it just sets the named property on the object.\n\n\n###Declaring a new Class\n\nCreating a new class with declare is easy!\n\n```javascript\n\nvar Mammal = declare({\n     //define your instance methods and properties\n     instance : {\n\n         //will be called whenever a new instance is created\n         constructor: function(options) {\n             options = options || {};\n             this._super(arguments);\n             this._type = options.type || \"mammal\";\n         },\n\n         speak : function() {\n             return  \"A mammal of type \" + this._type + \" sounds like\";\n         },\n\n         //Define your getters\n         getters : {\n\n             //can be accessed by using the get method. (mammal.get(\"type\"))\n             type : function() {\n                 return this._type;\n             }\n         },\n\n          //Define your setters\n         setters : {\n\n               //can be accessed by using the set method. (mammal.set(\"type\", \"mammalType\"))\n             type : function(t) {\n                 this._type = t;\n             }\n         }\n     },\n\n     //Define your static methods\n     static : {\n\n         //Mammal.soundOff(); //\"Im a mammal!!\"\n         soundOff : function() {\n             return \"Im a mammal!!\";\n         }\n     }\n});\n\n\n```\n\nYou can use Mammal just like you would any other class.\n\n```javascript\nMammal.soundOff(\"Im a mammal!!\");\n\nvar myMammal = new Mammal({type : \"mymammal\"});\nmyMammal.speak(); // \"A mammal of type mymammal sounds like\"\nmyMammal.get(\"type\"); //\"mymammal\"\nmyMammal.set(\"type\", \"mammal\");\nmyMammal.get(\"type\"); //\"mammal\"\n\n\n```\n\n###Extending a class\n\nIf you want to just extend a single class use the .extend method.\n\n```javascript\n\nvar Wolf = Mammal.extend({\n\n  //define your instance method\n  instance: {\n\n       //You can override super constructors just be sure to call `_super`\n      constructor: function(options) {\n         options = options || {};\n         this._super(arguments); //call our super constructor.\n         this._sound = \"growl\";\n         this._color = options.color || \"grey\";\n     },\n\n     //override Mammals `speak` method by appending our own data to it.\n     speak : function() {\n         return this._super(arguments) + \" a \" + this._sound;\n     },\n\n     //add new getters for sound and color\n     getters : {\n\n          //new Wolf().get(\"type\")\n          //notice color is read only as we did not define a setter\n         color : function() {\n             return this._color;\n         },\n\n         //new Wolf().get(\"sound\")\n         sound : function() {\n             return this._sound;\n         }\n     },\n\n     setters : {\n\n         //new Wolf().set(\"sound\", \"howl\")\n         sound : function(s) {\n             this._sound = s;\n         }\n     }\n\n },\n\n static : {\n\n     //You can override super static methods also! And you can still use _super\n     soundOff : function() {\n         //You can even call super in your statics!!!\n         //should return \"I'm a mammal!! that growls\"\n         return this._super(arguments) + \" that growls\";\n     }\n }\n});\n\nWolf.soundOff(); //Im a mammal!! that growls\n\nvar myWolf = new Wolf();\nmyWolf instanceof Mammal //true\nmyWolf instanceof Wolf //true\n\n```\n\nYou can also extend a class by using the declare method and just pass in the super class.\n\n```javascript\n//Typical hierarchical inheritance\n// Mammal->Wolf->Dog\nvar Dog = declare(Wolf, {\n   instance: {\n       constructor: function(options) {\n           options = options || {};\n           this._super(arguments);\n           //override Wolfs initialization of sound to woof.\n           this._sound = \"woof\";\n\n       },\n\n       speak : function() {\n           //Should return \"A mammal of type mammal sounds like a growl thats domesticated\"\n           return this._super(arguments) + \" thats domesticated\";\n       }\n   },\n\n   static : {\n       soundOff : function() {\n           //should return \"I'm a mammal!! that growls but now barks\"\n           return this._super(arguments) + \" but now barks\";\n       }\n   }\n});\n\nDog.soundOff(); //Im a mammal!! that growls but now barks\n\nvar myDog = new Dog();\nmyDog instanceof Mammal //true\nmyDog instanceof Wolf //true\nmyDog instanceof Dog //true\n\n\n//Notice you still get the extend method.\n\n// Mammal->Wolf->Dog->Breed\nvar Breed = Dog.extend({\n   instance: {\n\n       //initialize outside of constructor\n       _pitch : \"high\",\n\n       constructor: function(options) {\n           options = options || {};\n           this._super(arguments);\n           this.breed = options.breed || \"lab\";\n       },\n\n       speak : function() {\n           //Should return \"A mammal of type mammal sounds like a\n           //growl thats domesticated with a high pitch!\"\n           return this._super(arguments) + \" with a \" + this._pitch + \" pitch!\";\n       },\n\n       getters : {\n           pitch : function() {\n               return this._pitch;\n           }\n       }\n   },\n\n   static : {\n       soundOff : function() {\n           //should return \"I'M A MAMMAL!! THAT GROWLS BUT NOW BARKS!\"\n           return this._super(arguments).toUpperCase() + \"!\";\n       }\n   }\n});\n\n\nBreed.soundOff()//\"IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!\"\n\nvar myBreed = new Breed({color : \"gold\", type : \"lab\"}),\nmyBreed instanceof Dog //true\nmyBreed instanceof Wolf //true\nmyBreed instanceof Mammal //true\nmyBreed.speak() //\"A mammal of type lab sounds like a woof thats domesticated with a high pitch!\"\nmyBreed.get(\"type\") //\"lab\"\nmyBreed.get(\"color\") //\"gold\"\nmyBreed.get(\"sound\")\" //\"woof\"\n```\n\n###Multiple Inheritance / Mixins\n\ndeclare also allows the use of multiple super classes.\nThis is useful if you have generic classes that provide functionality but shouldnt be used on their own.\n\nLets declare a mixin that allows us to watch for property changes.\n\n```javascript\n//Notice that we set up the functions outside of declare because we can reuse them\n\nfunction _set(prop, val) {\n    //get the old value\n    var oldVal = this.get(prop);\n    //call super to actually set the property\n    var ret = this._super(arguments);\n    //call our handlers\n    this.__callHandlers(prop, oldVal, val);\n    return ret;\n}\n\nfunction _callHandlers(prop, oldVal, newVal) {\n   //get our handlers for the property\n    var handlers = this.__watchers[prop], l;\n    //if the handlers exist and their length does not equal 0 then we call loop through them\n    if (handlers && (l = handlers.length) !== 0) {\n        for (var i = 0; i < l; i++) {\n            //call the handler\n            handlers[i].call(null, prop, oldVal, newVal);\n        }\n    }\n}\n\n\n//the watch function\nfunction _watch(prop, handler) {\n    if (\"function\" !== typeof handler) {\n        //if its not a function then its an invalid handler\n        throw new TypeError(\"Invalid handler.\");\n    }\n    if (!this.__watchers[prop]) {\n        //create the watchers if it doesnt exist\n        this.__watchers[prop] = [handler];\n    } else {\n        //otherwise just add it to the handlers array\n        this.__watchers[prop].push(handler);\n    }\n}\n\nfunction _unwatch(prop, handler) {\n    if (\"function\" !== typeof handler) {\n        throw new TypeError(\"Invalid handler.\");\n    }\n    var handlers = this.__watchers[prop], index;\n    if (handlers && (index = handlers.indexOf(handler)) !== -1) {\n       //remove the handler if it is found\n        handlers.splice(index, 1);\n    }\n}\n\ndeclare({\n    instance:{\n        constructor:function () {\n            this._super(arguments);\n            //set up our watchers\n            this.__watchers = {};\n        },\n\n        //override the default set function so we can watch values\n        \"set\":_set,\n        //set up our callhandlers function\n        __callHandlers:_callHandlers,\n        //add the watch function\n        watch:_watch,\n        //add the unwatch function\n        unwatch:_unwatch\n    },\n\n    \"static\":{\n\n        init:function () {\n            this._super(arguments);\n            this.__watchers = {};\n        },\n        //override the default set function so we can watch values\n        \"set\":_set,\n        //set our callHandlers function\n        __callHandlers:_callHandlers,\n        //add the watch\n        watch:_watch,\n        //add the unwatch function\n        unwatch:_unwatch\n    }\n})\n\n```\n\nNow lets use the mixin\n\n```javascript\nvar WatchDog = declare([Dog, WatchMixin]);\n\nvar watchDog = new WatchDog();\n//create our handler\nfunction watch(id, oldVal, newVal) {\n    console.log(\"watchdog's %s was %s, now %s\", id, oldVal, newVal);\n}\n\n//watch for property changes\nwatchDog.watch(\"type\", watch);\nwatchDog.watch(\"color\", watch);\nwatchDog.watch(\"sound\", watch);\n\n//now set the properties each handler will be called\nwatchDog.set(\"type\", \"newDog\");\nwatchDog.set(\"color\", \"newColor\");\nwatchDog.set(\"sound\", \"newSound\");\n\n\n//unwatch the property changes\nwatchDog.unwatch(\"type\", watch);\nwatchDog.unwatch(\"color\", watch);\nwatchDog.unwatch(\"sound\", watch);\n\n//no handlers will be called this time\nwatchDog.set(\"type\", \"newDog\");\nwatchDog.set(\"color\", \"newColor\");\nwatchDog.set(\"sound\", \"newSound\");\n\n\n```\n\n###Accessing static methods and properties witin an instance.\n\nTo access static properties on an instance use the `_static` property which is a reference to your constructor.\n\nFor example if your in your constructor and you want to have configurable default values.\n\n```javascript\nconsturctor : function constructor(opts){\n    this.opts = opts || {};\n    this._type = opts.type || this._static.DEFAULT_TYPE;\n}\n```\n\n\n\n###Creating a new instance of within an instance.\n\nOften times you want to create a new instance of an object within an instance. If your subclassed however you cannot return a new instance of the parent class as it will not be the right sub class. `declare` provides a way around this by setting the `_static` property on each isntance of the class.\n\nLets add a reproduce method `Mammal`\n\n```javascript\nreproduce : function(options){\n    return new this._static(options);\n}\n```\n\nNow in each subclass you can call reproduce and get the proper type.\n\n```javascript\nvar myDog = new Dog();\nvar myDogsChild = myDog.reproduce();\n\nmyDogsChild instanceof Dog; //true\n```\n\n###Using the `as`\n\n`declare` also provides an `as` method which allows you to add your class to an object or if your using node.js you can pass in `module` and the class will be exported as the module.\n\n```javascript\nvar animals = {};\n\nMammal.as(animals, \"Dog\");\nWolf.as(animals, \"Wolf\");\nDog.as(animals, \"Dog\");\nBreed.as(animals, \"Breed\");\n\nvar myDog = new animals.Dog();\n\n```\n\nOr in node\n\n```javascript\nMammal.as(exports, \"Dog\");\nWolf.as(exports, \"Wolf\");\nDog.as(exports, \"Dog\");\nBreed.as(exports, \"Breed\");\n\n```\n\nTo export a class as the `module` in node\n\n```javascript\nMammal.as(module);\n```\n\n\n\n\n\n\n\n\n\n","_attachments":{},"homepage":"https://github.com/doug-martin/declare.js","bugs":{"url":"https://github.com/doug-martin/declare.js/issues"},"license":"MIT"}