{"id":17983469,"url":"https://github.com/techjacker/extasy","last_synced_at":"2025-04-04T02:12:54.709Z","repository":{"id":9059706,"uuid":"10827854","full_name":"techjacker/extasy","owner":"techjacker","description":"Blissfully easy JavaScript inheritance","archived":false,"fork":false,"pushed_at":"2017-12-30T16:00:59.000Z","size":99,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T13:44:39.668Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/techjacker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-20T19:33:59.000Z","updated_at":"2017-12-30T16:00:59.000Z","dependencies_parsed_at":"2022-08-28T08:10:28.144Z","dependency_job_id":null,"html_url":"https://github.com/techjacker/extasy","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techjacker%2Fextasy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techjacker%2Fextasy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techjacker%2Fextasy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techjacker%2Fextasy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/techjacker","download_url":"https://codeload.github.com/techjacker/extasy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247107828,"owners_count":20884797,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T18:17:20.376Z","updated_at":"2025-04-04T02:12:54.693Z","avatar_url":"https://github.com/techjacker.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# extasy\n\n[![Build Status](https://secure.travis-ci.org/techjacker/extasy.png)](http://travis-ci.org/techjacker/extasy)\n\n- Extend function inspired by YUI, coffeescript, typescript and google closure inheritance patterns.\n- 2.5k minified (950 bytes gzipped)\n\n\n### Install\n\n#### Node\n\n```Shell\nnpm install extasy\n```\n\n#### Browser\n\n```Shell\ncomponent install extasy\n```\n\n```Shell\nbower install extasy\n```\n\n```HTML\n\u003cscript src=\"extasy-browser.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n\tfunction Child() {};\n\tfunction Parent() {};\n\textasy(Child, Parent);\n\u003c/script\u003e\n```\n\n### Docs\n[Yuidocs documentation here](docs/index.html)\n- link only works when checkout repo and preview README locally\n\n### Full Example\n\n```JavaScript\nvar extasy = require('./lib/main.js');\n\nfunction Parent() {};\nParent.prototype.foo = function(x, y) {\n\treturn x + y;\n};\n\nfunction Child() {};\n// must extend before overwriting prototype methods!\nextasy(Child, Parent);\nChild.prototype.foo = function(x, y) {\n\treturn 2 + this.super_.foo(x, y);\n};\n\n/*--------------------------------------\nno tests throw an error\n---------------------------------------*/\nvar ChildInst = new Child();\n\nvar assert = require('assert');\nassert(ChildInst.constructor === Child);\nassert(ChildInst.super_ === Parent.prototype);\nassert(Object.getPrototypeOf(ChildInst) === Child.prototype);\nassert(Object.getPrototypeOf(Object.getPrototypeOf(ChildInst)) === Parent.prototype);\nassert(ChildInst instanceof Child);\nassert(ChildInst instanceof Parent);\n\nconsole.log('ok');\n```\n\n\n## API\n\n#### extasy(childConstructor, ParentClass, StaticProps)\n\n\tfunction Child() {};\n\tfunction Parent() {};\n\textasy(Child, Parent, {\n\t\tiam: 'optional static props'\n\t}));\n\n##### @param {Constructor} Child Constructor Class\nFunction for child class that you want to create\n\n##### @param {Class|Array} ParentClass\n\nA single class or an array of classes that you want the child to inherit from. The paren(t's/ts') methods will be put on the child's prototype. If the parent is a dynamic class (ie uses a constructor function) then the parent's prototype methods will be put on the child's prototype. If the parent is a static class (ie an object literal) then it's static methods will be put on the child's prototype. If an array of classes is passed in then these will be flattened (ie a single parent class combining all the methods to be inherited will be created) before applying to the child's prototype.\n\n##### @param  {[Object]} StaticProps\nOptional instance methods to give the class when instantiated (won't be put on proto). By default the paren(t's/ts') instance methods are applied to the child as instance methods\n\n##### @return {Class}\nThe child class is returned\n\n\n\n## Features\n### Accepts Constructor or Static Class Parents\nParent can be either a constructor or static class (ie constructor functions or object literals).\n\n#### Constructor Parents\nParent's prototype methods are placed on child's prototype (static methods if parent is object literal).\n\n```JavaScript\nfunction Child() {};\nfunction Parent() {};\nextasy(Child, Parent);\nvar ChildInst = new Child();\nassert(ChildInst.super_ === Parent.prototype);\nassert(ChildInst.hello === 'world');\n```\n\n\n#### Static Parents\n\n```JavaScript\nfunction Child() {};\nvar Parent = {};\nextasy(Child, Parent);\nassert(Child.super_ === Parent);\nvar ChildInst = new Child();\nassert(ChildInst.constructor.super_ === Parent);\n```\n\n#### Multiple Parents\n\n```JavaScript\nfunction Child() {};\nfunction Parent() {};\nParent.prototype.kinky = function () { return 'yes, ' + this.menage; };\nfunction Parent2() {};\nvar Parent3 = {menage: 'a trois'};\n\n// inherit\nextasy(Child, [Parent, Parent2, Parent3]);\nvar ChildInst = new Child();\n\nassert(Child.prototype.kinky === Parent.prototype.kinky);\nassert(ChildInst.constructor.prototype.kinky === Parent.prototype.kinky);\nassert(Child.kinky() === 'yes, a trois');\nassert(ChildInst.kinky() === 'yes, a trois');\n```\n\n\n### Copies Constuctor* Parent's Instance Methods \u0026 Properties\nParent's instance methods are set as child instance methods if parent is a constructor class.\nDoes not do this for static classes because their 'instance' methods are put on the prototype\n\n```JavaScript\nfunction Child() {};\nfunction Parent() {};\nParent.prototype.random = 'randomness';\nParent.random = 'random';\nParent.bar = 'bar';\nextasy(Child, Parent);\n// differences child class vs instance\nvar ChildInst = new Child();\nassert(Child.bar === Parent.bar);\nassert(Child.super_ === undefined);\nassert(ChildInst.super_ !== undefined);\nassert(Child.random === Parent.random);\nassert(Child.random === 'random');\nassert(ChildInst.constructor.random === 'random');\nassert(ChildInst.super_.random === 'randomness');\n```\n\n### Overloading\n####  Overloading Constructor Class Parent\n\n```JavaScript\nfunction Child() {};\nfunction Parent() {};\nParent.prototype.foo = function () { return 'father'; };\nextasy(Child, Parent);\n\n// extend the protoype after extending or else will fail...\nChild.prototype.foo = function () {\n\treturn 'you are my ' + this.super_.foo();\n}\n\n// initialise\nvar ChildInst = new Child();\nassert(ChildInst.foo() === 'you are my father');\n\n// overload\nChildInst.foo = function () {\n\treturn 'you WERE my ' + this.super_.foo();\n}\nassert(ChildInst.foo() === 'you WERE my father');\n```\n\n\n#### Overloading Static Class Parent\n\n```JavaScript\nfunction Child() {};\nvar Parent = {foo: function () { return 'father'; }};\nextasy(Child, Parent);\n\n// can't overload thru prototype - need to do thru instance\nassert(Child.super_.foo === Parent.foo);\nassert(Child.prototype.foo === Parent.foo);\nChild.foo = function () {\n\treturn 'you are my ' + this.super_.foo();\n}\n\n// overloading instance\nvar ChildInst = new Child();\nassert(Child.foo() === 'you are my father');\nassert(ChildInst.constructor.foo() === 'you are my father');\n```\n\n\n#### Overloading Multiple Parents\n\n```JavaScript\nfunction Child() {};\nfunction Parent() {};\nParent.prototype.kinky = function () { return 'yes, ' + this.menage; };\nfunction Parent2() {};\nvar Parent3 = {menage: 'a trois'};\n\n// inherit\nextasy(Child, [Parent, Parent2, Parent3]);\nvar ChildInst = new Child();\n\n// can't overload thru prototype - need to do thru instance\nassert(Child.super_.kinky === Parent.prototype.kinky);\nassert(Child.prototype.kinky === Parent.prototype.kinky);\n\n// class overloading\nChild.kinky = function () {\n\treturn 'Q: Is my parent kinky? A: ' + this.super_.kinky();\n};\nassert(Child.kinky() === 'Q: Is my parent kinky? A: yes, a trois');\nassert(ChildInst.kinky() !== 'Q: Is my parent kinky? A: yes, a trois');\n\n// instance overloading\nvar ChildInstOverload = new Child();\nassert(ChildInstOverload.kinky() === 'yes, a trois');\nChildInstOverload.kinky = function () {\n\treturn 'Q: Is my class\\'s parent kinky? A: ' + this.constructor.super_.kinky();\n};\nassert(ChildInstOverload.kinky() === 'Q: Is my class\\'s parent kinky? A: yes, a trois');\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechjacker%2Fextasy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechjacker%2Fextasy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechjacker%2Fextasy/lists"}