{"id":23908531,"url":"https://github.com/mandober/js-object-relationships","last_synced_at":"2026-06-12T22:33:01.702Z","repository":{"id":156251943,"uuid":"86079991","full_name":"mandober/js-object-relationships","owner":"mandober","description":"Relationships between Objects in JS","archived":false,"fork":false,"pushed_at":"2017-05-03T00:56:57.000Z","size":855,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-23T15:37:01.613Z","etag":null,"topics":["javascript","prototype-chain"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mandober.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-24T15:00:32.000Z","updated_at":"2020-05-27T02:53:12.000Z","dependencies_parsed_at":"2023-05-04T04:38:49.457Z","dependency_job_id":null,"html_url":"https://github.com/mandober/js-object-relationships","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mandober/js-object-relationships","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandober%2Fjs-object-relationships","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandober%2Fjs-object-relationships/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandober%2Fjs-object-relationships/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandober%2Fjs-object-relationships/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mandober","download_url":"https://codeload.github.com/mandober/js-object-relationships/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandober%2Fjs-object-relationships/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34265491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["javascript","prototype-chain"],"created_at":"2025-01-05T04:38:42.558Z","updated_at":"2026-06-12T22:33:01.695Z","avatar_url":"https://github.com/mandober.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Relationships between Objects in JS\n\nExploring relationships between built-in objects in JavaScript.\n\n## Data Types\n\nThere are 7 built-in data types in JavaScript:\n* 6 primitive types: `string, number, boolean, symbol, null, undefined`\n* 1 compound type: `object`, with subtypes such as object, array, function, etc.\n\n*Typically for JavaScript there's a naming confusion right from the start, preventing a clean grouping of builtin objects: there's a compound type named object, which is comprised of many subtypes. These subtypes are collectively called builtin objects (built-ins) or native objects (natives) or just, well, objects. Problem is, one of these native object is also called object.*\n\nSo, all built-ins are, in fact, objects. Each one is a specialized subtypes of generic object type. Commonly used built-ins are `Object, Array, Date, RegExp, Math, Function`. Function is a callable object; String, Symbol, Number and Boolean objects are rarely used directly, but they are fundamental when dealing with their primitive counterparts (\"boxing primitives\").\n\nJS host environment provides many other natives, such as global object (`window` in browser), but they are not part of EcmaScript core, rather, they are a part of a separate specification (Browser Object Model, Document Object Model, etc.).\n\n\u003e Lists of all built-in objects on MDN: [Standard built-in objects][link1]\n\n\n## Built-in objects\n\nObjects in JS are collection of properties. Property is a key/value pair: key is a property name and value can be any of any type: a primitive (string, number, etc) or a compound (object, function, array, etc).\n\nBuilt-in objects have corresponding constructor functions: `Object`, `Function`, `Array`, `Regexp`, etc. \n\nAll of these constructor functions have a prototype: `Object.prototype`, `Function.prototype`, `Array.prototype`, `Regexp.prototype`, etc.\n\n\n### Constructors and prototypes\n\nConstructor functions, being objects, have properties. One of them is a special property named `prototype` that references an object - function's prototype object. In turn, the prototype object itself has a special property named `constructor` that references back the constructor function.\n\nThe prototype object has many properties (methods) specific to its type; for example, `Array` function's prototype object is itself an array, and it holds properties (methods) that are useful when dealing with arrays (`push, pop, indexOf`, etc). \n\nOne way to looks at this, is that all natives are defined by a pair: a constructor function and function's corresponding prototype.\n\nWhen referring to a particular method, for example a method found on the Array function itself, convention is to write `Array.from`, but when method is on `Array.prototype` object, it is shorthanded as `Array#pop`.\n\n\n### Prototype Chain\n\nAll objects have access to their own properties, but moreover, they can also access properties found on other objects. This mechanism is implemented through a special internal (accessible only to JS engine) property called `[[Prototype]]` (internal properties are usually denoted in double brackets). ES6 has standardized a public, externally accessible, version of this property, `__proto__`. \n\n\n![Prototype Chain][pic1]    \n*Diagram 1: JS engine’s “looking busy” screensaver*\n\nDiagram shows some common constructor functions and their prototypes. Thick red lines represent `[[Prototype]]` links i.e. `__proto__` references . These links make up the prototype chain.\n\n*(Proto)typical JS naming convention: there's a `prototype` property that references prototype objects and internal [[Prototype]] property along with  public `__proto__` property that comprises the prototype chain. Warning: these two refer to very different objects.*\n\nIn a way, prototype chain can be viewed as collection of all the [[Prototype]] links, or, more specifically, as a prototype chain of a given object. For example, prototype chain of `Function` function, starts with the function itself, continues to `Function.prototype` and then ends at `Object.prototype`.\n\n`Object.prototype` is the final link in the prototype chain , it terminates the prototype chain by Prototype-linking to `null`.\n\n\u003e All roads lead to `Object.prototype`    \n\nPrototype chain is traversed every time an object (array, function, object, etc) is queried for a property; if an object doesn't have such property, the search will continue, by following the Prototype links, to the next object. Finally, if `Object.prototype`, which is always at the end of any object's prototype chain, doesn't have such property, the search is over (and `undefined` is returned).\n\nThis is why all object have access to properties (methods) found on `Object.prototype` like `toString()`, `valueOf()`, `hasOwnProperty()`, `propertyIsEnumerable()`, etc.\n\nAll said is true for initial JS environment, before any  user code is executed - let a user interfere and the lot quickly goes tits up because these relationships (properties) are not immutable.\n\n\n### Identifying objects\n\nConstructor function, like all functions have a proper name (a name as a string) so they are easily recognized in the output of various JS host environments.\n\n![Identifying objects][pic2]    \n*Function, Object, prototypes, properties*\n\nThe problem is recognizing their prototype objects as they don't have a name - they are only referred to in relation to their constructor function, e.g. `Object.prototype` object. JS host environments will have different representations for them.\n\nConveniently, browsers' output is clickable, which displays all object's properties - knowing what (prototype) object contains which properties is a way to distinguish them.\n\n\n## Creating new objects\n\n### Objects and Functions\n\n`Object` and `Function` natives are the most fundamental builtins; their prototype objects are at the top of the prototype chain; former sits on the top of a prototype chain, while latter is in the prototype chain of all functions, including constructor functions and user created ones.\n\n![Object and Function][pic3]   \n*Initial state*\n\n`Object` constructor function can create various subtypes of the general object type; it can construct new \"proper\" object, but it is mostly creates wrapper objects for different types (for example, if its argument is a string parameter, it will wrap the string, creating a `String` object).\n\n![Creating new objects][pic4]    \n*Creating new objects using object literal*\n\nDiagram shows creation of new object (yellow entity) and the resulting prototype chain: whether a new object is created with a constructor call, or by using its literal form, the new object will be [[Prototype]] linked to `Object.prototype`.\n\n```js\n// make an object using literal notation:\nvar obj1 = {a:1, b:2};\n// which amount to the same as:\nvar obj1 = new Object(); \nobj1.a = 1;\nobj1.b = 2;\n\n// quasi OO style:\nfunction Person(f, l) {\n  this.f = f;\n  this.l = l;\n}\nvar jack = new Person(\"jack\", \"bauer\");\n```\nFrequently used pattern for creating new object(s) is to define a function and constructor call it. In the code block above, first a new function is defined, then it is constructor called (with the `new` keyword), resulting in a new object (called 'jack').\n\nIn this scenario, resulting object will have a different [[Prototype]] linkage than an object created using literal notation. Resulting prototype chain is shown below:\n\n![pic5]    \n*Creating a new object via constructor call*\n\nInstantiated object ('jack') will be [[Prototype]] linked to the prototype object of the constructor function ('Person.prototype').\n\n\n\n\n\n---\n[link1]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects\n[pic1]: diagrams/01_prototype-chain.png\n[pic2]: diagrams/02_methods.png\n[pic3]: diagrams/03_object-and-function.png\n[pic4]: diagrams/04_object-literal.png\n[pic5]: diagrams/05_object-construction-call.png\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandober%2Fjs-object-relationships","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmandober%2Fjs-object-relationships","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandober%2Fjs-object-relationships/lists"}