Proposal: [Symbol.equals]
It's pretty important that the meaning ===
not be able to change.
It's pretty important that the meaning `===` not be able to change. On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator <viliuskubilius416 at gmail.com> wrote: > What about having Symbol.equals? > > For example, for now this is what it does: > > ```js > > class Position { > constructor(o) { > this.x = o.x instanceof Number ? o.x : 0 > > this.y = o.y instanceof Number ? o.y : 0 > > this.z = o.z instanceof Number ? o.z : 0 > } > } > console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, > y: 10, z: 10}) > > ``` > Output is of course, false. > With `Symbol.equals`, we could make it easier, instead of > `instance.equals(otherInstance)`. > > > > For example: > > ```js > > class Position { > > [Symbol.equals](oIn) { > return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z > } > constructor(o) { > this.x = o.x instanceof Number ? o.x : 0 > > this.y = o.y instanceof Number ? o.y : 0 > > this.z = o.z instanceof Number ? o.z : 0 > } > } > console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, > y: 10, z: 10}) > > ``` > Now output would be true. > > This would save most of the time, instead of writing .equals and then > surrounding everything with (). > > > <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. > www.avast.com > <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> > <#m_4203195586323233386_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190118/fd27a89a/attachment.html>
Yeah, I agree. I'd suggest overloading ==
, but that'd risk serious web
compat issues, especially if null
/undefined
aren't special-cased. I
feel an equals
instance method added to all builtins and an
Object.equals
attempting that method first before performing a shallow
object comparison would be the best solution.
Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web compat issues, especially if `null`/`undefined` aren't special-cased. I feel an `equals` instance method added to all builtins and an `Object.equals` attempting that method first before performing a shallow object comparison would be the best solution. On Fri, Jan 18, 2019 at 15:24 Jordan Harband <ljharb at gmail.com> wrote: > It's pretty important that the meaning `===` not be able to change. > > On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator < > viliuskubilius416 at gmail.com> wrote: > >> What about having Symbol.equals? >> >> For example, for now this is what it does: >> >> ```js >> >> class Position { >> constructor(o) { >> this.x = o.x instanceof Number ? o.x : 0 >> >> this.y = o.y instanceof Number ? o.y : 0 >> >> this.z = o.z instanceof Number ? o.z : 0 >> } >> } >> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, >> y: 10, z: 10}) >> >> ``` >> Output is of course, false. >> With `Symbol.equals`, we could make it easier, instead of >> `instance.equals(otherInstance)`. >> >> >> >> For example: >> >> ```js >> >> class Position { >> >> [Symbol.equals](oIn) { >> return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z >> } >> constructor(o) { >> this.x = o.x instanceof Number ? o.x : 0 >> >> this.y = o.y instanceof Number ? o.y : 0 >> >> this.z = o.z instanceof Number ? o.z : 0 >> } >> } >> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, >> y: 10, z: 10}) >> >> ``` >> Now output would be true. >> >> This would save most of the time, instead of writing .equals and then >> surrounding everything with (). >> >> >> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. >> www.avast.com >> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> >> <#m_-3789658945863370968_m_4203195586323233386_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190118/366229ac/attachment.html>
the most reliable/idiot-proof equality is by avoiding classes altogether; stick with plain json-objects and compare their canonical-json-representation like this real-world example [1]:
/*jslint devel*/
(function () {
"use strict";
var jsonStringifyCanonical;
jsonStringifyCanonical = function (obj, replacer, space) {
/*
* this function will JSON.stringify <obj>,
* with object-keys sorted and circular-references removed
*/
var circularSet;
var stringify;
var tmp;
stringify = function (obj) {
/*
* this function will recursively JSON.stringify obj,
* with object-keys sorted and circular-references removed
*/
// if obj is not an object or function,
// then JSON.stringify as normal
if (!(
obj
&& typeof obj === "object"
&& typeof obj.toJSON !== "function"
)) {
return JSON.stringify(obj);
}
// ignore circular-reference
if (circularSet.has(obj)) {
return;
}
circularSet.add(obj);
// if obj is an array, then recurse its items
if (Array.isArray(obj)) {
tmp = "[" + obj.map(function (obj) {
// recurse
tmp = stringify(obj);
return (
typeof tmp === "string"
? tmp
: "null"
);
}).join(",") + "]";
circularSet.delete(obj);
return tmp;
}
// if obj is not an array,
// then recurse its items with object-keys sorted
tmp = "{" + Object.keys(obj).sort().map(function (key) {
// recurse
tmp = stringify(obj[key]);
if (typeof tmp === "string") {
return JSON.stringify(key) + ":" + tmp;
}
}).filter(function (obj) {
return typeof obj === "string";
}).join(",") + "}";
circularSet.delete(obj);
return tmp;
};
circularSet = new Set();
return JSON.stringify((
(typeof obj === "object" && obj)
// recurse
? JSON.parse(stringify(obj))
: obj
), replacer, space);
};
// true
console.assert(
// {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}}
jsonStringifyCanonical({
data: {x: 1, y: 2, z: 3},
meta: {label: "point #32"}
})
// === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}}
=== jsonStringifyCanonical({
meta: {label: "point #32"},
data: {z: 3, y: 2, x: 1}
})
);
}());
[1] testing aa “==“ b by comparing their canonical json-representation kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903, kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903
kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760, kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760
the most reliable/idiot-proof equality is by avoiding classes altogether; stick with plain json-objects and compare their canonical-json-representation like this real-world example [1]: ``` /*jslint devel*/ (function () { "use strict"; var jsonStringifyCanonical; jsonStringifyCanonical = function (obj, replacer, space) { /* * this function will JSON.stringify <obj>, * with object-keys sorted and circular-references removed */ var circularSet; var stringify; var tmp; stringify = function (obj) { /* * this function will recursively JSON.stringify obj, * with object-keys sorted and circular-references removed */ // if obj is not an object or function, // then JSON.stringify as normal if (!( obj && typeof obj === "object" && typeof obj.toJSON !== "function" )) { return JSON.stringify(obj); } // ignore circular-reference if (circularSet.has(obj)) { return; } circularSet.add(obj); // if obj is an array, then recurse its items if (Array.isArray(obj)) { tmp = "[" + obj.map(function (obj) { // recurse tmp = stringify(obj); return ( typeof tmp === "string" ? tmp : "null" ); }).join(",") + "]"; circularSet.delete(obj); return tmp; } // if obj is not an array, // then recurse its items with object-keys sorted tmp = "{" + Object.keys(obj).sort().map(function (key) { // recurse tmp = stringify(obj[key]); if (typeof tmp === "string") { return JSON.stringify(key) + ":" + tmp; } }).filter(function (obj) { return typeof obj === "string"; }).join(",") + "}"; circularSet.delete(obj); return tmp; }; circularSet = new Set(); return JSON.stringify(( (typeof obj === "object" && obj) // recurse ? JSON.parse(stringify(obj)) : obj ), replacer, space); }; // true console.assert( // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} jsonStringifyCanonical({ data: {x: 1, y: 2, z: 3}, meta: {label: "point #32"} }) // === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} === jsonStringifyCanonical({ meta: {label: "point #32"}, data: {z: 3, y: 2, x: 1} }) ); }()); ``` [1] testing aa “==“ b by comparing their canonical json-representation https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903 <https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760 <https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760> > On 18 Jan 2019, at 3:39 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > > Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web compat issues, especially if `null`/`undefined` aren't special-cased. I feel an `equals` instance method added to all builtins and an `Object.equals` attempting that method first before performing a shallow object comparison would be the best solution. > On Fri, Jan 18, 2019 at 15:24 Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com>> wrote: > It's pretty important that the meaning `===` not be able to change. > > On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator <viliuskubilius416 at gmail.com <mailto:viliuskubilius416 at gmail.com>> wrote: > What about having Symbol.equals? > > For example, for now this is what it does: > > ```js > > class Position { > constructor(o) { > this.x = o.x instanceof Number ? o.x : 0 > > this.y = o.y instanceof Number ? o.y : 0 > > this.z = o.z instanceof Number ? o.z : 0 > } > } > console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10}) > > ``` > Output is of course, false. > With `Symbol.equals`, we could make it easier, instead of `instance.equals(otherInstance)`. > > > > For example: > > ```js > > class Position { > > [Symbol.equals](oIn) { > return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z > } > constructor(o) { > this.x = o.x instanceof Number ? o.x : 0 > > this.y = o.y instanceof Number ? o.y : 0 > > this.z = o.z instanceof Number ? o.z : 0 > } > } > console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10}) > > ``` > Now output would be true. > > This would save most of the time, instead of writing .equals and then surrounding everything with (). > > > <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> <x-msg://1/#m_-3789658945863370968_m_4203195586323233386_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>_______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190118/6e75c869/attachment-0001.html>
This thread would apply equally well to objects (there's no such thing as a "json object" - json is a string, and once it's parsed into an object it's not json anymore) as to classes.
Please stop derailing threads with your off-topic ideology about how to write code - that belongs in a style guide, or in your own project, but not here.
This thread would apply equally well to objects (there's no such thing as a "json object" - json is a string, and once it's parsed into an object it's not json anymore) as to classes. Please stop derailing threads with your off-topic ideology about how to write code - that belongs in a style guide, or in your own project, but not here. On Fri, Jan 18, 2019 at 9:28 PM kai zhu <kaizhu256 at gmail.com> wrote: > the most reliable/idiot-proof equality is by avoiding classes altogether; > stick with plain json-objects and compare their > canonical-json-representation like this real-world example [1]: > > ``` > /*jslint devel*/ > (function () { > "use strict"; > var jsonStringifyCanonical; > > jsonStringifyCanonical = function (obj, replacer, space) { > /* > * this function will JSON.stringify <obj>, > * with object-keys sorted and circular-references removed > */ > var circularSet; > var stringify; > var tmp; > stringify = function (obj) { > /* > * this function will recursively JSON.stringify obj, > * with object-keys sorted and circular-references removed > */ > // if obj is not an object or function, > // then JSON.stringify as normal > if (!( > obj > && typeof obj === "object" > && typeof obj.toJSON !== "function" > )) { > return JSON.stringify(obj); > } > // ignore circular-reference > if (circularSet.has(obj)) { > return; > } > circularSet.add(obj); > // if obj is an array, then recurse its items > if (Array.isArray(obj)) { > tmp = "[" + obj.map(function (obj) { > // recurse > tmp = stringify(obj); > return ( > typeof tmp === "string" > ? tmp > : "null" > ); > }).join(",") + "]"; > circularSet.delete(obj); > return tmp; > } > // if obj is not an array, > // then recurse its items with object-keys sorted > tmp = "{" + Object.keys(obj).sort().map(function (key) { > // recurse > tmp = stringify(obj[key]); > if (typeof tmp === "string") { > return JSON.stringify(key) + ":" + tmp; > } > }).filter(function (obj) { > return typeof obj === "string"; > }).join(",") + "}"; > circularSet.delete(obj); > return tmp; > }; > circularSet = new Set(); > return JSON.stringify(( > (typeof obj === "object" && obj) > // recurse > ? JSON.parse(stringify(obj)) > : obj > ), replacer, space); > }; > > // true > console.assert( > // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} > jsonStringifyCanonical({ > data: {x: 1, y: 2, z: 3}, > meta: {label: "point #32"} > }) > // === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} > === jsonStringifyCanonical({ > meta: {label: "point #32"}, > data: {z: 3, y: 2, x: 1} > }) > ); > }()); > ``` > > > [1] testing aa “==“ b by comparing their canonical json-representation > https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903 > > https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760 > > > On 18 Jan 2019, at 3:39 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > > Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web > compat issues, especially if `null`/`undefined` aren't special-cased. I > feel an `equals` instance method added to all builtins and an > `Object.equals` attempting that method first before performing a shallow > object comparison would be the best solution. > On Fri, Jan 18, 2019 at 15:24 Jordan Harband <ljharb at gmail.com> wrote: > >> It's pretty important that the meaning `===` not be able to change. >> >> On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator < >> viliuskubilius416 at gmail.com> wrote: >> >>> What about having Symbol.equals? >>> >>> For example, for now this is what it does: >>> >>> ```js >>> >>> class Position { >>> constructor(o) { >>> this.x = o.x instanceof Number ? o.x : 0 >>> >>> this.y = o.y instanceof Number ? o.y : 0 >>> >>> this.z = o.z instanceof Number ? o.z : 0 >>> } >>> } >>> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, >>> y: 10, z: 10}) >>> >>> ``` >>> Output is of course, false. >>> With `Symbol.equals`, we could make it easier, instead of >>> `instance.equals(otherInstance)`. >>> >>> >>> >>> For example: >>> >>> ```js >>> >>> class Position { >>> >>> [Symbol.equals](oIn) { >>> return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z >>> } >>> constructor(o) { >>> this.x = o.x instanceof Number ? o.x : 0 >>> >>> this.y = o.y instanceof Number ? o.y : 0 >>> >>> this.z = o.z instanceof Number ? o.z : 0 >>> } >>> } >>> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, >>> y: 10, z: 10}) >>> >>> ``` >>> Now output would be true. >>> >>> This would save most of the time, instead of writing .equals and then >>> surrounding everything with (). >>> >>> >>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. >>> www.avast.com >>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190118/5a33f5ee/attachment.html>
This thread would apply equally well to objects (there's no such thing as a "json object" - json is a string, and once it's parsed into an object it's not json anymore) as to classes.
i’m not so sure when you start having classes with getters/setters/private-fields. then people begin digging rabbit-holes/silos trying to solve low-level equality-issues that shouldn’t even exist, and overall lose focus of the big-picture UX-workflow problems most of us js-devs were originally hired to solve.
> This thread would apply equally well to objects (there's no such thing as a "json object" - json is a string, and once it's parsed into an object it's not json anymore) as to classes. i’m not so sure when you start having classes with getters/setters/private-fields. then people begin digging rabbit-holes/silos trying to solve low-level equality-issues that shouldn’t even exist, and overall lose focus of the big-picture UX-workflow problems most of us js-devs were originally hired to solve. > On 18 Jan 2019, at 11:32 PM, Jordan Harband <ljharb at gmail.com> wrote: > > This thread would apply equally well to objects (there's no such thing as a "json object" - json is a string, and once it's parsed into an object it's not json anymore) as to classes. > > Please stop derailing threads with your off-topic ideology about how to write code - that belongs in a style guide, or in your own project, but not here. > > On Fri, Jan 18, 2019 at 9:28 PM kai zhu <kaizhu256 at gmail.com <mailto:kaizhu256 at gmail.com>> wrote: > the most reliable/idiot-proof equality is by avoiding classes altogether; stick with plain json-objects and compare their canonical-json-representation like this real-world example [1]: > > ``` > /*jslint devel*/ > (function () { > "use strict"; > var jsonStringifyCanonical; > > jsonStringifyCanonical = function (obj, replacer, space) { > /* > * this function will JSON.stringify <obj>, > * with object-keys sorted and circular-references removed > */ > var circularSet; > var stringify; > var tmp; > stringify = function (obj) { > /* > * this function will recursively JSON.stringify obj, > * with object-keys sorted and circular-references removed > */ > // if obj is not an object or function, > // then JSON.stringify as normal > if (!( > obj > && typeof obj === "object" > && typeof obj.toJSON !== "function" > )) { > return JSON.stringify(obj); > } > // ignore circular-reference > if (circularSet.has(obj)) { > return; > } > circularSet.add(obj); > // if obj is an array, then recurse its items > if (Array.isArray(obj)) { > tmp = "[" + obj.map(function (obj) { > // recurse > tmp = stringify(obj); > return ( > typeof tmp === "string" > ? tmp > : "null" > ); > }).join(",") + "]"; > circularSet.delete(obj); > return tmp; > } > // if obj is not an array, > // then recurse its items with object-keys sorted > tmp = "{" + Object.keys(obj).sort().map(function (key) { > // recurse > tmp = stringify(obj[key]); > if (typeof tmp === "string") { > return JSON.stringify(key) + ":" + tmp; > } > }).filter(function (obj) { > return typeof obj === "string"; > }).join(",") + "}"; > circularSet.delete(obj); > return tmp; > }; > circularSet = new Set(); > return JSON.stringify(( > (typeof obj === "object" && obj) > // recurse > ? JSON.parse(stringify(obj)) > : obj > ), replacer, space); > }; > > // true > console.assert( > // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} > jsonStringifyCanonical({ > data: {x: 1, y: 2, z: 3}, > meta: {label: "point #32"} > }) > // === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} > === jsonStringifyCanonical({ > meta: {label: "point #32"}, > data: {z: 3, y: 2, x: 1} > }) > ); > }()); > ``` > > > [1] testing aa “==“ b by comparing their canonical json-representation > https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903 <https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903> > https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760 <https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760> > > >> On 18 Jan 2019, at 3:39 PM, Isiah Meadows <isiahmeadows at gmail.com <mailto:isiahmeadows at gmail.com>> wrote: >> >> Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web compat issues, especially if `null`/`undefined` aren't special-cased. I feel an `equals` instance method added to all builtins and an `Object.equals` attempting that method first before performing a shallow object comparison would be the best solution. >> On Fri, Jan 18, 2019 at 15:24 Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com>> wrote: >> It's pretty important that the meaning `===` not be able to change. >> >> On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator <viliuskubilius416 at gmail.com <mailto:viliuskubilius416 at gmail.com>> wrote: >> What about having Symbol.equals? >> >> For example, for now this is what it does: >> >> ```js >> >> class Position { >> constructor(o) { >> this.x = o.x instanceof Number ? o.x : 0 >> >> this.y = o.y instanceof Number ? o.y : 0 >> >> this.z = o.z instanceof Number ? o.z : 0 >> } >> } >> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10}) >> >> ``` >> Output is of course, false. >> With `Symbol.equals`, we could make it easier, instead of `instance.equals(otherInstance)`. >> >> >> >> For example: >> >> ```js >> >> class Position { >> >> [Symbol.equals](oIn) { >> return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z >> } >> constructor(o) { >> this.x = o.x instanceof Number ? o.x : 0 >> >> this.y = o.y instanceof Number ? o.y : 0 >> >> this.z = o.z instanceof Number ? o.z : 0 >> } >> } >> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10}) >> >> ``` >> Now output would be true. >> >> This would save most of the time, instead of writing .equals and then surrounding everything with (). >> >> >> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> <>_______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190119/93fcd768/attachment-0001.html>
As has been stated many times before, many JS developers have been hired to do things entirely unrelated to UX workflows; regardless, whether you like a specific coding style or not is irrelevant to discussing language features, and is very disruptive to these discussions. Please confine that to discussing style with your own team, or within a styleguide.
As has been stated many times before, many JS developers have been hired to do things entirely unrelated to UX workflows; regardless, whether you like a specific coding style or not is *irrelevant* to discussing language features, and is very disruptive to these discussions. Please confine that to discussing style with your own team, or within a styleguide. On Fri, Jan 18, 2019 at 11:08 PM kai zhu <kaizhu256 at gmail.com> wrote: > > This thread would apply equally well to objects (there's no such thing > as a "json object" - json is a string, and once it's parsed into an object > it's not json anymore) as to classes. > > i’m not so sure when you start having classes with > getters/setters/private-fields. then people begin digging > rabbit-holes/silos trying to solve low-level equality-issues that shouldn’t > even exist, and overall lose focus of the big-picture UX-workflow problems > most of us js-devs were originally hired to solve. > > On 18 Jan 2019, at 11:32 PM, Jordan Harband <ljharb at gmail.com> wrote: > > This thread would apply equally well to objects (there's no such thing as > a "json object" - json is a string, and once it's parsed into an object > it's not json anymore) as to classes. > > Please stop derailing threads with your off-topic ideology about how to > write code - that belongs in a style guide, or in your own project, but not > here. > > On Fri, Jan 18, 2019 at 9:28 PM kai zhu <kaizhu256 at gmail.com> wrote: > >> the most reliable/idiot-proof equality is by avoiding classes altogether; >> stick with plain json-objects and compare their >> canonical-json-representation like this real-world example [1]: >> >> ``` >> /*jslint devel*/ >> (function () { >> "use strict"; >> var jsonStringifyCanonical; >> >> jsonStringifyCanonical = function (obj, replacer, space) { >> /* >> * this function will JSON.stringify <obj>, >> * with object-keys sorted and circular-references removed >> */ >> var circularSet; >> var stringify; >> var tmp; >> stringify = function (obj) { >> /* >> * this function will recursively JSON.stringify obj, >> * with object-keys sorted and circular-references removed >> */ >> // if obj is not an object or function, >> // then JSON.stringify as normal >> if (!( >> obj >> && typeof obj === "object" >> && typeof obj.toJSON !== "function" >> )) { >> return JSON.stringify(obj); >> } >> // ignore circular-reference >> if (circularSet.has(obj)) { >> return; >> } >> circularSet.add(obj); >> // if obj is an array, then recurse its items >> if (Array.isArray(obj)) { >> tmp = "[" + obj.map(function (obj) { >> // recurse >> tmp = stringify(obj); >> return ( >> typeof tmp === "string" >> ? tmp >> : "null" >> ); >> }).join(",") + "]"; >> circularSet.delete(obj); >> return tmp; >> } >> // if obj is not an array, >> // then recurse its items with object-keys sorted >> tmp = "{" + Object.keys(obj).sort().map(function (key) { >> // recurse >> tmp = stringify(obj[key]); >> if (typeof tmp === "string") { >> return JSON.stringify(key) + ":" + tmp; >> } >> }).filter(function (obj) { >> return typeof obj === "string"; >> }).join(",") + "}"; >> circularSet.delete(obj); >> return tmp; >> }; >> circularSet = new Set(); >> return JSON.stringify(( >> (typeof obj === "object" && obj) >> // recurse >> ? JSON.parse(stringify(obj)) >> : obj >> ), replacer, space); >> }; >> >> // true >> console.assert( >> // {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} >> jsonStringifyCanonical({ >> data: {x: 1, y: 2, z: 3}, >> meta: {label: "point #32"} >> }) >> // === {"data":{"x":1,"y":2,"z":3},"meta":{"label":"point #13"}} >> === jsonStringifyCanonical({ >> meta: {label: "point #32"}, >> data: {z: 3, y: 2, x: 1} >> }) >> ); >> }()); >> ``` >> >> >> [1] testing aa “==“ b by comparing their canonical json-representation >> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/test.js#L2903 >> >> https://github.com/kaizhu256/node-utility2/blob/2018.12.30/lib.utility2.js#L2760 >> >> >> On 18 Jan 2019, at 3:39 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: >> >> Yeah, I agree. I'd suggest overloading `==`, but that'd risk serious web >> compat issues, especially if `null`/`undefined` aren't special-cased. I >> feel an `equals` instance method added to all builtins and an >> `Object.equals` attempting that method first before performing a shallow >> object comparison would be the best solution. >> On Fri, Jan 18, 2019 at 15:24 Jordan Harband <ljharb at gmail.com> wrote: >> >>> It's pretty important that the meaning `===` not be able to change. >>> >>> On Fri, Jan 18, 2019 at 10:33 AM ViliusCreator < >>> viliuskubilius416 at gmail.com> wrote: >>> >>>> What about having Symbol.equals? >>>> >>>> For example, for now this is what it does: >>>> >>>> ```js >>>> >>>> class Position { >>>> constructor(o) { >>>> this.x = o.x instanceof Number ? o.x : 0 >>>> >>>> this.y = o.y instanceof Number ? o.y : 0 >>>> >>>> this.z = o.z instanceof Number ? o.z : 0 >>>> } >>>> } >>>> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: >>>> 10, y: 10, z: 10}) >>>> >>>> ``` >>>> Output is of course, false. >>>> With `Symbol.equals`, we could make it easier, instead of >>>> `instance.equals(otherInstance)`. >>>> >>>> >>>> >>>> For example: >>>> >>>> ```js >>>> >>>> class Position { >>>> >>>> [Symbol.equals](oIn) { >>>> return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z >>>> } >>>> constructor(o) { >>>> this.x = o.x instanceof Number ? o.x : 0 >>>> >>>> this.y = o.y instanceof Number ? o.y : 0 >>>> >>>> this.z = o.z instanceof Number ? o.z : 0 >>>> } >>>> } >>>> console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: >>>> 10, y: 10, z: 10}) >>>> >>>> ``` >>>> Now output would be true. >>>> >>>> This would save most of the time, instead of writing .equals and then >>>> surrounding everything with (). >>>> >>>> >>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. >>>> www.avast.com >>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190119/dd614112/attachment-0001.html>
What about having Symbol.equals? For example, for now this is what it does:
class Position { constructor(o) { this.x = o.x instanceof Number ? o.x : 0 this.y = o.y instanceof Number ? o.y : 0 this.z = o.z instanceof Number ? o.z : 0 } } console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10})
Output is of course, false. With
Symbol.equals
, we could make it easier, instead ofinstance.equals(otherInstance)
.For example:
class Position { [Symbol.equals](oIn) { return oIn.x === this.x && oIn.y === this.y && oIn.z === this.z } constructor(o) { this.x = o.x instanceof Number ? o.x : 0 this.y = o.y instanceof Number ? o.y : 0 this.z = o.z instanceof Number ? o.z : 0 } } console.log(new Position({x: 10, y: 10, z: 10}) === new Position({x: 10, y: 10, z: 10})
Now output would be true. This would save most of the time, instead of writing .equals and then surrounding everything with ().