Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Beginner's question: How does this function definition work? Date: Tue, 09 Dec 2014 17:59:52 +0100 Organization: PointedEars Software (PES) Lines: 112 Message-ID: <5703570.yfUBlUlCX7@PointedEars.de> References: <6fae7412-601f-4fda-8739-35cc865cc36d@googlegroups.com> <20141111222613.2d818647@cel.eternal-september.org> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1418144394 27302 eJwFwYkBgDAIA8CVRAjPOJg2+4/gHTwtWZHIgKChc2X4Zhx9qXW18MLraA2nGXn4LFm60g8wfRJk (9 Dec 2014 16:59:54 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Tue, 9 Dec 2014 16:59:54 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwNx8ERACEIA8CW5JCI5UiC/Zdwzr42HAauicCM+0Qo5XDSzX2DIySBF6YyfTx9cjNfe2TtXi8DlUV1rx9cwxZj Cancel-Lock: sha1:qRBB/YdrOKqWUN6isECbITEJ+ns= X-NNTP-Posting-Host: eJwFwYEBwCAIA7CX2KC1nIOg/59gAufHXkEwcHFlLEFr9uHQT8oZ1V22hcFfPofRnZB5ej8cGBES Xref: csiph.com comp.lang.javascript:26292 Charles Lehner wrote: > Thing.prototype = { > init: function() { > /* ... */ > } > }; > > Using = assigns the function value to a variable, rather than as a > property of an object. Incorrect. The “=” operator assigns the evaluation result of the expression right-hand side (RHS) to the evaluation result of the expression left-hand side (LHS). If the LHS matches the property accessor syntax, a property with the value is created or an existing property value is overwritten by the RHS (unless prevented/transmuted by a setter, which is triggered by this if there is any). If the LHS is an identifier, Identifier Resolution takes place in order to determine whether an object in the scope chain has such a property or there is a variable with the identifier as its identifier in scope; if there is no such object and variable, and the code is not strict mode code, the global object is augmented with a property with the RHS (otherwise a ReferenceError exception is thrown). If the LHS is a /VariableDeclaration/ a variable is created in the local scope and assigned the value RHS; if a variable with the same identifier has already been declared, the previous value is overwritten. Here, “prototype” is a *property* of the object referred to by “Thing”, as indicated by the dot property accessor notation LHS. It is assigned a reference to an Object instance that has been created with the Object Initialiser RHS. The Object Initialiser contains a definition for an “init” property which is assigned, upon initialization, a reference to a Function instance created by function expression, through which it becomes a method of the aforementioned Object instance. Since the “prototype” property of Function instances is special, all objects that are created by calling the Function instance referred to by “Thing” as a constructor inherit the properties of the referred Object instance through the prototype chain. This is not the recommended way to define a prototype. By doing this, instances created through the constructor have the object referred to by “Object”, not the object referred by “Thing” referred by the value of their “constructor” property. This can only be fixed by creating a “constructor” property on the prototype with the appropriate value; that property is enumerable by default and shows up in for-in iteration. Only in implementations of ECMASCript Edition 5 and later could this be prevented in a safe, standards-compliant way. Therefore, the object referred to by the predefined value of the prototype property should be augmented instead. Functions and methods can be written to reduce the amount of code that one needs to write, however one needs to be aware that code analyzers need additional hints then. Either Thing.prototype.init = function (…) { // … }; … or, for example, Thing.extend(…, { /** @memberOf Thing.prototype */ init: function (…) { … } }); whereas extend() would be a user-defined method like Function.prototype.extend() in Using such a method has the additional advantage that you can easily set up longer prototype chains to emulate class-based inheritance, which allows for better code reuse. > If defining a function with a colon not in an object literal doesn't > produce an error, then it is actually getting parsed as a label, which is > an unrelated, obscure feature of the language having to do with switch > statements. Incorrect. A label-like expression in an Object Initialiser is never parsed as a label. Instead, the Object Initialiser-like expression is actually parsed as a /Block/ statement, and the IdentifierName followed by the colon as according to the /LabelledStatement/ production. This is only possible if the expression RHS of the colon can be produced by the /Statement/ production of the grammar. Labelled statement have nothing to do with “switch” statements in particular. The expression LHS of switch statement’s colons is _not_ a label, but an AssignmentExpression which is matched by loose comparison (Abstract Equality Comparison Algorithm). As for “obscure”, that is a matter of opinion. ISTM that those who did not have the basic knowledge above should keep to themselves their opinion as to what is “obscure” in the discussed programming language. -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.