Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.albasani.net!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Why use prototype in this example Date: Wed, 07 Jan 2015 04:25:14 +0100 Organization: PointedEars Software (PES) Lines: 121 Message-ID: <5077005.ZnA5KHH3MS@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1420601139 18380 eJwNycEBwCAIA8CViJBQxlEq+4/Q3vfogjpDVHA48dhZFMCcHvOJW+h40/5xzsJR7dy1pLzIDwOmEBc= (7 Jan 2015 03:25:39 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Wed, 7 Jan 2015 03:25:39 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwFwQkBACAIA8BKKownjkPoH8E7iG0rV4MpBlOYJUned0RSV7uUh58e0pQrWIps5GD3lsu5fM+S6KzQ8wFimxYs Cancel-Lock: sha1:zkFANanI0mySTbxq3/WEbMHr62o= X-NNTP-Posting-Host: eJwFwYEBwCAIA7CXhrRFzgGV/09YQpfpBESBw8EsWMEPr6a2vbZK4uX7hMWsVujuicihN38Z3hDm Xref: csiph.com comp.lang.javascript:26477 Tony Johansson wrote: > Here I have two examples. The difference between these is that in example > 1 I create sayHello as a prototype while in > exemple 2 I add sayHello as a function in the class Person There is no class because there are no classes. [1] At most, there is a user-defined object type then. > I mean in both example 1 and 2 I create an instance of Person. > I can't see any point to use a prototype compared to add methods to the > class? You are _not_ adding methods to a class because there is no class. The standard’s(!) terminology “instance of F” (or for short, “F instance”) with prototype-based inheritance should not be misunderstood so that F would be a class (as in class-based inheritance). It is still only a symbol for a reference to an object (usually, a Function instance [2]). (The internal [[Class]] property is a separate issue.) When a function F is called as a constructor, “this” in that function execution context refers to the newly constructed object, an “F instance”. [3] Therefore, when you augment the object referred to by ”this” in an object’s constructor, you are augmenting that object, and only it. (Because it is possible that way that objects constructed with the same constructor call are fundamentally different from one another, and need not share even the same prototype chain, it makes no sense to talk of a "class" instead of a constructor here – the fact aside that there is the *additional* concept of a class in certain implementations.) This is also why in many cases it is a good idea to define prototype methods, prototype properties in general, while in others it is better to define methods in the constructor, separate for each instance: prototype properties are shared among all instances through the prototype chain; on the other hand, instance methods defined and assigned in the constructor can close over, therefore provide access to, symbols of the constructor’s function execution context that can serve as "private" properties, and the respective access methods as "privileged" ones. (This is most useful with setters and getters, see jsx.array.BigArray in JSX:array.js for an example. [4]) ________ [1] (JFTR: I do not agree with the statements about extension of native prototypes. The logic used there is flawed because if you extend native prototypes, or allow or expect others to do that when using your code together with theirs, you have to take the same precautions with compatibility features as with new ones. Also, because in newer implementations you can make user-defined properties non-enumerable, and there is a built-in method for creating objects with empty prototype chain, such extensions are not so much of an issue anymore. As always, use with care.) [2] [3] [4] > Start example 1 med prototype > *********************** > var Person = function (firstName) { > this.firstName = firstName; > }; It is not necessary to use a function expression to define a constructor; you can use a function declaration: function Person (firstName) { this.firstName = firstName; } ISTM a function expression is only useful if the constructor *definition* needs to use a previously assigned value. > Person.prototype.sayHello = function() { > console.log("Hello, I'm " + this.firstName); > }; > > var person1 = new Person("Alice"); > var person2 = new Person("Bob"); > > // call the Person sayHello method. ^ prototype > person1.sayHello(); // logs "Hello, I'm Alice" > person2.sayHello(); // logs "Hello, I'm Bob" person1 != person2 person1.sayHello == person2.sayHello > […] > var Person = function (firstName) { > this.firstName = firstName; > > this.sayHello = function () { > alert("Hello, I'm " + this.firstName); ^^^^^ window.alert > }; > }; > > var person1 = new Person("Alice"); > var person2 = new Person("Bob"); > > // call the Person sayHello method. ^ instances’ ^ s > person1.sayHello(); // logs "Hello, I'm Alice" > person2.sayHello(); // logs "Hello, I'm Bob" person1 != person2 person1.sayHello != person2.sayHello HTH -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.