edit-article
Home
Up
Delete
Article Name:
Article Description:
005-prototypal-inheritance - An overview of prototypal inheritance in JavaScript
Chapter ID/Name:
Status:
Write
Writing
Written
Add Photo:
Owner ID:
Content:
use HTML
Edit Content
<h1 style="text-align: center;">prototypal inheritance</h1> <h2>[WHAT]</h2> <ol> <li><strong>] prototypal inheritance </strong></li> <ol> <li>] Prototypal inheritance is all about objects. Objects inherit properties and methods from other objects. That's all there is to it.</li> <li>] in other OOP languages, there is typically a class keyword that you use to define classes, these classes are like templates that you then use to create objects ( an object is an instance of a class)</li> </ol> <li><strong>] ???</strong></li> <ol> <li>] ? Constructors never come into the picture.? </li> <li>] ??? The "constructor pattern" of prototypal inheritance. Unfortunately JavaScript uses the constructor pattern of prototypal inheritance ???</li> <li><span style="text-decoration: line-through;">? is Crafting your own constructors for producing custom objects,</span></li> <li><span style="text-decoration: line-through;">? also sets up prototypal inheritance for "your object()"instances.,</span></li> </ol></ol> <p> </p> <h2>[WHY]</h2> <ol> <li>] <a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/" target="_blank">advantages of prototypal inheritance VS classical inheritance</a> </li> <ol> <li>] good article that goes in depth as to the whys of prototypal inheritance</li> </ol> <li><strong>] objects are muteable</strong></li> <ol> <li>] you can dynamically add and remove properties and methods from existing objects at runtime</li> </ol> <li><strong>] simple</strong></li> <ol> <li>] no class hierarchies to define and maintain </li> </ol> <li><strong>] powerful</strong></li> <ol> <li>]</li> </ol> <li><strong>] dynamic, better for dynamic languages</strong></li> <ol> <li>]</li> </ol> <li><strong>] smaller code footprint</strong></li> <ol> <li>] less redundant code - using the prototype object of your user created objects, all instances of your object will point to the same function definition, whereas create a new instance of your object will create a copy of each function for each object instance</li> </ol></ol> <h2>[WHY NOT]</h2> <ol> <li>] <a href="/view/article?id=2744" target="_blank">classical inheritance in javascript</a></li> <li>] <a href="/view/article?id=2742" target="_blank">prototypal inheritance VS classical inheritance</a></li> </ol> <h2>[WHERE]</h2> <ol> <li>]</li> </ol> <h2>[WHEN]</h2> <ol> <li>]</li> </ol> <h2>[EXAMPLE]</h2> <ol> <li>] Car inherits from Vehicle -</li> <li>] Student inherits from Person -</li> </ol> <h2>[HOW-TO (simple)]</h2> <ol> <li><strong>] define a constructor function for your 'base' object to inherit from,</strong></li> <ol> <li>] EX function Person(name,birthdate) = {}</li> </ol> <li><strong>] define constructor function for the 'inheriting' object,</strong></li> <ol> <li>] EX - Student(course,grade) {}</li> </ol> <li><strong>] use .call() OR apply method of base object FROM within 'the inheriting object' to set the values of properties for the base object</strong></li> <ol> <li>] Person.call(this, 'joe','1990-01-31') - use the call method for single args, comma seperated</li> <li>] Person.apply(this, arguements) - apply method for multipe args(array)</li> </ol> <li><strong>] use Object.create() to create a new instance of the base object within the inheriting object</strong></li> <ol> <li>] EX Student.prototype = Object.create(Person);</li> </ol> <li><strong>] SET the constructor property of the inheriting object to refer to itself ...</strong></li> <ol> <li>] Student.prototype.constructor = Student;</li> </ol> <li><strong>] CREATE an instance of the new inheriting object</strong></li> <ol> <li>] var myStudent = new Student('computer science','a+');</li> </ol></ol> <h2>[HOW-TO (crockford)]</h2> <ol> <li><strong>x] there are 2 'commonly used' patterns of using prototypal inheritance</strong></li> <ol> <li>] constructor pattern - wrong - commonly used b/c it is based upon familiar concepts from the java programming lanuage,</li> <li>] prototypal pattern - correct </li> <li>] SRC = REF 1</li> </ol> <li><strong>] Create a brand new object.</strong></li> <ol> <li><strong>] </strong>There are two ways of creating objects using prototypal inheritance:</li> </ol> <li><strong>] Clone an existing object and extend it.</strong>JavaScript offers two ways to clone an object -</li> <ol> <li>] <a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/#delegation_or_differential_inheritance">delegation</a> aka CLONE</li> <li>] <a href="http://aaditmshah.github.io/why-prototypal-inheritance-matters/#cloning_or_concatenative_inheritance">concatenation</a> aka COPY</li> <li>] Henceforth I'll use the word "clone" to exclusively refer to inheritance via delegation, and the word "copy" to exclusively refer to inheritance via concatenation.</li> </ol></ol> <h2>[REFERENCE]</h2> <ol> <li>] <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain</a></li> <ol> <li>] the contructor pattern, ] Object.create (es5) and ] classes ( es6)</li> </ol> <li>] <a href="http://javascript.crockford.com/prototypal.html">http://javascript.crockford.com/prototypal.html</a></li> <ol> <li>] examples of prototypal inheritance v1</li> <li>] examples of prototypal inheritance v2</li> <li>] examples of prototypal inheritance v3</li> </ol> <li>] <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript</a> </li> <ol> <li>] includes example of prototypal inheritance with Person and Student objects, Student inheriting from Person</li> </ol> <li>] <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model</a> - JavaScript MDN</li> <ol> <li>] Class based VS prototype based languages</li> </ol> <li>] 2010 q <a href="http://stackoverflow.com/questions/2800964/benefits-of-prototypal-inheritance-over-classical">http://stackoverflow.com/questions/2800964/benefits-of-prototypal-inheritance-over-classical</a></li> <ol> <li>] a 2013 -</li> </ol> <li>] <a href="http://stackoverflow.com/questions/2064731/good-example-of-javascripts-prototype-based-inheritance" target="_blank">http://stackoverflow.com/questions/2064731/good-example-of-javascripts-prototype-based-inheritance</a></li> <ol> <li>]</li> </ol> <li>] <a href="http://javascript.info/tutorial/inheritance" target="_blank">http://javascript.info/tutorial/inheritance</a> </li> <ol> <li>] animal / rabbit example, __proto___,</li> <li>] <span style="font-family: Courier New;">rabbit.__proto__ = animal </span><code class="jscript comments">// inherit ||</code></li> <li><code class="jscript comments">] rabbit = Object.create(animal) ||</code></li> <li><code class="jscript comments">] Rabbit.prototype = animal </code></li> <li><code class="jscript comments"><code class="jscript comments">] var rabbit = new Rabbit('John') </code></code></li> </ol> <li><code><code>] <a href="http://www.2ality.com/2012/01/js-inheritance-by-example.html" target="_blank">http://www.2ality.com/2012/01/js-inheritance-by-example.html</a></code></code></li> <ol> <li><code><code>] Dr Axel Rauschmeyer - </code></code></li> </ol> <li><code><code>] <a href="https://en.wikipedia.org/wiki/Prototype-based_programming">https://en.wikipedia.org/wiki/Prototype-based_programming</a> </code></code></li> <ol> <li><code><code>] </code></code></li> </ol></ol><hr /> <p><strong>true prototypal inheritiance ( crockford v1 2006-06-07)</strong></p> <ol> <li>] function object(o) {<br /> function F() {}<br /> F.prototype = o;<br /> return new F();<br /> }</li> </ol> <p>The <code>object</code> function untangles JavaScript's constructor pattern, achieving true prototypal inheritance. It takes an old object as a parameter and returns an empty new object that inherits from the old one. If we attempt to obtain a member from the new object, and it lacks that key, then the old object will supply the member. Objects inherit from objects. What could be more object oriented than that?</p> <p>The problem with the <code>object</code> function is that it is global, and globals are clearly problematic.</p> <hr /> <p><strong>true prototypal inheritiance ( crockford v2 2007-04-02)</strong></p> <p>Object.prototype.begetObject = function () {<br /> function F() {}<br /> F.prototype = this;<br /> return new F();<br />};<br /><br />newObject = oldObject.begetObject();</p> <p>The problem with <code>Object.prototype.begetObject</code> is that it trips up incompetent programs, and it can produce unexpected results when <code>begetObject</code> is overridden.</p> <hr /> <p><span style="background-color: #00ff00;"><strong>true prototypal inheritiance ( crockford v2 2008-04-7)</strong></span></p> <p><span style="background-color: #00ff00;">if (typeof Object.create !== 'function') {</span><br /><span style="background-color: #00ff00;"> Object.create = function (o) {</span><br /><span style="background-color: #00ff00;"> function F() {}</span><br /><span style="background-color: #00ff00;"> F.prototype = o;</span><br /><span style="background-color: #00ff00;"> return new F();</span><br /><span style="background-color: #00ff00;"> };</span><br /><span style="background-color: #00ff00;">}</span></p> <hr /> <p> </p> <p>NOTES from article # 1682 - adding methods and properties to existing objects</p> <h3>[2012-09-01]</h3> <ol> <li>] (id=703) UPDATED - object.prototype - using prototype (property) to add new properties & methods to (existing) objects</li> <ol> <li>] example 3 - adding NEW properties(only) to existing objects,</li> </ol></ol> <h3>[2012-09-02]</h3> <ol> <li><strong>*] namespace - </strong></li> <ol> <li>IF you create a constructor function and then define all of the methods for all of your objects in the "global" namespace, you will end up with 'ns pollution' and 'naming conflicts' - to avoid that ...</li> </ol> <li><strong>*] why= use prototype and NOT just declare/define your methods in the - ] constructor function , ] json or ] literal</strong></li> <ol> <li>B/C - IF you define your method (or property) in the constructor/json/literal declaration, EVERY single instance of your object will be created with a copy of your method code,</li> <li>IF you define your method (or property) using prototype, one copy of your method code will be created and every single instance of your object will REFER to that 1 copy</li> <li>REF #] 004 - see comments section for notes on both of these</li> </ol></ol> <p> newObject = Object.create(oldObject);</p> <ol> <li> <strong>] jsISsexy - art - oop in js</strong></li> <li>] eric says dont use constructor pattern - <a href="http://ericleads.com/2013/02/fluent-javascript-three-different-kinds-of-prototypal-oo/" target="_blank">http://ericleads.com/2013/02/fluent-javascript-three-different-kinds-of-prototypal-oo/</a></li> <li>] <a href="http://ejohn.org/blog/simple-javascript-inheritance/" target="_blank">http://ejohn.org/blog/simple-javascript-inheritance/</a></li> <li>] crockford proto pattern ] <a href="http://javascript.crockford.com/prototypal.html" target="_blank">http://javascript.crockford.com/prototypal.html</a> see example below</li> <li> </li> </ol><hr /> <p><strong>CROCKFORD method</strong></p> <p>if (typeof Object.create !== 'function') {<br /> Object.create = function (o) {<br /> function F() {}<br /> F.prototype = o;<br /> return new F();<br /> };<br />}<br />newObject = Object.create(oldObject);</p> <hr /> <div class="crayon-pre" style="line-height: 15px !important; font-size: 12px !important;"> <div id="crayon-5322c78574a06113052588-1"><strong>ERIC method</strong></div> <div>var proto={</div> <div id="crayon-5322c78574a06113052588-2"> hello:functionhello(){</div> <div id="crayon-5322c78574a06113052588-3"> return'Hello, my name is '+this.name;</div> <div id="crayon-5322c78574a06113052588-4"> }</div> <div id="crayon-5322c78574a06113052588-5">};</div> <div id="crayon-5322c78574a06113052588-6" class="crayon-line crayon-striped-line"> </div> <div id="crayon-5322c78574a06113052588-7" class="crayon-line"><span class="crayon-t">var </span><span class="crayon-v">george</span><span class="crayon-o">=</span><span class="crayon-t">Object</span><span class="crayon-sy">.</span><span class="crayon-e">create</span><span class="crayon-sy">(</span><span class="crayon-i">proto</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div> <div id="crayon-5322c78574a06113052588-8" class="crayon-line crayon-striped-line"><span class="crayon-v">george</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-o">=</span><span class="crayon-s">'George'</span><span class="crayon-sy">;</span></div> </div> <p> </p> <hr /> <p> <br /> <a href="http://stackoverflow.com/questions/14781373/can-anyone-come-up-with-a-good-prototype-example-in-js-that-helps-me-understand?lq=1" target="_blank">http://stackoverflow.com/questions/14781373/can-anyone-come-up-with-a-good-prototype-example-in-js-that-helps-me-understand?lq=1</a><br />- person.prototype.haircolor = brown; // add a new property to all previously instantiate instances of<br /><a href="http://stackoverflow.com/questions/8659390/context-to-use-call-and-apply-in-javascript" target="_blank">http://stackoverflow.com/questions/8659390/context-to-use-call-and-apply-in-javascript</a><br /><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply</a><br /><a href="https://gist.github.com/wendyleung/4cbd95baa9b147abc087" target="_blank">https://gist.github.com/wendyleung/4cbd95baa9b147abc087</a> ( call vs apply) <br /><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create" target="_blank">https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create</a></p> <p><a href="http://pixdeo.com/articles/Inventory%20Items%20and%20prototypal%20inheritance/" target="_blank">http://pixdeo.com/articles/Inventory%20Items%20and%20prototypal%20inheritance/</a> - SRC=hn, USER=, COMMENTS(#),</p> <p> </p> <p> </p> <p> </p>