Path: csiph.com!feeder.erje.net!1.eu.feeder.erje.net!news.albasani.net!news.mb-net.net!open-news-network.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: x === x Date: Tue, 30 May 2017 16:21:13 +0200 Organization: PointedEars Software (PES) Lines: 144 Message-ID: <2563985.e9J7NaK4W3@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn NNTP-Posting-Host: 47.229.197.178.dynamic.wless.zhbmb00p-cgnat.res.cust.swisscom.ch Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: gwaiyur.mb-net.net 1496154074 15189 178.197.229.47 (30 May 2017 14:21:14 GMT) X-Complaints-To: abuse@open-news-network.org NNTP-Posting-Date: Tue, 30 May 2017 14:21:14 +0000 (UTC) User-Agent: KNode/4.14.2 X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. In mathematics, usually, when »...« is a certain term, we have > > ... === ... > > for the same term left and right. > > In JavaScript, this does not always hold for expressions, albeit > possibly sometimes for different reasons: Just “possibly” – are you serious? You profess to teach, but apparently still do not understand the basics of, these programming *languages*; nor, it appears, programming in general. > Math.random() === Math.random() This should be obvious even to you: The return values of consecutive calls of Math.random() may be, but are not supposed to be, equal. After all, the method is supposed to generate *random* numbers. > NaN === NaN This evaluating to “false” is due to the implementation of the ECMAScript Number type as a type of IEEE 754 “double-precision” floating-point values. > [] === [] Left-hand side and right-hand side refer to different, consecutively constructed, Array instances, and the operator compares the reference values, not the syntax or object content. [To do the latter, Array.prototype.every() may be used: [1, 2, 3].every(function (e, i) { return this[i] === e }, [1, 2, 3]) Note that arrow functions must not be used then, as “this” would not be defined by the second argument then: [1, 2, 3].every((e, i) => ( /* Does not work: “this” is “undefined” in strict mode or refers to the global object */ this[i] === e ), [1, 2, 3]) That is IMHO an oversight in the Specification that precludes the use of arrow functions where they would be most useful for short syntax.] > ( {} === {} ) Left-hand side and right-hand side refer to different, consecutively constructed, Object instances, and the operator compares the reference values, not the syntax or object content. [To do the latter, a custom equals() method may be defined, like in Java. Care must be taken to avoid augmenting the Object prototype; otherwise, for-in and for-of loops must be filtered, and the “in” operator either cannot be used in a simple manner, or can only be applied to objects that do not have the Object prototype in their prototype chain, such as those created with Object.create(null, …). The introduction of an Object.equals() method that compares object content, by calling the first referred object’s equals() method unless the object is the same as referred by “Object” and if such a method is defined, using simple comparison otherwise, is indicated: Object.equals = function (obj1, obj2, options) { if (obj1 != Object && typeof obj1.equals == "function") { return obj1.equals(obj2); } return ( options && options.enumerableOnly ? Object.keys(obj1) : Object.getOwnPropertyNames(obj1) ).every( options && options.strict ? function (key) { return (obj1[key] === obj2[key]); } : function (key) { return (obj1[key] == obj2[key]); } ); }; ] > ( ()=>0 )===( ()=>0 ) Left-hand side and right-hand side refer to different Function instances, and the operator compares the reference values, not the syntax or object content. [There is no reliable *and* *normatively* backwards-compatible way to do the latter, however the string representations of both functions may be compared in newer implementations. See ECMAScript 2016, § 19.2.3.5 Function.prototype.toString(), “toString Representation Requirements”.] > In the first case, we cannot be sure that it will evaluate to > »false«, but this is is possibly. ^^^^^^^^^^^^^^^^^^^ Parse error. > The last three cases are similar, but it is also remarkable > how one needs to add parentheses: no parens required for the > array, outer parens for the objects, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ No parentheses are required there; the “===” operator marks “{}” as an expression as opposed to an empty Block statement. {} === {} is equivalent. Besides, arrays *are* objects in ECMAScript implementations. The proper terms to use there to make the distinction are “Object initializer” to refer to the syntax element, and “Object instance reference” to refer to the evaluation value. > and two pairs of parens for the functions. The parentheses there are required to satisfy the grammar and to avoid ambiguity: The parentheses around the second arrow function are required to avoid defining an arrow function that attempts to compares 0 with a syntactically invalid expression, “()”, equivalent to () => ((0 === ()) => 0) -----------------^ [“=>” is not an operator; the greater-than-or-equal operator is “>=”. Therefore, “0 === ()” is the longest possible match.] The parentheses around the first arrow function are required to avoid the ambiguity of defining an arrow function that compares 0 and a Function instance reference created by the second arrow function, equivalent to () => (0 === (() => 0)) -- PointedEars FAQ: | | Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.