Object.assign and inherited properties
You are talking about "flatting" all properties, which is an undesired overhead.
var b = Object.create(
Object.getPrototypeOf(a)
);
Object.assign(b, a);
But what's bugging me every time more, is that somebody had a very bad idea
to spread Object.assign
as something good for inheritance or object
cloning.
Where does this come from? Object.assign
retrieves properties and ignore
getters and setters, is the last tool you want to use as substitution
principle because it breaks.
Object.assign
is good only to define enumerable, writable, and
configurable properties, like configuration or setup objects.
Are you dealing with prototypes and Object.assign
? You gonna have way
more problems than a missed flattered structure.
Can you explain what is your goal ? Wouldn't this work?
var a = {}; // or anything else
var b = Object.create(
Object.getPrototypeOf(a)
);
Object.getOwnPropertyNames(a).forEach(function (k) {
Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k));
});
Best
You are talking about "flatting" all properties, which is an undesired overhead. ```js var b = Object.create( Object.getPrototypeOf(a) ); Object.assign(b, a); ``` But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. Can you explain what is your goal ? Wouldn't this work? ```js var a = {}; // or anything else var b = Object.create( Object.getPrototypeOf(a) ); Object.getOwnPropertyNames(a).forEach(function (k) { Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); }); ``` Best Regards On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: > Hello, > > Why does Object.assign ignore inherited enumerable properties? > What is the problem to which ignoring inherited properties is the solution > to? > > All I can see is that it prevents a useful use of inheritance. The Liskov > substitution principle > <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was > mentioned 27 years ago in ’87. Why is Object.assign breaking it? > > - Everyone who’s messing with Object.prototype has to do it an > non-enumerable style anyway. > - Most uses of Object.assign will likely be for objects with a finite > number of keys. Those form specific and implicit types from which people > are likely to read with the dot-operator. That takes inheritance into > account anyway. > > I don’t get the agenda to mess with object inheritance. If one wants > methods to only be in the parent and data on the child (so Object.assign > would only copy data), use a classical language. In a delegation-prototypal > language one should be able to inherit freely because of LSP > <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. > > Andri > > _______________________________________________ > 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/20150227/37e9c05f/attachment-0001.html>
You are talking about "flatting" all properties, which is an undesired overhead.
Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there.
But what's bugging me every time more, is that somebody had a very bad idea to spread
Object.assign
as something good for inheritance or object cloning.Where does this come from?
Object.assign
retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks.
Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around.
Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s not meant to be the function-equivalent of for (var key in source) target[key] = source[key]
then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that.
But what's bugging me every time more, is that somebody had a very bad idea to spread
Object.assign
as something good for inheritance or object cloning.
Are you dealing with prototypes and
Object.assign
? You gonna have way more problems than a missed flattered structure. Can you explain what is your goal ? Wouldn't this work?
Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call.
My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix every obj.name use with hasOwn: obj.hasOwnProperty(“name”) && obj.name
. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for.
A.
> You are talking about "flatting" all properties, which is an undesired overhead. Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. > But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. > > Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. > But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. > Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. > Can you explain what is your goal ? Wouldn't this work? Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. A. On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > You are talking about "flatting" all properties, which is an undesired overhead. > > ```js > > var b = Object.create( > Object.getPrototypeOf(a) > ); > > Object.assign(b, a); > > ``` > > But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. > > Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. > > `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. > > Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. > > Can you explain what is your goal ? Wouldn't this work? > > ```js > > var a = {}; // or anything else > > var b = Object.create( > Object.getPrototypeOf(a) > ); > > Object.getOwnPropertyNames(a).forEach(function (k) { > Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); > }); > > ``` > > > Best Regards > > > > On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: > Hello, > > Why does Object.assign ignore inherited enumerable properties? > What is the problem to which ignoring inherited properties is the solution to? > > All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? > > - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. > - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. > > I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. > > Andri > > _______________________________________________ > 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/20150227/82de5d1b/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/82de5d1b/attachment.p7s>
noone? JSLint doesn't even let you write a for/in loop if you don't have
obj.hasOwnProperty(key)
in it, and usually nobody wants inherited
properties (included methods from old classes/ahem prototypes) reassigned
everywhere.
If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in
function flatEnumerables(a) {
for (var c, k, i = 1; i < arguments.length; i++) {
for (k in (c = arguments[i])) a[k] = c[k];
}
return a;
}
This would do what you are looking for (which is the first time I
personally read/hear about somebody wanting Object.assign
to behave like
a for/in)
Would that work?
Best
noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in ``` function flatEnumerables(a) { for (var c, k, i = 1; i < arguments.length; i++) { for (k in (c = arguments[i])) a[k] = c[k]; } return a; } ``` This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) Would that work? Best Regards On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: > You are talking about "flatting" all properties, which is an undesired > overhead. > > > Umm, Object.assign is as it is because of performance? I don’t think it is > nor is that a good reason. Every property access in JavaScript takes > inheritance into account and there are thousands more than a Object.assign > call here and there. > > But what's bugging me every time more, is that somebody had a very bad > idea to spread `Object.assign` as something good for inheritance or object > cloning. > > Where does this come from? `Object.assign` retrieves properties and ignore > getters and setters, is the last tool you want to use as substitution > principle because it breaks. > > > Ignores getters? You mean merely reads them? That’s not ignoring. Getters > are an implementation detail of an interface. > Prototypes aren't only useful for sharing behavior. They’re just as useful > for *data objects and value types*. Nothing breaks when you clone or > assign them around. > > Object.assign just read properties from one object and assign them to > another. Something you used to do by hand. It’s just shorter to type > assign(A, B) than type all properties of B out manually. If it’s _not_ > meant to be the function-equivalent of `*for (var key in source) > target[key] = source[key]*` then that’s too bad as my money is on it’s > going to be used as such. I definitely want to use it for that. > > But what's bugging me every time more, is that somebody had a very bad > idea to spread `Object.assign` as something good for inheritance or object > cloning. > > Are you dealing with prototypes and `Object.assign` ? You gonna have way > more problems than a missed flattered structure. > Can you explain what is your goal ? Wouldn't this work? > > > Inheritance? Inheritance is an implementation detail. A function receiving > an object must not care about its inheritance tree as long as it fulfills > the required interface. That’s what the LSP says as well. Even though > JavaScript has no explicit concept of interfaces or types, they’re implicit > in any function call. > > My goal is to save people from having to think every time they call a > function whether this 3rd party function ignores inherited properties or > not. If the callee uses Object.assign, it strips them out, if not, the > dot-operator takes it into account. Surely no-one’s expecting everyone to > prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) && > obj.name <http://obj.name>`*. Why do it in Object.assigns then is beyond > me. Inconsistent and uncalled for. > > A. > > On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > You are talking about "flatting" all properties, which is an undesired > overhead. > > ```js > > var b = Object.create( > Object.getPrototypeOf(a) > ); > > Object.assign(b, a); > > ``` > > But what's bugging me every time more, is that somebody had a very bad > idea to spread `Object.assign` as something good for inheritance or object > cloning. > > Where does this come from? `Object.assign` retrieves properties and ignore > getters and setters, is the last tool you want to use as substitution > principle because it breaks. > > `Object.assign` is good only to define enumerable, writable, and > configurable properties, like configuration or setup objects. > > Are you dealing with prototypes and `Object.assign` ? You gonna have way > more problems than a missed flattered structure. > > Can you explain what is your goal ? Wouldn't this work? > > ```js > > var a = {}; // or anything else > > var b = Object.create( > Object.getPrototypeOf(a) > ); > > Object.getOwnPropertyNames(a).forEach(function (k) { > Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); > }); > > ``` > > > Best Regards > > > > On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: > >> Hello, >> >> Why does Object.assign ignore inherited enumerable properties? >> What is the problem to which ignoring inherited properties is the >> solution to? >> >> All I can see is that it prevents a useful use of inheritance. The Liskov >> substitution principle >> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >> >> - Everyone who’s messing with Object.prototype has to do it an >> non-enumerable style anyway. >> - Most uses of Object.assign will likely be for objects with a finite >> number of keys. Those form specific and implicit types from which people >> are likely to read with the dot-operator. That takes inheritance into >> account anyway. >> >> I don’t get the agenda to mess with object inheritance. If one wants >> methods to only be in the parent and data on the child (so Object.assign >> would only copy data), use a classical language. In a delegation-prototypal >> language one should be able to inherit freely because of LSP >> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >> >> Andri >> >> _______________________________________________ >> 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/20150227/09cef77c/attachment-0001.html>
On Fri, Feb 27, 2015 at 10:56 PM, Andri Möll <andri at dot.ee> wrote:
Prototypes aren't only useful for sharing behavior. They’re just as
useful for data objects and value types.
They, er, sort of aren't. One big deal is that you can't JSON.stringify()
them, because that ignores inherited properties. Additionally: you can't
delete
properties from them reliably because you don't know whether
they're inherited. You can't Object.freeze()
them to guarantee their
property interface will never be modified afterward, because the prototypes
could still be altered (this could be construed as a feature, but I think
it too badly wounds the "guarantee" that Object.freeze offers). You also
can't Object.freeze()
the first prototype, because then its properties
can't be easily overridden on its inheritors due to the override "bug".
The main use-case for Object.create()
ing data objects seems to be virtual
duplication of the properties. Suggestion: switch to exclusively using
actual duplication via Object.assign()
whenever possible.
Granted, I actually do have a personal project that uses the prototype chain to make a data structure, but I don't consider its use to be common or robust enough to be standardised, yet.
...
Object.assign
was designed specifically to "pave a cowpath" - that is, to
take a very common third-party function and exactly replicate its semantics
in the standard, as a drop-in replacement in future projects.
(Object.create
and Function.prototype.bind
arose from a similar
upbringing.) The semantics it replicates are jQuery.extend
, PrototypeJS's
Object.extend
and similar .extend
methods, which only copy enumerable
own non-symbol properties. I don't quite like it, myself, because I think
the 'non-symbol' restriction is a bit of a dated decision from back when
symbols were "private members" instead of the more general unique property
identifiers they are now - but it's still my most commonly used ES6-shim
method.
If you're interested in a rough idea of where TC39 stands on data object copying, see these notes about object rest destructuring:
MM: In ES3, assumption is there's all sorts of gunk on Object.prototype
because no way to get rid of it. Reason it was restricted to own-ness was because there was a desire to not iterate stuff on Object.prototype
YK: There's a notion of copying today that means "enum, own"
AWB: Notions in JS today are diff from notions 5 years ago and 5 years
from now
MM: We can't accomodate legacy in this way forever. We're in a history
dependent trap, we should make this (enumerable + own)?[verify]
On Fri, Feb 27, 2015 at 10:56 PM, Andri Möll <andri at dot.ee> wrote: > Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. They, er, sort of aren't. One big deal is that you can't `JSON.stringify()` them, because that ignores inherited properties. Additionally: you can't `delete` properties from them reliably because you don't know whether they're inherited. You can't `Object.freeze()` them to guarantee their property interface will never be modified afterward, because the prototypes could still be altered (this could be construed as a feature, but I think it too badly wounds the "guarantee" that Object.freeze offers). You also can't `Object.freeze()` the first prototype, because then its properties can't be easily overridden on its inheritors due to the override "bug". The main use-case for `Object.create()`ing data objects seems to be virtual duplication of the properties. Suggestion: switch to exclusively using actual duplication via `Object.assign()` whenever possible. Granted, I actually do have a personal project that uses the prototype chain to make a data structure, but I don't consider its use to be common or robust enough to be standardised, yet. ... `Object.assign` was designed specifically to "pave a cowpath" - that is, to take a very common third-party function and exactly replicate its semantics in the standard, as a drop-in replacement in future projects. (`Object.create` and `Function.prototype.bind` arose from a similar upbringing.) The semantics it replicates are `jQuery.extend`, PrototypeJS's `Object.extend` and similar `.extend` methods, which only copy enumerable own non-symbol properties. I don't quite like it, myself, because I think the 'non-symbol' restriction is a bit of a dated decision from back when symbols were "private members" instead of the more general unique property identifiers they are now - but it's still my most commonly used ES6-shim method. If you're interested in a rough idea of where TC39 stands on data object copying, see [these notes about object rest destructuring]( https://github.com/rwaldron/tc39-notes/blob/b1af70ec299e996a9f1e2e34746269fbbb835d7e/es6/2014-09/sept-25.md#58-object-rest-destructuring-and-spread-properties ): >MM: In ES3, assumption is there's all sorts of gunk on Object.prototype because no way to get rid of it. Reason it was restricted to own-ness was because there was a desire to not iterate stuff on Object.prototype > >YK: There's a notion of copying today that means "enum, own" > >AWB: Notions in JS today are diff from notions 5 years ago and 5 years from now > >MM: We can't accomodate legacy in this way forever. We're in a history dependent trap, we should make this (enumerable + own)?[verify] -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150228/a9b7c75f/attachment.html>
noone? JSLint doesn't even let you write a for/in loop if you don't have
obj.hasOwnProperty(key)
in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere.
Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore.
Again, I ask, what is the problem to which ignoring inherited properties is the solution to?
I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence.
JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter.
And as I said below: until everyone also prefixes their obj.name uses with hasOwn: obj.hasOwnProperty(“name”) && obj.name
, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that?
This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design.
A.
> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. Again, I ask, what is the problem to which ignoring inherited properties is the solution to? I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence. JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter. And as I said below: until everyone also prefixes their obj.name uses with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that? This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design. A. On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. > > If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in > > ``` > function flatEnumerables(a) { > for (var c, k, i = 1; i < arguments.length; i++) { > for (k in (c = arguments[i])) a[k] = c[k]; > } > return a; > } > ``` > This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) > > Would that work? > > Best Regards > > > > On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >> You are talking about "flatting" all properties, which is an undesired overhead. > > Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. > >> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >> >> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. > > > Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. > Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. > > Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. > >> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. > >> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >> Can you explain what is your goal ? Wouldn't this work? > > Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. > > My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. > > A. > > On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > >> You are talking about "flatting" all properties, which is an undesired overhead. >> >> ```js >> >> var b = Object.create( >> Object.getPrototypeOf(a) >> ); >> >> Object.assign(b, a); >> >> ``` >> >> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >> >> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >> >> `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. >> >> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >> >> Can you explain what is your goal ? Wouldn't this work? >> >> ```js >> >> var a = {}; // or anything else >> >> var b = Object.create( >> Object.getPrototypeOf(a) >> ); >> >> Object.getOwnPropertyNames(a).forEach(function (k) { >> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >> }); >> >> ``` >> >> >> Best Regards >> >> >> >> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >> Hello, >> >> Why does Object.assign ignore inherited enumerable properties? >> What is the problem to which ignoring inherited properties is the solution to? >> >> All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? >> >> - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. >> - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. >> >> I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. >> >> Andri >> >> _______________________________________________ >> 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/20150227/79ec9182/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/79ec9182/attachment-0001.p7s>
On 27 February 2015 at 15:22, Andri Möll <andri at dot.ee> wrote:
noone? JSLint doesn't even let you write a for/in loop if you don't have
obj.hasOwnProperty(key)
in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere.Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore.
Again, I ask, what is the problem to which ignoring inherited properties is the solution to?
The fragile base class problem is one.
On 27 February 2015 at 15:22, Andri Möll <andri at dot.ee> wrote: > noone? JSLint doesn't even let you write a for/in loop if you don't have > `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited > properties (included methods from old classes/ahem prototypes) reassigned > everywhere. > > > Huh? Old prototypes? Those prototypes have their properties set as > non-enumerable since how long now? You yourself said one shouldn’t use > Object.assign for objects with behavior in the inheritance chain. And I > agree. It’s pretty much only useful for data objects (a.k.a plain). Those > have no methods in the inheritance chain one needs to ignore. > > Again, I ask, *what is the problem to which ignoring inherited properties > is the solution to?* > The fragile base class problem is one. /Andreas -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/2a9455cb/attachment.html>
They, er, sort of aren't. One big deal is that you can't
JSON.stringify()
them, because that ignores inherited properties.
Indeed, I too think JSON.stringify is poorly designed in that respect, especially because, adding insult to injury, inheritance is considered when searching for toJSON. As I said, inconsistent as hell. :-) Those of us, and apparently you included, accept the delete-freeze nuances. People who find copying sufficient, can carry on — inheritance won't affect them.
Object.assign
was designed specifically to "pave a cowpath" - that is, to take a very common third-party function and exactly replicate its semantics in the standard, as a drop-in replacement in future projects
Reasonable approach to stdlib design. Except this cowpath isn’t paved the way cows walked: Both jQuery.extend and Underscore.extend do consider inheritance. And if the world’s most popular JS library has taken inheritance into account for at least 7 years now (that was the last time I tried to prefix everything with hasOwnProperty), where’s the problem?
On Feb 27, 2015, at 16:34, Andreas Rossberg <rossberg at google.com> wrote:
The fragile base class problem is one.
That’s a problem of the caller, not the callee, the user of Object.assign. If I decide to use inheritance, that’s my risk. And because a mutable Object.prototype is every object’s ancestor anyway, ignoring intermediary inheritance in Object.assign doesn’t fix anything.
If you're interested in a rough idea of where TC39 stands on data object copying, see these notes about object rest destructuring:
Thanks! I didn’t get much out of it, sadly. I see some vague references to “people do this” and “community does that”, which translates to “people I agree with” and “my community”. The worrying about Object.prototype.hostile = true
is also a fool’s errand, because every object inherits from Object.prototype and every person uses the dot-operator to read values. Every obj.hostile returns true no matter how many times you run it through Object.assign. That is security theatre.
I did find an argument I haven’t addressed directly: because a future record type won’t support inheriting from, it follows that neither should it be supported for regular objects. Well, no. That’s a non sequitur. Inheritance is an implementation detail. A callee must not care how properties of a pre-agreed upon interface are implemented. Object.assign even agrees to half of it — it doesn’t care whether a property is plain or implemented as a getter. Now it just needs to iterate over inheritance and all’s dandy.
A.
> They, er, sort of aren't. One big deal is that you can't `JSON.stringify()` them, because that ignores inherited properties. Indeed, I too think JSON.stringify is poorly designed in that respect, especially because, adding insult to injury, inheritance _is_ considered when searching for toJSON. As I said, inconsistent as hell. :-) Those of us, and apparently you included, accept the delete-freeze nuances. People who find copying sufficient, can carry on — inheritance won't affect them. > `Object.assign` was designed specifically to "pave a cowpath" - that is, to take a very common third-party function and exactly replicate its semantics in the standard, as a drop-in replacement in future projects Reasonable approach to stdlib design. Except this cowpath isn’t paved the way cows walked: Both jQuery.extend _and_ Underscore.extend do consider inheritance. And if the world’s most popular JS library has taken inheritance into account for at least 7 years now (that was the last time I tried to prefix everything with hasOwnProperty), where’s the problem? On Feb 27, 2015, at 16:34, Andreas Rossberg <rossberg at google.com> wrote: > The fragile base class problem is one. That’s a problem of the caller, not the callee, the user of Object.assign. If I decide to use inheritance, that’s my risk. And because a mutable Object.prototype is every object’s ancestor anyway, ignoring intermediary inheritance in Object.assign doesn’t fix anything. > If you're interested in a rough idea of where TC39 stands on data object copying, see [these notes about object rest destructuring](https://github.com/rwaldron/tc39-notes/blob/b1af70ec299e996a9f1e2e34746269fbbb835d7e/es6/2014-09/sept-25.md#58-object-rest-destructuring-and-spread-properties): Thanks! I didn’t get much out of it, sadly. I see some vague references to “people do this” and “community does that”, which translates to “people I agree with” and “my community”. The worrying about `Object.prototype.hostile = true` is also a fool’s errand, because every object inherits from Object.prototype and every person uses the dot-operator to read values. Every obj.hostile returns true no matter how many times you run it through Object.assign. That is security theatre. I did find an argument I haven’t addressed directly: because a future record type won’t support inheriting from, it follows that neither should it be supported for regular objects. Well, no. That’s a non sequitur. Inheritance is an implementation detail. A callee must not care how properties of a pre-agreed upon interface are implemented. Object.assign even agrees to half of it — it doesn’t care whether a property is plain or implemented as a getter. Now it just needs to iterate over inheritance and all’s dandy. A. On Feb 27, 2015, at 16:21, Leon Arnott <leonarnott at gmail.com> wrote: > On Fri, Feb 27, 2015 at 10:56 PM, Andri Möll <andri at dot.ee> wrote: > > Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. > > They, er, sort of aren't. One big deal is that you can't `JSON.stringify()` them, because that ignores inherited properties. Additionally: you can't `delete` properties from them reliably because you don't know whether they're inherited. You can't `Object.freeze()` them to guarantee their property interface will never be modified afterward, because the prototypes could still be altered (this could be construed as a feature, but I think it too badly wounds the "guarantee" that Object.freeze offers). You also can't `Object.freeze()` the first prototype, because then its properties can't be easily overridden on its inheritors due to the override "bug". > > The main use-case for `Object.create()`ing data objects seems to be virtual duplication of the properties. Suggestion: switch to exclusively using actual duplication via `Object.assign()` whenever possible. > > Granted, I actually do have a personal project that uses the prototype chain to make a data structure, but I don't consider its use to be common or robust enough to be standardised, yet. > > ... > > `Object.assign` was designed specifically to "pave a cowpath" - that is, to take a very common third-party function and exactly replicate its semantics in the standard, as a drop-in replacement in future projects. (`Object.create` and `Function.prototype.bind` arose from a similar upbringing.) The semantics it replicates are `jQuery.extend`, PrototypeJS's `Object.extend` and similar `.extend` methods, which only copy enumerable own non-symbol properties. I don't quite like it, myself, because I think the 'non-symbol' restriction is a bit of a dated decision from back when symbols were "private members" instead of the more general unique property identifiers they are now - but it's still my most commonly used ES6-shim method. > > If you're interested in a rough idea of where TC39 stands on data object copying, see [these notes about object rest destructuring](https://github.com/rwaldron/tc39-notes/blob/b1af70ec299e996a9f1e2e34746269fbbb835d7e/es6/2014-09/sept-25.md#58-object-rest-destructuring-and-spread-properties): > > >MM: In ES3, assumption is there's all sorts of gunk on Object.prototype because no way to get rid of it. Reason it was restricted to own-ness was because there was a desire to not iterate stuff on Object.prototype > > > >YK: There's a notion of copying today that means "enum, own" > > > >AWB: Notions in JS today are diff from notions 5 years ago and 5 years from now > > > >MM: We can't accomodate legacy in this way forever. We're in a history dependent trap, we should make this (enumerable + own)?[verify] -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/b305f97a/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/b305f97a/attachment-0001.p7s>
On 27 February 2015 at 16:16, Andri Möll <andri at dot.ee> wrote:
The fragile base class problem is one.
That’s a problem of the caller, not the callee, the user of Object.assign. If I decide to use inheritance, that’s my risk.
You would like it to be that way, but that's not how it plays out in practice. Once dependencies have been created, you often can't afford to break them, no matter how much a problem is their fault.
On 27 February 2015 at 16:16, Andri Möll <andri at dot.ee> wrote: > The fragile base class problem is one. > > > That’s a problem of the caller, not the callee, the user of Object.assign. > If I decide to use inheritance, that’s my risk. > You would like it to be that way, but that's not how it plays out in practice. Once dependencies have been created, you often can't afford to break them, no matter how much a problem is their fault. /Andreas -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/12554e06/attachment.html>
answering inline ...
On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote:
noone? JSLint doesn't even let you write a for/in loop if you don't have
obj.hasOwnProperty(key)
in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere.Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now?
nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need.
You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore.
meaning you are good to go with assign or the function I wrote for you.
Again, I ask, what is the problem to which ignoring inherited properties is the solution to?
[ 1 ] What is the problem in accessing inherited values?
If you don't want to distinguish them, just don't and use a for/in
Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999
I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence.
You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. I am back with previous [ 1 ] question then.
JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter.
You can define you rtoJSON
method that returns the result of the for/in
based function I've written for you. Is that retarded?
Moreover, you can recreate instances at parse time with a specialized reviver: gist.github.com/WebReflection/87e41c09691edf9432da Is that retarded? ( maybe this one is :P )
And as I said below: until everyone also prefixes their obj.name uses with hasOwn:
*obj.hasOwnProperty(“name”) && obj.name <http://obj.name>
*, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that?
actually, following your logic you should never access that unless you are sure it's also enumerable so ...
*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") && **obj.name <http://obj.name/>
*`
This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design.
Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter.
I really don't see, with all possibilities you have to write the way you
want, and a function I wrote for you that does what you need, why bothering
Object.assign
Best
answering inline ... On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: > noone? JSLint doesn't even let you write a for/in loop if you don't have > `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited > properties (included methods from old classes/ahem prototypes) reassigned > everywhere. > > > Huh? Old prototypes? Those prototypes have their properties set as > non-enumerable since how long now? > nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. > You yourself said one shouldn’t use Object.assign for objects with > behavior in the inheritance chain. And I agree. It’s pretty much only > useful for data objects (a.k.a plain). Those have no methods in the > inheritance chain one needs to ignore. > meaning you are good to go with assign or the function I wrote for you. > > Again, I ask, *what is the problem to which ignoring inherited properties > is the solution to?* > > [ 1 ] What is the problem in accessing inherited values? If you don't want to distinguish them, just don't and use a for/in Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 > I posit everyone wants inherited properties. Just half of the people have > been FUDed into being afraid of inheritance. But arguments based on > assumptions on what other people want are irrelevant because naive people > are easy to influence. > You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. I am back with previous [ 1 ] question then. > JSLint is how Douglas Crockford writes his code. That’s not an argument > for right APIs. JSON.stringify is equally retarded with its inconsistent > handling of inheritance, but that’s another matter. > You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? Moreover, you can recreate instances at parse time with a specialized reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da Is that retarded? ( maybe this one is :P ) > > And as I said below: until everyone also prefixes their obj.name uses > with hasOwn: `*obj.hasOwnProperty(“name”) && obj.name <http://obj.name>`*, > skipping inherited properties is a fool’s errand. It causes *inconsistent > APIs* because you don’t run your options et alii objects through > inheritance strippers every time. And you shouldn’t. Or does anyone > disagree with that? > actually, following your logic you should never access that unless you are sure it's also enumerable so ... `*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") && **obj.name <http://obj.name/>`*` > > This is a bigger problem than my use of Object.assign. Proliferation of > Object.assign will prevent everyone else from relying on inheritance. And > in a prototypal language I find that bad API design. > Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` Best Regards > > A. > > On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > noone? JSLint doesn't even let you write a for/in loop if you don't have > `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited > properties (included methods from old classes/ahem prototypes) reassigned > everywhere. > > If you deal with data objects and dictionaries yuo'll always have a flat > structure, right? If you don't care about properties descriptors (getters > and setters) you can always use a for/in > > ``` > function flatEnumerables(a) { > for (var c, k, i = 1; i < arguments.length; i++) { > for (k in (c = arguments[i])) a[k] = c[k]; > } > return a; > } > ``` > This would do what you are looking for (which is the first time I > personally read/hear about somebody wanting `Object.assign` to behave like > a for/in) > > Would that work? > > Best Regards > > > > On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: > >> You are talking about "flatting" all properties, which is an undesired >> overhead. >> >> >> Umm, Object.assign is as it is because of performance? I don’t think it >> is nor is that a good reason. Every property access in JavaScript takes >> inheritance into account and there are thousands more than a Object.assign >> call here and there. >> >> But what's bugging me every time more, is that somebody had a very bad >> idea to spread `Object.assign` as something good for inheritance or object >> cloning. >> >> Where does this come from? `Object.assign` retrieves properties and >> ignore getters and setters, is the last tool you want to use as >> substitution principle because it breaks. >> >> >> Ignores getters? You mean merely reads them? That’s not ignoring. Getters >> are an implementation detail of an interface. >> Prototypes aren't only useful for sharing behavior. They’re just as >> useful for *data objects and value types*. Nothing breaks when you clone >> or assign them around. >> >> Object.assign just read properties from one object and assign them to >> another. Something you used to do by hand. It’s just shorter to type >> assign(A, B) than type all properties of B out manually. If it’s _not_ >> meant to be the function-equivalent of `*for (var key in source) >> target[key] = source[key]*` then that’s too bad as my money is on it’s >> going to be used as such. I definitely want to use it for that. >> >> But what's bugging me every time more, is that somebody had a very bad >> idea to spread `Object.assign` as something good for inheritance or object >> cloning. >> >> Are you dealing with prototypes and `Object.assign` ? You gonna have way >> more problems than a missed flattered structure. >> Can you explain what is your goal ? Wouldn't this work? >> >> >> Inheritance? Inheritance is an implementation detail. A function >> receiving an object must not care about its inheritance tree as long as it >> fulfills the required interface. That’s what the LSP says as well. Even >> though JavaScript has no explicit concept of interfaces or types, they’re >> implicit in any function call. >> >> My goal is to save people from having to think every time they call a >> function whether this 3rd party function ignores inherited properties or >> not. If the callee uses Object.assign, it strips them out, if not, the >> dot-operator takes it into account. Surely no-one’s expecting everyone to >> prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) && >> obj.name <http://obj.name/>`*. Why do it in Object.assigns then is >> beyond me. Inconsistent and uncalled for. >> >> A. >> >> On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> >> wrote: >> >> You are talking about "flatting" all properties, which is an undesired >> overhead. >> >> ```js >> >> var b = Object.create( >> Object.getPrototypeOf(a) >> ); >> >> Object.assign(b, a); >> >> ``` >> >> But what's bugging me every time more, is that somebody had a very bad >> idea to spread `Object.assign` as something good for inheritance or object >> cloning. >> >> Where does this come from? `Object.assign` retrieves properties and >> ignore getters and setters, is the last tool you want to use as >> substitution principle because it breaks. >> >> `Object.assign` is good only to define enumerable, writable, and >> configurable properties, like configuration or setup objects. >> >> Are you dealing with prototypes and `Object.assign` ? You gonna have way >> more problems than a missed flattered structure. >> >> Can you explain what is your goal ? Wouldn't this work? >> >> ```js >> >> var a = {}; // or anything else >> >> var b = Object.create( >> Object.getPrototypeOf(a) >> ); >> >> Object.getOwnPropertyNames(a).forEach(function (k) { >> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >> }); >> >> ``` >> >> >> Best Regards >> >> >> >> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >> >>> Hello, >>> >>> Why does Object.assign ignore inherited enumerable properties? >>> What is the problem to which ignoring inherited properties is the >>> solution to? >>> >>> All I can see is that it prevents a useful use of inheritance. The Liskov >>> substitution principle >>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >>> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>> >>> - Everyone who’s messing with Object.prototype has to do it an >>> non-enumerable style anyway. >>> - Most uses of Object.assign will likely be for objects with a finite >>> number of keys. Those form specific and implicit types from which people >>> are likely to read with the dot-operator. That takes inheritance into >>> account anyway. >>> >>> I don’t get the agenda to mess with object inheritance. If one wants >>> methods to only be in the parent and data on the child (so Object.assign >>> would only copy data), use a classical language. In a delegation-prototypal >>> language one should be able to inherit freely because of LSP >>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >>> >>> Andri >>> >>> _______________________________________________ >>> 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/20150227/fcb18c48/attachment-0001.html>
ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need.
Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed Object.assign is more useful for data/record objects than for objects with behavior. Ignoring inheritance because of methods is not an argument then.
You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore.
meaning you are good to go with assign or the function I wrote for you.
Sadly not. Inheritance should not be conflicted with sharing behavior (methods). Entirely orthogonal concepts. It’s very useful to inherit from various data/record objects and pass those around. The receiver of such an object need never know there’s inheritance involved.
[ 1 ] What is the problem in accessing inherited values? If you don't want to distinguish them, just don't and use a for/in Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999
They thing to remember here is other people’s code. My code perfectly honors your inheritance chains when iterating or accessing properties. But me doing that doesn’t imply everyone else won’t use Object.assign to set up their defaults as is very convenient: person = Object.assign({name: “”, age: 0}, person)
. You think they won’t? They already do so with Object.keys when it’s entirely unnecessary for 9/10 use-cases.
You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. I am back with previous [ 1 ] question then.
Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties is an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: options = Object.assign({}, options)
.
You can define you r
toJSON
method that returns the result of the for/in based function I've written for you. Is that retarded?
I’ll leave JSON out of this discussion. Yeah, I’d like to set Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends on it serializing only own properties. Ugh.
Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering
Object.assign
But it’s not me who wants to flatten stuff. It’s the people who will write functions or APIs that use Object.assign while setting their defaults. I don’t mind them flattening, but only if they don’t lose half of the properties to inheritance stripping while doing so.
Am I explaining the problem wrong? I’m still surprised there are people who don’t find the following behavior retarded:
function logPerson(person) { console.log(“%s is from %s.”, person.name, person.country) }
function logTraveler(person) { logPerson(Object.assign({name: “Traveller”}, person)) }
var PERSON = {name: “Unnamed”, country: “Estonia"}
var john = Object.create(PERSON)
john.name = “John”
logPerson(john) // => John is from Estonia.
logTraveler(john) // => John is from undefined.
While a little contrived, like I said, Object.assign and its equivalents from libraries are already used to set defaults. Just in case: please don’t propose replacing every Object.create with Object.assign.
A.
> ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed Object.assign is more useful for data/record objects than for objects with behavior. Ignoring inheritance because of methods is not an argument then. > You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. > > meaning you are good to go with assign or the function I wrote for you. Sadly not. Inheritance should not be conflicted with sharing behavior (methods). Entirely orthogonal concepts. It’s very useful to inherit from various data/record objects and pass those around. The receiver of such an object need never know there’s inheritance involved. > [ 1 ] What is the problem in accessing inherited values? > If you don't want to distinguish them, just don't and use a for/in > Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 They thing to remember here is _other people’s code_. My code perfectly honors your inheritance chains when iterating or accessing properties. But me doing that doesn’t imply everyone else won’t use Object.assign to set up their defaults as is very convenient: `person = Object.assign({name: “”, age: 0}, person)`. You think they won’t? They already do so with Object.keys when it’s entirely unnecessary for 9/10 use-cases. > You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. > I am back with previous [ 1 ] question then. Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. > You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? I’ll leave JSON out of this discussion. Yeah, I’d like to set Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends on it serializing only own properties. Ugh. > Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. > I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` But it’s not me who wants to flatten stuff. It’s the people who will write functions or APIs that use Object.assign while setting their defaults. I don’t mind them flattening, but only if they don’t lose half of the properties to inheritance stripping while doing so. Am I explaining the problem wrong? I’m still surprised there are people who don’t find the following behavior retarded: ``` function logPerson(person) { console.log(“%s is from %s.”, person.name, person.country) } function logTraveler(person) { logPerson(Object.assign({name: “Traveller”}, person)) } var PERSON = {name: “Unnamed”, country: “Estonia"} var john = Object.create(PERSON) john.name = “John” logPerson(john) // => John is from Estonia. logTraveler(john) // => John is from undefined. ``` While a little contrived, like I said, Object.assign and its equivalents from libraries are already used to set defaults. Just in case: please don’t propose replacing every Object.create with Object.assign. A. On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > answering inline ... > > On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. > > Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? > > nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. > > > > You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. > > meaning you are good to go with assign or the function I wrote for you. > > > > > Again, I ask, what is the problem to which ignoring inherited properties is the solution to? > > > > [ 1 ] What is the problem in accessing inherited values? > > If you don't want to distinguish them, just don't and use a for/in > > Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 > > > > I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence. > > You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. > I am back with previous [ 1 ] question then. > > > > JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter. > > You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? > > Moreover, you can recreate instances at parse time with a specialized reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da > Is that retarded? ( maybe this one is :P ) > > > > And as I said below: until everyone also prefixes their obj.name uses with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that? > > actually, following your logic you should never access that unless you are sure it's also enumerable so ... > > `obj.hasOwnProperty("name") && obj.propertyIsEnumerable("name") && obj.name`` > > > > This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design. > > Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. > > I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` > > Best Regards > > > > > A. > > On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > >> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >> >> If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in >> >> ``` >> function flatEnumerables(a) { >> for (var c, k, i = 1; i < arguments.length; i++) { >> for (k in (c = arguments[i])) a[k] = c[k]; >> } >> return a; >> } >> ``` >> This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) >> >> Would that work? >> >> Best Regards >> >> >> >> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>> You are talking about "flatting" all properties, which is an undesired overhead. >> >> Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. >> >>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>> >>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >> >> >> Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. >> Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. >> >> Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. >> >>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >> >>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>> Can you explain what is your goal ? Wouldn't this work? >> >> Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. >> >> My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. >> >> A. >> >> On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >> >>> You are talking about "flatting" all properties, which is an undesired overhead. >>> >>> ```js >>> >>> var b = Object.create( >>> Object.getPrototypeOf(a) >>> ); >>> >>> Object.assign(b, a); >>> >>> ``` >>> >>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>> >>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>> >>> `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. >>> >>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>> >>> Can you explain what is your goal ? Wouldn't this work? >>> >>> ```js >>> >>> var a = {}; // or anything else >>> >>> var b = Object.create( >>> Object.getPrototypeOf(a) >>> ); >>> >>> Object.getOwnPropertyNames(a).forEach(function (k) { >>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>> }); >>> >>> ``` >>> >>> >>> Best Regards >>> >>> >>> >>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>> Hello, >>> >>> Why does Object.assign ignore inherited enumerable properties? >>> What is the problem to which ignoring inherited properties is the solution to? >>> >>> All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>> >>> - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. >>> - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. >>> >>> I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. >>> >>> Andri >>> >>> _______________________________________________ >>> 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/20150227/b74d139b/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/b74d139b/attachment-0001.p7s>
That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods.
Moreover, back to your ES5/3compat example, if you have a person object, you never inherit name, you always have your own name as you explicitly set "John".
You eventually inherit the surname, but that's indeed not your own so it should not be copied as such, it should stay there inherited unless you explicitly go to the inheritance office (the property descriptor officer) and ask for an own surname.
Same is for all people from Estonia, they all inherit their native country when born, they have to hide it explicitly at the same "descriptor office" in order to make them their own country.
But all this goes down to why/how/where you need to retrieve these info. That is the place you log through a for/in in order to reach all exposed (read enumerables) properties. That is where you log passing whatever it is through the function I've written.
Before? country isan accessible info, as the surname and other inherited properties eventually would be, and only if re-set on top, will become own properties.
At the end of the day, Object.assign
has been already adopted and
polyfilled and used for some time now, changing it now will probably break
all code based on it.
Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? )
Best
That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. Moreover, back to your ES5/3compat example, if you have a person object, you **never** inherit name, you always have your own name as you explicitly set "John". You eventually inherit the surname, but that's indeed not your own so it should not be copied as such, it should stay there inherited unless you explicitly go to the inheritance office (the property descriptor officer) and ask for an own surname. Same is for all people from Estonia, they all inherit their native country when born, they have to hide it explicitly at the same "descriptor office" in order to make them their own country. But all this goes down to why/how/where you need to retrieve these info. That is the place you log through a for/in in order to reach all exposed (read enumerables) properties. That is where you log passing whatever it is through the function I've written. Before? country isan accessible info, as the surname and other inherited properties eventually would be, and only if re-set on top, will become own properties. At the end of the day, `Object.assign` has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it. Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? ) Best Regards On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: > ES3 these are all enumerable, you don't want methods copied all over your > objects each time because that's the entire point of having prototypal > inheritance, right? If instead of inheriting and composing you copy > everything as enumerable, writable, and configurable, that's your choice, > not what I believe we all need. > > > Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed > Object.assign is more useful for data/record objects than for objects with > behavior. Ignoring inheritance because of methods is not an argument then. > > You yourself said one shouldn’t use Object.assign for objects with >> behavior in the inheritance chain. And I agree. It’s pretty much only >> useful for data objects (a.k.a plain). Those have no methods in the >> inheritance chain one needs to ignore. >> > > meaning you are good to go with assign or the function I wrote for you. > > > Sadly not. Inheritance should not be conflicted with sharing behavior > (methods). Entirely orthogonal concepts. It’s very useful to inherit from > various data/record objects and pass those around. The receiver of such an > object need never know there’s inheritance involved. > > [ 1 ] What is the problem in accessing inherited values? > If you don't want to distinguish them, just don't and use a for/in > Why do you want now to change Object assign instead of simply using > for/in? This requirement is available since 1999 > > > They thing to remember here is _other people’s code_. My code perfectly > honors your inheritance chains when iterating or accessing properties. But > me doing that doesn’t imply everyone else won’t use Object.assign to set up > their defaults as is very convenient: `person = Object.assign({name: “”, > age: 0}, person)`. You think they won’t? They already do so with > Object.keys when it’s entirely unnecessary for 9/10 use-cases. > > You seem to be afraid of inheritance since you want to ignore it and flat > all the properties per each copied/enriched object. > I am back with previous [ 1 ] question then. > > > Nah, I’m saying inheritance is an implementation detail of my object. It’s > none of the receiver’s/callee’s business how I implemented that particular > interface (any agreed upon set of properties _is_ an interface). But the > moment someone passes my object to Object.assign, they get the wrong > output. Even if it should’ve been a no-op: `options = Object.assign({}, > options)`. > > You can define you r`toJSON` method that returns the result of the for/in > based function I've written for you. Is that retarded? > > > I’ll leave JSON out of this discussion. Yeah, I’d like to set > Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends > on it serializing only own properties. Ugh. > > Precisely ! So use inheritance instead of flattening/hiding it > everywhere. Use dictionaries and for/in when all this does not matter. > > I really don't see, with all possibilities you have to write the way you > want, and a function I wrote for you that does what you need, why bothering > `Object.assign` > > > But it’s not me who wants to flatten stuff. It’s the people who will write > functions or APIs that use Object.assign while setting their defaults. I > don’t mind them flattening, but only if they don’t lose half of the > properties to inheritance stripping while doing so. > > Am I explaining the problem wrong? I’m still surprised there are people > who don’t find the following behavior retarded: > > ``` > function logPerson(person) { console.log(“%s is from %s.”, person.name, > person.country) } > function logTraveler(person) { logPerson(Object.assign({name: > “Traveller”}, person)) } > > var PERSON = {name: “Unnamed”, country: “Estonia"} > var john = Object.create(PERSON) > john.name = “John” > > logPerson(john) // => John is from Estonia. > logTraveler(john) // => John is from undefined. > ``` > > While a little contrived, like I said, Object.assign and its equivalents > from libraries are already used to set defaults. > Just in case: please don’t propose replacing every Object.create with > Object.assign. > > A. > > On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > answering inline ... > > On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: > >> noone? JSLint doesn't even let you write a for/in loop if you don't have >> `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >> properties (included methods from old classes/ahem prototypes) reassigned >> everywhere. >> >> >> Huh? Old prototypes? Those prototypes have their properties set as >> non-enumerable since how long now? >> > > nope, I was rather talking about user-land defined "classes" through > prototypes. in ES3 these are all enumerable, you don't want methods copied > all over your objects each time because that's the entire point of having > prototypal inheritance, right? If instead of inheriting and composing you > copy everything as enumerable, writable, and configurable, that's your > choice, not what I believe we all need. > > > > >> You yourself said one shouldn’t use Object.assign for objects with >> behavior in the inheritance chain. And I agree. It’s pretty much only >> useful for data objects (a.k.a plain). Those have no methods in the >> inheritance chain one needs to ignore. >> > > meaning you are good to go with assign or the function I wrote for you. > > > > >> >> Again, I ask, *what is the problem to which ignoring inherited >> properties is the solution to?* >> >> > > [ 1 ] What is the problem in accessing inherited values? > > If you don't want to distinguish them, just don't and use a for/in > > Why do you want now to change Object assign instead of simply using > for/in? This requirement is available since 1999 > > > > >> I posit everyone wants inherited properties. Just half of the people have >> been FUDed into being afraid of inheritance. But arguments based on >> assumptions on what other people want are irrelevant because naive people >> are easy to influence. >> > > You seem to be afraid of inheritance since you want to ignore it and flat > all the properties per each copied/enriched object. > I am back with previous [ 1 ] question then. > > > > >> JSLint is how Douglas Crockford writes his code. That’s not an argument >> for right APIs. JSON.stringify is equally retarded with its inconsistent >> handling of inheritance, but that’s another matter. >> > > You can define you r`toJSON` method that returns the result of the for/in > based function I've written for you. Is that retarded? > > Moreover, you can recreate instances at parse time with a specialized > reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da > Is that retarded? ( maybe this one is :P ) > > > >> >> And as I said below: until everyone also prefixes their obj.name uses >> with hasOwn: `*obj.hasOwnProperty(“name”) && obj.name >> <http://obj.name/>`*, skipping inherited properties is a fool’s errand. >> It causes *inconsistent APIs* because you don’t run your options et alii >> objects through inheritance strippers every time. And you shouldn’t. Or >> does anyone disagree with that? >> > > actually, following your logic you should never access that unless you are > sure it's also enumerable so ... > > `*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") && **obj.name > <http://obj.name/>`*` > > > >> >> This is a bigger problem than my use of Object.assign. Proliferation of >> Object.assign will prevent everyone else from relying on inheritance. And >> in a prototypal language I find that bad API design. >> > > Precisely ! So use inheritance instead of flattening/hiding it > everywhere. Use dictionaries and for/in when all this does not matter. > > I really don't see, with all possibilities you have to write the way you > want, and a function I wrote for you that does what you need, why bothering > `Object.assign` > > Best Regards > > > > >> >> A. >> >> On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> >> wrote: >> >> noone? JSLint doesn't even let you write a for/in loop if you don't have >> `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >> properties (included methods from old classes/ahem prototypes) reassigned >> everywhere. >> >> If you deal with data objects and dictionaries yuo'll always have a flat >> structure, right? If you don't care about properties descriptors (getters >> and setters) you can always use a for/in >> >> ``` >> function flatEnumerables(a) { >> for (var c, k, i = 1; i < arguments.length; i++) { >> for (k in (c = arguments[i])) a[k] = c[k]; >> } >> return a; >> } >> ``` >> This would do what you are looking for (which is the first time I >> personally read/hear about somebody wanting `Object.assign` to behave like >> a for/in) >> >> Would that work? >> >> Best Regards >> >> >> >> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >> >>> You are talking about "flatting" all properties, which is an undesired >>> overhead. >>> >>> >>> Umm, Object.assign is as it is because of performance? I don’t think it >>> is nor is that a good reason. Every property access in JavaScript takes >>> inheritance into account and there are thousands more than a Object.assign >>> call here and there. >>> >>> But what's bugging me every time more, is that somebody had a very bad >>> idea to spread `Object.assign` as something good for inheritance or object >>> cloning. >>> >>> Where does this come from? `Object.assign` retrieves properties and >>> ignore getters and setters, is the last tool you want to use as >>> substitution principle because it breaks. >>> >>> >>> Ignores getters? You mean merely reads them? That’s not ignoring. >>> Getters are an implementation detail of an interface. >>> Prototypes aren't only useful for sharing behavior. They’re just as >>> useful for *data objects and value types*. Nothing breaks when you >>> clone or assign them around. >>> >>> Object.assign just read properties from one object and assign them to >>> another. Something you used to do by hand. It’s just shorter to type >>> assign(A, B) than type all properties of B out manually. If it’s _not_ >>> meant to be the function-equivalent of `*for (var key in source) >>> target[key] = source[key]*` then that’s too bad as my money is on it’s >>> going to be used as such. I definitely want to use it for that. >>> >>> But what's bugging me every time more, is that somebody had a very bad >>> idea to spread `Object.assign` as something good for inheritance or object >>> cloning. >>> >>> Are you dealing with prototypes and `Object.assign` ? You gonna have way >>> more problems than a missed flattered structure. >>> Can you explain what is your goal ? Wouldn't this work? >>> >>> >>> Inheritance? Inheritance is an implementation detail. A function >>> receiving an object must not care about its inheritance tree as long as it >>> fulfills the required interface. That’s what the LSP says as well. Even >>> though JavaScript has no explicit concept of interfaces or types, they’re >>> implicit in any function call. >>> >>> My goal is to save people from having to think every time they call a >>> function whether this 3rd party function ignores inherited properties or >>> not. If the callee uses Object.assign, it strips them out, if not, the >>> dot-operator takes it into account. Surely no-one’s expecting everyone to >>> prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) >>> && obj.name <http://obj.name/>`*. Why do it in Object.assigns then is >>> beyond me. Inconsistent and uncalled for. >>> >>> A. >>> >>> On Feb 27, 2015, at 14:24, Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>> You are talking about "flatting" all properties, which is an undesired >>> overhead. >>> >>> ```js >>> >>> var b = Object.create( >>> Object.getPrototypeOf(a) >>> ); >>> >>> Object.assign(b, a); >>> >>> ``` >>> >>> But what's bugging me every time more, is that somebody had a very bad >>> idea to spread `Object.assign` as something good for inheritance or object >>> cloning. >>> >>> Where does this come from? `Object.assign` retrieves properties and >>> ignore getters and setters, is the last tool you want to use as >>> substitution principle because it breaks. >>> >>> `Object.assign` is good only to define enumerable, writable, and >>> configurable properties, like configuration or setup objects. >>> >>> Are you dealing with prototypes and `Object.assign` ? You gonna have way >>> more problems than a missed flattered structure. >>> >>> Can you explain what is your goal ? Wouldn't this work? >>> >>> ```js >>> >>> var a = {}; // or anything else >>> >>> var b = Object.create( >>> Object.getPrototypeOf(a) >>> ); >>> >>> Object.getOwnPropertyNames(a).forEach(function (k) { >>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>> }); >>> >>> ``` >>> >>> >>> Best Regards >>> >>> >>> >>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>> >>>> Hello, >>>> >>>> Why does Object.assign ignore inherited enumerable properties? >>>> What is the problem to which ignoring inherited properties is the >>>> solution to? >>>> >>>> All I can see is that it prevents a useful use of inheritance. The Liskov >>>> substitution principle >>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >>>> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>> >>>> - Everyone who’s messing with Object.prototype has to do it an >>>> non-enumerable style anyway. >>>> - Most uses of Object.assign will likely be for objects with a finite >>>> number of keys. Those form specific and implicit types from which people >>>> are likely to read with the dot-operator. That takes inheritance into >>>> account anyway. >>>> >>>> I don’t get the agenda to mess with object inheritance. If one wants >>>> methods to only be in the parent and data on the child (so Object.assign >>>> would only copy data), use a classical language. In a delegation-prototypal >>>> language one should be able to inherit freely because of LSP >>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >>>> >>>> Andri >>>> >>>> _______________________________________________ >>>> 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/20150227/5e1ee01d/attachment-0001.html>
That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods.
Classes are just syntactic sugar over prototypes after all. I’m definitely going to continue promoting use of plain old prototypical approaches in addition to that because they're simple and elegant: why waste computation power in constructors when you can do so once on the prototype. I find that an advantage of prototypal languages over classical ones.
A bit of a plug in this regard, check out this simple observable implementation that supports inheritance: moll/js-concert Boy does this save computation. No need to bind listeners for every object (e.g. domain model) instance: Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t it? ;-)
At the end of the day,
Object.assign
has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it.
Well, that didn’t seem to prevent changing class method enumerability just a little time ago.
That is where you log passing whatever it is through the function I've written.
Sweet story you made out of the example. :-) Coming back to non-prose for a sec, unless you get everyone to ignore Object.assign and use your function, there’s no point in proposing your functions. That’s what I’ve now repeated plenty of times. It’s going to hurt us prototype-uses because others will use Object.assign where they need not.
Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? )
Umm, that was already explained by Leon Arnott’s email: Object.assign is cowpath pavement. Everyone seems to like a for-in assignment helper. Two of most popular assign/extend implementation mentioned (jQuery, Underscore) have supported inheritance for at least 7 years. Do you not find that as evidence “from the field"?
Or am I preaching to the choir? Are you personally already in favor of supporting inheritance in Object.assign? Given what I’ve read from you so far you won’t be affected by it as it seems to me you prefer to use this prototypal language in a classical way.
A.
> That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. Classes are just syntactic sugar over prototypes after all. I’m definitely going to continue promoting use of plain old prototypical approaches in addition to that because they're simple and elegant: why waste computation power in constructors when you can do so once on the prototype. I find that an advantage of prototypal languages over classical ones. A bit of a plug in this regard, check out this simple observable implementation that supports inheritance: https://github.com/moll/js-concert Boy does this save computation. No need to bind listeners for every object (e.g. domain model) instance: Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t it? ;-) > At the end of the day, `Object.assign` has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it. Well, that didn’t seem to prevent changing class method enumerability just a little time ago. > That is where you log passing whatever it is through the function I've written. Sweet story you made out of the example. :-) Coming back to non-prose for a sec, unless you get everyone to ignore Object.assign and use your function, there’s no point in proposing your functions. That’s what I’ve now repeated plenty of times. It’s going to hurt _us_ prototype-uses because _others_ will use Object.assign where they need not. > Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? ) Umm, that was already explained by Leon Arnott’s email: Object.assign is cowpath pavement. Everyone seems to like a for-in assignment helper. Two of most popular assign/extend implementation mentioned (jQuery, Underscore) have supported inheritance for _at least_ 7 years. Do you not find that as evidence “from the field"? Or am I preaching to the choir? Are you personally already in favor of supporting inheritance in Object.assign? Given what I’ve read from you so far you won’t be affected by it as it seems to me you prefer to use this prototypal language in a classical way. A. On Feb 27, 2015, at 19:51, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. > > Moreover, back to your ES5/3compat example, if you have a person object, you **never** inherit name, you always have your own name as you explicitly set "John". > > You eventually inherit the surname, but that's indeed not your own so it should not be copied as such, it should stay there inherited unless you explicitly go to the inheritance office (the property descriptor officer) and ask for an own surname. > > Same is for all people from Estonia, they all inherit their native country when born, they have to hide it explicitly at the same "descriptor office" in order to make them their own country. > > But all this goes down to why/how/where you need to retrieve these info. That is the place you log through a for/in in order to reach all exposed (read enumerables) properties. > That is where you log passing whatever it is through the function I've written. > > Before? country isan accessible info, as the surname and other inherited properties eventually would be, and only if re-set on top, will become own properties. > > At the end of the day, `Object.assign` has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it. > > Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? ) > > Best Regards > > > On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: >> ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. > > Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed Object.assign is more useful for data/record objects than for objects with behavior. Ignoring inheritance because of methods is not an argument then. > >> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >> >> meaning you are good to go with assign or the function I wrote for you. > > > Sadly not. Inheritance should not be conflicted with sharing behavior (methods). Entirely orthogonal concepts. It’s very useful to inherit from various data/record objects and pass those around. The receiver of such an object need never know there’s inheritance involved. > >> [ 1 ] What is the problem in accessing inherited values? >> If you don't want to distinguish them, just don't and use a for/in >> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 > > They thing to remember here is _other people’s code_. My code perfectly honors your inheritance chains when iterating or accessing properties. But me doing that doesn’t imply everyone else won’t use Object.assign to set up their defaults as is very convenient: `person = Object.assign({name: “”, age: 0}, person)`. You think they won’t? They already do so with Object.keys when it’s entirely unnecessary for 9/10 use-cases. > >> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >> I am back with previous [ 1 ] question then. > > > Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. > >> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? > > > I’ll leave JSON out of this discussion. Yeah, I’d like to set Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends on it serializing only own properties. Ugh. > >> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. > >> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` > > > But it’s not me who wants to flatten stuff. It’s the people who will write functions or APIs that use Object.assign while setting their defaults. I don’t mind them flattening, but only if they don’t lose half of the properties to inheritance stripping while doing so. > > Am I explaining the problem wrong? I’m still surprised there are people who don’t find the following behavior retarded: > > ``` > function logPerson(person) { console.log(“%s is from %s.”, person.name, person.country) } > function logTraveler(person) { logPerson(Object.assign({name: “Traveller”}, person)) } > > var PERSON = {name: “Unnamed”, country: “Estonia"} > var john = Object.create(PERSON) > john.name = “John” > > logPerson(john) // => John is from Estonia. > logTraveler(john) // => John is from undefined. > ``` > > While a little contrived, like I said, Object.assign and its equivalents from libraries are already used to set defaults. > Just in case: please don’t propose replacing every Object.create with Object.assign. > > A. > > On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > >> answering inline ... >> >> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >> >> Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? >> >> nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. >> >> >> >> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >> >> meaning you are good to go with assign or the function I wrote for you. >> >> >> >> >> Again, I ask, what is the problem to which ignoring inherited properties is the solution to? >> >> >> >> [ 1 ] What is the problem in accessing inherited values? >> >> If you don't want to distinguish them, just don't and use a for/in >> >> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 >> >> >> >> I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence. >> >> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >> I am back with previous [ 1 ] question then. >> >> >> >> JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter. >> >> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? >> >> Moreover, you can recreate instances at parse time with a specialized reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >> Is that retarded? ( maybe this one is :P ) >> >> >> >> And as I said below: until everyone also prefixes their obj.name uses with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that? >> >> actually, following your logic you should never access that unless you are sure it's also enumerable so ... >> >> `obj.hasOwnProperty("name") && obj.propertyIsEnumerable("name") && obj.name`` >> >> >> >> This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design. >> >> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. >> >> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` >> >> Best Regards >> >> >> >> >> A. >> >> On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >> >>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >>> >>> If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in >>> >>> ``` >>> function flatEnumerables(a) { >>> for (var c, k, i = 1; i < arguments.length; i++) { >>> for (k in (c = arguments[i])) a[k] = c[k]; >>> } >>> return a; >>> } >>> ``` >>> This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) >>> >>> Would that work? >>> >>> Best Regards >>> >>> >>> >>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>>> You are talking about "flatting" all properties, which is an undesired overhead. >>> >>> Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. >>> >>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>> >>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>> >>> >>> Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. >>> Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. >>> >>> Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. >>> >>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>> >>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>> Can you explain what is your goal ? Wouldn't this work? >>> >>> Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. >>> >>> My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. >>> >>> A. >>> >>> On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>> >>>> You are talking about "flatting" all properties, which is an undesired overhead. >>>> >>>> ```js >>>> >>>> var b = Object.create( >>>> Object.getPrototypeOf(a) >>>> ); >>>> >>>> Object.assign(b, a); >>>> >>>> ``` >>>> >>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>> >>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>>> >>>> `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. >>>> >>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>> >>>> Can you explain what is your goal ? Wouldn't this work? >>>> >>>> ```js >>>> >>>> var a = {}; // or anything else >>>> >>>> var b = Object.create( >>>> Object.getPrototypeOf(a) >>>> ); >>>> >>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>> }); >>>> >>>> ``` >>>> >>>> >>>> Best Regards >>>> >>>> >>>> >>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>> Hello, >>>> >>>> Why does Object.assign ignore inherited enumerable properties? >>>> What is the problem to which ignoring inherited properties is the solution to? >>>> >>>> All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>> >>>> - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. >>>> - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. >>>> >>>> I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. >>>> >>>> Andri >>>> >>>> _______________________________________________ >>>> 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/20150227/15221557/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/15221557/attachment-0001.p7s>
FWIW I do like prototypal inheritance ... but ...
On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote:
That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods.
Classes are just syntactic sugar over prototypes after all.
except finally these behave like natives always have: non enumerable methods / accessors ... those that even you said don't want on your way
I’m definitely going to continue promoting use of plain old prototypical approaches in addition to that because they're simple and elegant:
objects will still be used for composing and whenever you
Object.create(Object.getPrototypeOf(other))
you are still using
prototypal inheritance.
None of this has ever been solved in Object.assign
though ...
why waste computation power in constructors when you can do so once on the prototype.
'cause 99% of the time you need to initialize your PERSON with a name
property, as example ... do that in the object creation through an implicit
initializer as constructor is: done!
I find that an advantage of prototypal languages over classical ones.
I guess you like init
methods too then
A bit of a plug in this regard, check out this simple observable implementation that supports inheritance: moll/js-concert Boy does this save computation. No need to bind listeners for every object (e.g. domain model) instance: Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t it? ;-)
Check what DOM offered since about ever: EventListener interface: www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener
You inherit this:
class EventListener {
handleEvent(e) {
var type = 'on' + e.type;
if (type in this) this[type](e);
}
}
And BOOM, every class inheriting that will be able to create instances usable as handlers, no need bind listeners to anything anymore!
class DaClicker extends EventListener {
constructor(el) {
el.addEventListener('click', this);
}
onclick(e) {
alert([e.type, this instanceof DaClicker]);
}
}
var driver = new DaClicker(document);
How cool is that? Now, let's go back to Object.assign
...
Well, that didn’t seem to prevent changing class method enumerability just
a little time ago.
and didn't affect Object.assign
behavior ... we all agreed here
enumerability had to be changed in order to be consistent with native
classes and be able to extend them without causing unexpected behaviors ...
it was the last window before breaking classes forever, while
Object.assign
is a method based on old ES3 concepts that has not much to
do with ES6 and that was never meant to be used to extend objects. It's the
wrong tool for the job, accessors are lost in the process, and everything
else is ignored, including inheritance.
Sweet story you made out of the example. :-) Coming back to non-prose for a sec, unless you get everyone to ignore Object.assign and use your function, there’s no point in proposing your functions. That’s what I’ve now repeated plenty of times. It’s going to hurt us prototype-uses because others will use Object.assign where they need not.
There's no point in proposing Object.assign
to deal with inheritance,
prototypal inheritance, and de-facto extend ability. Object.assing
has
one well defined use case: copy own enumerable properties, that's it ...
really ... that's just it. Good for setup or config options, nothing
else!
Umm, that was already explained by Leon Arnott’s email: Object.assign is cowpath pavement. Everyone seems to like a for-in assignment helper. Two of most popular assign/extend implementation mentioned (jQuery, Underscore) have supported inheritance for at least 7 years. Do you not find that as evidence “from the field"?
common extend do not loop over inherited properties, if these do is because
these were written in an era where Object.getPrototypeOf
and
Object.setPrototypeOf
where missing.
You talked about computation power and you want to loop over everything per
each Object.assign
call ... I am sorry I don't follow you anymore here!
Or am I preaching to the choir? Are you personally already in favor of supporting inheritance in Object.assign?
Object.assign
has nothing to do with inheritance, that's what I am
saying, not just supporting.
Given what I’ve read from you so far you won’t be affected by it as it seems to me you prefer to use this prototypal language in a classical way.
No, I do like prototypal inheritance and I love the fact it's still the root of JS inheritance.
What is my personal position here is that Object.assign
is the wrong
method/tool/function to do anything prototypal or classical inheritance
related.
Developers should understand it, and I am realizing they don't ... like not at all!
Best
FWIW I do like prototypal inheritance ... but ... On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote: > That is not what people relying in Object.assign and ES6 will write, > because you cannot define properties in a generic class, only methods. > > > Classes are just syntactic sugar over prototypes after all. > except finally these behave like natives always have: non enumerable methods / accessors ... those that even you said don't want on your way > I’m definitely going to continue promoting use of plain old prototypical > approaches in addition to that because they're simple and elegant: > objects will still be used for composing and whenever you `Object.create(Object.getPrototypeOf(other))` you are still using prototypal inheritance. None of this has ever been solved in `Object.assign` though ... > why waste computation power in constructors when you can do so once on the > prototype. > 'cause 99% of the time you need to initialize your PERSON with a `name` property, as example ... do that in the object creation through an implicit initializer as constructor is: done! > I find that an advantage of prototypal languages over classical ones. > I guess you like `init` methods too then > > A bit of a plug in this regard, check out this simple observable > implementation that supports inheritance: > https://github.com/moll/js-concert > Boy does this save computation. No need to bind listeners for every object > (e.g. domain model) instance: > Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t > it? ;-) > Check what DOM offered since about ever: EventListener interface: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener You inherit this: ```js class EventListener { handleEvent(e) { var type = 'on' + e.type; if (type in this) this[type](e); } } ``` And BOOM, every class inheriting that will be able to create instances usable as handlers, no need bind listeners to anything anymore! ```js class DaClicker extends EventListener { constructor(el) { el.addEventListener('click', this); } onclick(e) { alert([e.type, this instanceof DaClicker]); } } var driver = new DaClicker(document); ``` How cool is that? Now, let's go back to `Object.assign` ... Well, that didn’t seem to prevent changing class method enumerability just > a little time ago. > and didn't affect `Object.assign` behavior ... we all agreed here enumerability had to be changed in order to be consistent with native classes and be able to extend them without causing unexpected behaviors ... it was the last window before breaking classes forever, while `Object.assign` is a method based on old ES3 concepts that has not much to do with ES6 and that was never meant to be used to extend objects. It's the wrong tool for the job, accessors are lost in the process, and everything else is ignored, including inheritance. > Sweet story you made out of the example. :-) Coming back to non-prose for > a sec, unless you get everyone to ignore Object.assign and use your > function, there’s no point in proposing your functions. That’s what I’ve > now repeated plenty of times. It’s going to hurt _us_ prototype-uses > because _others_ will use Object.assign where they need not. > There's no point in proposing `Object.assign` to deal with inheritance, prototypal inheritance, and de-facto extend ability. `Object.assing` has one well defined use case: copy own enumerable properties, that's it ... **really** ... that's just it. Good for setup or config options, nothing else! > Umm, that was already explained by Leon Arnott’s email: Object.assign is > cowpath pavement. Everyone seems to like a for-in assignment helper. Two of > most popular assign/extend implementation mentioned (jQuery, Underscore) > have supported inheritance for _at least_ 7 years. Do you not find that as > evidence “from the field"? > common extend do not loop over inherited properties, if these do is because these were written in an era where `Object.getPrototypeOf` and `Object.setPrototypeOf` where missing. You talked about computation power and you want to loop over everything per each `Object.assign` call ... I am sorry I don't follow you anymore here! > > Or am I preaching to the choir? Are you personally already in favor of > supporting inheritance in Object.assign? > `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. > Given what I’ve read from you so far you won’t be affected by it as it > seems to me you prefer to use this prototypal language in a classical way. > No, I do like prototypal inheritance and I love the fact it's still the root of JS inheritance. What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. Developers should understand it, and I am realizing they don't ... like not at all! Best Regards > > A. > > On Feb 27, 2015, at 19:51, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > That is not what people relying in Object.assign and ES6 will write, > because you cannot define properties in a generic class, only methods. > > Moreover, back to your ES5/3compat example, if you have a person object, > you **never** inherit name, you always have your own name as you explicitly > set "John". > > You eventually inherit the surname, but that's indeed not your own so it > should not be copied as such, it should stay there inherited unless you > explicitly go to the inheritance office (the property descriptor officer) > and ask for an own surname. > > Same is for all people from Estonia, they all inherit their native country > when born, they have to hide it explicitly at the same "descriptor office" > in order to make them their own country. > > But all this goes down to why/how/where you need to retrieve these info. > That is the place you log through a for/in in order to reach all exposed > (read enumerables) properties. > That is where you log passing whatever it is through the function I've > written. > > Before? country isan accessible info, as the surname and other inherited > properties eventually would be, and only if re-set on top, will become own > properties. > > At the end of the day, `Object.assign` has been already adopted and > polyfilled and used for some time now, changing it now will probably break > all code based on it. > > Again, I think this is the first time I hear someone wanting a new method > being exactly like a for/in ... use for/in if that's what you need ( KISS ? > ) > > Best Regards > > > On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: > >> ES3 these are all enumerable, you don't want methods copied all over your >> objects each time because that's the entire point of having prototypal >> inheritance, right? If instead of inheriting and composing you copy >> everything as enumerable, writable, and configurable, that's your choice, >> not what I believe we all need. >> >> >> Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed >> Object.assign is more useful for data/record objects than for objects with >> behavior. Ignoring inheritance because of methods is not an argument then. >> >> You yourself said one shouldn’t use Object.assign for objects with >>> behavior in the inheritance chain. And I agree. It’s pretty much only >>> useful for data objects (a.k.a plain). Those have no methods in the >>> inheritance chain one needs to ignore. >>> >> >> meaning you are good to go with assign or the function I wrote for you. >> >> >> Sadly not. Inheritance should not be conflicted with sharing behavior >> (methods). Entirely orthogonal concepts. It’s very useful to inherit from >> various data/record objects and pass those around. The receiver of such an >> object need never know there’s inheritance involved. >> >> [ 1 ] What is the problem in accessing inherited values? >> If you don't want to distinguish them, just don't and use a for/in >> Why do you want now to change Object assign instead of simply using >> for/in? This requirement is available since 1999 >> >> >> They thing to remember here is _other people’s code_. My code perfectly >> honors your inheritance chains when iterating or accessing properties. But >> me doing that doesn’t imply everyone else won’t use Object.assign to set up >> their defaults as is very convenient: `person = Object.assign({name: “”, >> age: 0}, person)`. You think they won’t? They already do so with >> Object.keys when it’s entirely unnecessary for 9/10 use-cases. >> >> You seem to be afraid of inheritance since you want to ignore it and flat >> all the properties per each copied/enriched object. >> I am back with previous [ 1 ] question then. >> >> >> Nah, I’m saying inheritance is an implementation detail of my object. >> It’s none of the receiver’s/callee’s business how I implemented that >> particular interface (any agreed upon set of properties _is_ an interface). >> But the moment someone passes my object to Object.assign, they get the >> wrong output. Even if it should’ve been a no-op: `options = >> Object.assign({}, options)`. >> >> You can define you r`toJSON` method that returns the result of the for/in >> based function I've written for you. Is that retarded? >> >> >> I’ll leave JSON out of this discussion. Yeah, I’d like to set >> Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends >> on it serializing only own properties. Ugh. >> >> Precisely ! So use inheritance instead of flattening/hiding it >> everywhere. Use dictionaries and for/in when all this does not matter. >> >> I really don't see, with all possibilities you have to write the way you >> want, and a function I wrote for you that does what you need, why bothering >> `Object.assign` >> >> >> But it’s not me who wants to flatten stuff. It’s the people who will >> write functions or APIs that use Object.assign while setting their >> defaults. I don’t mind them flattening, but only if they don’t lose half of >> the properties to inheritance stripping while doing so. >> >> Am I explaining the problem wrong? I’m still surprised there are people >> who don’t find the following behavior retarded: >> >> ``` >> function logPerson(person) { console.log(“%s is from %s.”, person.name, >> person.country) } >> function logTraveler(person) { logPerson(Object.assign({name: >> “Traveller”}, person)) } >> >> var PERSON = {name: “Unnamed”, country: “Estonia"} >> var john = Object.create(PERSON) >> john.name = “John” >> >> logPerson(john) // => John is from Estonia. >> logTraveler(john) // => John is from undefined. >> ``` >> >> While a little contrived, like I said, Object.assign and its equivalents >> from libraries are already used to set defaults. >> Just in case: please don’t propose replacing every Object.create with >> Object.assign. >> >> A. >> >> On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> >> wrote: >> >> answering inline ... >> >> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >> >>> noone? JSLint doesn't even let you write a for/in loop if you don't have >>> `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>> properties (included methods from old classes/ahem prototypes) reassigned >>> everywhere. >>> >>> >>> Huh? Old prototypes? Those prototypes have their properties set as >>> non-enumerable since how long now? >>> >> >> nope, I was rather talking about user-land defined "classes" through >> prototypes. in ES3 these are all enumerable, you don't want methods copied >> all over your objects each time because that's the entire point of having >> prototypal inheritance, right? If instead of inheriting and composing you >> copy everything as enumerable, writable, and configurable, that's your >> choice, not what I believe we all need. >> >> >> >> >>> You yourself said one shouldn’t use Object.assign for objects with >>> behavior in the inheritance chain. And I agree. It’s pretty much only >>> useful for data objects (a.k.a plain). Those have no methods in the >>> inheritance chain one needs to ignore. >>> >> >> meaning you are good to go with assign or the function I wrote for you. >> >> >> >> >>> >>> Again, I ask, *what is the problem to which ignoring inherited >>> properties is the solution to?* >>> >>> >> >> [ 1 ] What is the problem in accessing inherited values? >> >> If you don't want to distinguish them, just don't and use a for/in >> >> Why do you want now to change Object assign instead of simply using >> for/in? This requirement is available since 1999 >> >> >> >> >>> I posit everyone wants inherited properties. Just half of the people >>> have been FUDed into being afraid of inheritance. But arguments based on >>> assumptions on what other people want are irrelevant because naive people >>> are easy to influence. >>> >> >> You seem to be afraid of inheritance since you want to ignore it and flat >> all the properties per each copied/enriched object. >> I am back with previous [ 1 ] question then. >> >> >> >> >>> JSLint is how Douglas Crockford writes his code. That’s not an argument >>> for right APIs. JSON.stringify is equally retarded with its inconsistent >>> handling of inheritance, but that’s another matter. >>> >> >> You can define you r`toJSON` method that returns the result of the for/in >> based function I've written for you. Is that retarded? >> >> Moreover, you can recreate instances at parse time with a specialized >> reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >> Is that retarded? ( maybe this one is :P ) >> >> >> >>> >>> And as I said below: until everyone also prefixes their obj.name uses >>> with hasOwn: `*obj.hasOwnProperty(“name”) && obj.name >>> <http://obj.name/>`*, skipping inherited properties is a fool’s errand. >>> It causes *inconsistent APIs* because you don’t run your options et >>> alii objects through inheritance strippers every time. And you shouldn’t. >>> Or does anyone disagree with that? >>> >> >> actually, following your logic you should never access that unless you >> are sure it's also enumerable so ... >> >> `*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") && **obj.name >> <http://obj.name/>`*` >> >> >> >>> >>> This is a bigger problem than my use of Object.assign. Proliferation of >>> Object.assign will prevent everyone else from relying on inheritance. And >>> in a prototypal language I find that bad API design. >>> >> >> Precisely ! So use inheritance instead of flattening/hiding it >> everywhere. Use dictionaries and for/in when all this does not matter. >> >> I really don't see, with all possibilities you have to write the way you >> want, and a function I wrote for you that does what you need, why bothering >> `Object.assign` >> >> Best Regards >> >> >> >> >>> >>> A. >>> >>> On Feb 27, 2015, at 15:40, Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>> noone? JSLint doesn't even let you write a for/in loop if you don't have >>> `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>> properties (included methods from old classes/ahem prototypes) reassigned >>> everywhere. >>> >>> If you deal with data objects and dictionaries yuo'll always have a flat >>> structure, right? If you don't care about properties descriptors (getters >>> and setters) you can always use a for/in >>> >>> ``` >>> function flatEnumerables(a) { >>> for (var c, k, i = 1; i < arguments.length; i++) { >>> for (k in (c = arguments[i])) a[k] = c[k]; >>> } >>> return a; >>> } >>> ``` >>> This would do what you are looking for (which is the first time I >>> personally read/hear about somebody wanting `Object.assign` to behave like >>> a for/in) >>> >>> Would that work? >>> >>> Best Regards >>> >>> >>> >>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>> >>>> You are talking about "flatting" all properties, which is an undesired >>>> overhead. >>>> >>>> >>>> Umm, Object.assign is as it is because of performance? I don’t think it >>>> is nor is that a good reason. Every property access in JavaScript takes >>>> inheritance into account and there are thousands more than a Object.assign >>>> call here and there. >>>> >>>> But what's bugging me every time more, is that somebody had a very bad >>>> idea to spread `Object.assign` as something good for inheritance or object >>>> cloning. >>>> >>>> Where does this come from? `Object.assign` retrieves properties and >>>> ignore getters and setters, is the last tool you want to use as >>>> substitution principle because it breaks. >>>> >>>> >>>> Ignores getters? You mean merely reads them? That’s not ignoring. >>>> Getters are an implementation detail of an interface. >>>> Prototypes aren't only useful for sharing behavior. They’re just as >>>> useful for *data objects and value types*. Nothing breaks when you >>>> clone or assign them around. >>>> >>>> Object.assign just read properties from one object and assign them to >>>> another. Something you used to do by hand. It’s just shorter to type >>>> assign(A, B) than type all properties of B out manually. If it’s _not_ >>>> meant to be the function-equivalent of `*for (var key in source) >>>> target[key] = source[key]*` then that’s too bad as my money is on it’s >>>> going to be used as such. I definitely want to use it for that. >>>> >>>> But what's bugging me every time more, is that somebody had a very bad >>>> idea to spread `Object.assign` as something good for inheritance or object >>>> cloning. >>>> >>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>> way more problems than a missed flattered structure. >>>> Can you explain what is your goal ? Wouldn't this work? >>>> >>>> >>>> Inheritance? Inheritance is an implementation detail. A function >>>> receiving an object must not care about its inheritance tree as long as it >>>> fulfills the required interface. That’s what the LSP says as well. Even >>>> though JavaScript has no explicit concept of interfaces or types, they’re >>>> implicit in any function call. >>>> >>>> My goal is to save people from having to think every time they call a >>>> function whether this 3rd party function ignores inherited properties or >>>> not. If the callee uses Object.assign, it strips them out, if not, the >>>> dot-operator takes it into account. Surely no-one’s expecting everyone to >>>> prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) >>>> && obj.name <http://obj.name/>`*. Why do it in Object.assigns then is >>>> beyond me. Inconsistent and uncalled for. >>>> >>>> A. >>>> >>>> On Feb 27, 2015, at 14:24, Andrea Giammarchi < >>>> andrea.giammarchi at gmail.com> wrote: >>>> >>>> You are talking about "flatting" all properties, which is an undesired >>>> overhead. >>>> >>>> ```js >>>> >>>> var b = Object.create( >>>> Object.getPrototypeOf(a) >>>> ); >>>> >>>> Object.assign(b, a); >>>> >>>> ``` >>>> >>>> But what's bugging me every time more, is that somebody had a very bad >>>> idea to spread `Object.assign` as something good for inheritance or object >>>> cloning. >>>> >>>> Where does this come from? `Object.assign` retrieves properties and >>>> ignore getters and setters, is the last tool you want to use as >>>> substitution principle because it breaks. >>>> >>>> `Object.assign` is good only to define enumerable, writable, and >>>> configurable properties, like configuration or setup objects. >>>> >>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>> way more problems than a missed flattered structure. >>>> >>>> Can you explain what is your goal ? Wouldn't this work? >>>> >>>> ```js >>>> >>>> var a = {}; // or anything else >>>> >>>> var b = Object.create( >>>> Object.getPrototypeOf(a) >>>> ); >>>> >>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>> }); >>>> >>>> ``` >>>> >>>> >>>> Best Regards >>>> >>>> >>>> >>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>> >>>>> Hello, >>>>> >>>>> Why does Object.assign ignore inherited enumerable properties? >>>>> What is the problem to which ignoring inherited properties is the >>>>> solution to? >>>>> >>>>> All I can see is that it prevents a useful use of inheritance. The Liskov >>>>> substitution principle >>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >>>>> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>>> >>>>> - Everyone who’s messing with Object.prototype has to do it an >>>>> non-enumerable style anyway. >>>>> - Most uses of Object.assign will likely be for objects with a finite >>>>> number of keys. Those form specific and implicit types from which people >>>>> are likely to read with the dot-operator. That takes inheritance into >>>>> account anyway. >>>>> >>>>> I don’t get the agenda to mess with object inheritance. If one wants >>>>> methods to only be in the parent and data on the child (so Object.assign >>>>> would only copy data), use a classical language. In a delegation-prototypal >>>>> language one should be able to inherit freely because of LSP >>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >>>>> >>>>> Andri >>>>> >>>>> _______________________________________________ >>>>> 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/20150227/d4de54e3/attachment-0001.html>
Object.assign
has nothing to do with inheritance, that's what I am saying, not just supporting. What is my personal position here is thatObject.assign
is the wrong method/tool/function to do anything prototypal or classical inheritance related.
Are we entirely missing each other? I’ve said a few times now: it’s none of the callee’s business if I use inheritance in my options, config, setup or any other plain object (one without behavior). Object.assign must honor that.
I asked in my first email: What is the problem to which ignoring inherited properties is the solution to? If you have an argument that I haven’t refuted yet, please share.
Just search GitHub’s code for assign usage and you’ll see it fucking up inheritance all over the place. There’s even a IO.js issue for the same problem that I’m definitely going to help fix: iojs/io.js#62.
Andri Möll:
Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties is an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op:
options = Object.assign({}, options)
.Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around.
Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call.
A.
> `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. > What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. Are we entirely missing each other? I’ve said a few times now: it’s _none_ of the callee’s business if I use inheritance in my options, config, setup or any other plain object (one without behavior). Object.assign must honor that. I asked in my first email: What is the problem to which ignoring inherited properties is the solution to? If you have an argument that I haven’t refuted yet, please share. Just search GitHub’s code for assign usage and you’ll see it fucking up inheritance all over the place. There’s even a IO.js issue for the same problem that I’m definitely going to help fix: https://github.com/iojs/io.js/issues/62. Andri Möll: > Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. > > Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. > Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. > > > Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. A. On Feb 27, 2015, at 23:13, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > FWIW I do like prototypal inheritance ... but ... > > On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote: >> That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. > > Classes are just syntactic sugar over prototypes after all. > > except finally these behave like natives always have: non enumerable methods / accessors ... those that even you said don't want on your way > > > I’m definitely going to continue promoting use of plain old prototypical approaches in addition to that because they're simple and elegant: > > objects will still be used for composing and whenever you `Object.create(Object.getPrototypeOf(other))` you are still using prototypal inheritance. > > None of this has ever been solved in `Object.assign` though ... > > > why waste computation power in constructors when you can do so once on the prototype. > > 'cause 99% of the time you need to initialize your PERSON with a `name` property, as example ... do that in the object creation through an implicit initializer as constructor is: done! > > > I find that an advantage of prototypal languages over classical ones. > > I guess you like `init` methods too then > > > > > A bit of a plug in this regard, check out this simple observable implementation that supports inheritance: https://github.com/moll/js-concert > Boy does this save computation. No need to bind listeners for every object (e.g. domain model) instance: > Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t it? ;-) > > Check what DOM offered since about ever: EventListener interface: > http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener > > You inherit this: > > ```js > > class EventListener { > handleEvent(e) { > var type = 'on' + e.type; > if (type in this) this[type](e); > } > } > > ``` > > And BOOM, every class inheriting that will be able to create instances usable as handlers, no need bind listeners to anything anymore! > > ```js > > class DaClicker extends EventListener { > constructor(el) { > el.addEventListener('click', this); > } > onclick(e) { > alert([e.type, this instanceof DaClicker]); > } > } > > var driver = new DaClicker(document); > > ``` > > How cool is that? Now, let's go back to `Object.assign` ... > > > > Well, that didn’t seem to prevent changing class method enumerability just a little time ago. > > and didn't affect `Object.assign` behavior ... we all agreed here enumerability had to be changed in order to be consistent with native classes and be able to extend them without causing unexpected behaviors ... it was the last window before breaking classes forever, while `Object.assign` is a method based on old ES3 concepts that has not much to do with ES6 and that was never meant to be used to extend objects. It's the wrong tool for the job, accessors are lost in the process, and everything else is ignored, including inheritance. > > > > Sweet story you made out of the example. :-) Coming back to non-prose for a sec, unless you get everyone to ignore Object.assign and use your function, there’s no point in proposing your functions. That’s what I’ve now repeated plenty of times. It’s going to hurt _us_ prototype-uses because _others_ will use Object.assign where they need not. > > There's no point in proposing `Object.assign` to deal with inheritance, prototypal inheritance, and de-facto extend ability. `Object.assing` has one well defined use case: copy own enumerable properties, that's it ... **really** ... that's just it. Good for setup or config options, nothing else! > > > > > Umm, that was already explained by Leon Arnott’s email: Object.assign is cowpath pavement. Everyone seems to like a for-in assignment helper. Two of most popular assign/extend implementation mentioned (jQuery, Underscore) have supported inheritance for _at least_ 7 years. Do you not find that as evidence “from the field"? > > common extend do not loop over inherited properties, if these do is because these were written in an era where `Object.getPrototypeOf` and `Object.setPrototypeOf` where missing. > > You talked about computation power and you want to loop over everything per each `Object.assign` call ... I am sorry I don't follow you anymore here! > > > > Or am I preaching to the choir? Are you personally already in favor of supporting inheritance in Object.assign? > > `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. > > > > Given what I’ve read from you so far you won’t be affected by it as it seems to me you prefer to use this prototypal language in a classical way. > > > No, I do like prototypal inheritance and I love the fact it's still the root of JS inheritance. > > What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. > > Developers should understand it, and I am realizing they don't ... like not at all! > > Best Regards > > > > A. > > On Feb 27, 2015, at 19:51, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > >> That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. >> >> Moreover, back to your ES5/3compat example, if you have a person object, you **never** inherit name, you always have your own name as you explicitly set "John". >> >> You eventually inherit the surname, but that's indeed not your own so it should not be copied as such, it should stay there inherited unless you explicitly go to the inheritance office (the property descriptor officer) and ask for an own surname. >> >> Same is for all people from Estonia, they all inherit their native country when born, they have to hide it explicitly at the same "descriptor office" in order to make them their own country. >> >> But all this goes down to why/how/where you need to retrieve these info. That is the place you log through a for/in in order to reach all exposed (read enumerables) properties. >> That is where you log passing whatever it is through the function I've written. >> >> Before? country isan accessible info, as the surname and other inherited properties eventually would be, and only if re-set on top, will become own properties. >> >> At the end of the day, `Object.assign` has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it. >> >> Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? ) >> >> Best Regards >> >> >> On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: >>> ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. >> >> Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed Object.assign is more useful for data/record objects than for objects with behavior. Ignoring inheritance because of methods is not an argument then. >> >>> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >>> >>> meaning you are good to go with assign or the function I wrote for you. >> >> >> Sadly not. Inheritance should not be conflicted with sharing behavior (methods). Entirely orthogonal concepts. It’s very useful to inherit from various data/record objects and pass those around. The receiver of such an object need never know there’s inheritance involved. >> >>> [ 1 ] What is the problem in accessing inherited values? >>> If you don't want to distinguish them, just don't and use a for/in >>> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 >> >> They thing to remember here is _other people’s code_. My code perfectly honors your inheritance chains when iterating or accessing properties. But me doing that doesn’t imply everyone else won’t use Object.assign to set up their defaults as is very convenient: `person = Object.assign({name: “”, age: 0}, person)`. You think they won’t? They already do so with Object.keys when it’s entirely unnecessary for 9/10 use-cases. >> >>> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >>> I am back with previous [ 1 ] question then. >> >> >> Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. >> >>> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? >> >> >> I’ll leave JSON out of this discussion. Yeah, I’d like to set Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends on it serializing only own properties. Ugh. >> >>> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. >> >>> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` >> >> >> But it’s not me who wants to flatten stuff. It’s the people who will write functions or APIs that use Object.assign while setting their defaults. I don’t mind them flattening, but only if they don’t lose half of the properties to inheritance stripping while doing so. >> >> Am I explaining the problem wrong? I’m still surprised there are people who don’t find the following behavior retarded: >> >> ``` >> function logPerson(person) { console.log(“%s is from %s.”, person.name, person.country) } >> function logTraveler(person) { logPerson(Object.assign({name: “Traveller”}, person)) } >> >> var PERSON = {name: “Unnamed”, country: “Estonia"} >> var john = Object.create(PERSON) >> john.name = “John” >> >> logPerson(john) // => John is from Estonia. >> logTraveler(john) // => John is from undefined. >> ``` >> >> While a little contrived, like I said, Object.assign and its equivalents from libraries are already used to set defaults. >> Just in case: please don’t propose replacing every Object.create with Object.assign. >> >> A. >> >> On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >> >>> answering inline ... >>> >>> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >>>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >>> >>> Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? >>> >>> nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. >>> >>> >>> >>> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >>> >>> meaning you are good to go with assign or the function I wrote for you. >>> >>> >>> >>> >>> Again, I ask, what is the problem to which ignoring inherited properties is the solution to? >>> >>> >>> >>> [ 1 ] What is the problem in accessing inherited values? >>> >>> If you don't want to distinguish them, just don't and use a for/in >>> >>> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 >>> >>> >>> >>> I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence. >>> >>> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >>> I am back with previous [ 1 ] question then. >>> >>> >>> >>> JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter. >>> >>> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? >>> >>> Moreover, you can recreate instances at parse time with a specialized reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >>> Is that retarded? ( maybe this one is :P ) >>> >>> >>> >>> And as I said below: until everyone also prefixes their obj.name uses with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that? >>> >>> actually, following your logic you should never access that unless you are sure it's also enumerable so ... >>> >>> `obj.hasOwnProperty("name") && obj.propertyIsEnumerable("name") && obj.name`` >>> >>> >>> >>> This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design. >>> >>> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. >>> >>> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` >>> >>> Best Regards >>> >>> >>> >>> >>> A. >>> >>> On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>> >>>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >>>> >>>> If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in >>>> >>>> ``` >>>> function flatEnumerables(a) { >>>> for (var c, k, i = 1; i < arguments.length; i++) { >>>> for (k in (c = arguments[i])) a[k] = c[k]; >>>> } >>>> return a; >>>> } >>>> ``` >>>> This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) >>>> >>>> Would that work? >>>> >>>> Best Regards >>>> >>>> >>>> >>>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>>>> You are talking about "flatting" all properties, which is an undesired overhead. >>>> >>>> Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. >>>> >>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>>> >>>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>>> >>>> >>>> Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. >>>> Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. >>>> >>>> Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. >>>> >>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>> >>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>>> Can you explain what is your goal ? Wouldn't this work? >>>> >>>> Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. >>>> >>>> My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. >>>> >>>> A. >>>> >>>> On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>> >>>>> You are talking about "flatting" all properties, which is an undesired overhead. >>>>> >>>>> ```js >>>>> >>>>> var b = Object.create( >>>>> Object.getPrototypeOf(a) >>>>> ); >>>>> >>>>> Object.assign(b, a); >>>>> >>>>> ``` >>>>> >>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>>> >>>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>>>> >>>>> `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. >>>>> >>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>>> >>>>> Can you explain what is your goal ? Wouldn't this work? >>>>> >>>>> ```js >>>>> >>>>> var a = {}; // or anything else >>>>> >>>>> var b = Object.create( >>>>> Object.getPrototypeOf(a) >>>>> ); >>>>> >>>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>>> }); >>>>> >>>>> ``` >>>>> >>>>> >>>>> Best Regards >>>>> >>>>> >>>>> >>>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>>> Hello, >>>>> >>>>> Why does Object.assign ignore inherited enumerable properties? >>>>> What is the problem to which ignoring inherited properties is the solution to? >>>>> >>>>> All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>>> >>>>> - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. >>>>> - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. >>>>> >>>>> I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. >>>>> >>>>> Andri >>>>> >>>>> _______________________________________________ >>>>> 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/20150228/bb67ba90/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150228/bb67ba90/attachment-0001.p7s>
I think your issue is not real, since the bug you linked is indeed closed and the one you opened has been exhaustively answered bu John who's the main person behind lo-dash, the drop-in replacement for underscore. joyent/node#7587
and the "let it go" part is the one I'd like to +1 joyent/node#7587
There's nothing to add here, and this came after a discussion/link you should probably have linked before.
I understand your library was born believing Object.assign
would have
been the answer to all your problems, I'm afraid JS descriptors and
inheritance are a bit more complicated than just own, enumerable, writable,
properties.
Best
I think your issue is not real, since the bug you linked is indeed closed and the one you opened has been exhaustively answered bu John who's the main person behind lo-dash, the drop-in replacement for underscore. https://github.com/joyent/node/issues/7587#issuecomment-42560846 and the "let it go" part is the one I'd like to +1 https://github.com/joyent/node/issues/7587#issuecomment-42677422 There's nothing to add here, and this came after a discussion/link you should probably have linked before. I understand your library was born believing `Object.assign` would have been the answer to all your problems, I'm afraid JS descriptors and inheritance are a bit more complicated than just own, enumerable, writable, properties. Best Regards On Fri, Feb 27, 2015 at 10:30 PM, Andri Möll <andri at dot.ee> wrote: > `Object.assign` has **nothing to do with inheritance**, that's what I am > saying, not just supporting. > > What is my personal position here is that `Object.assign` is the wrong > method/tool/function to do anything prototypal or classical inheritance > related. > > > Are we entirely missing each other? I’ve said a few times now: it’s _none_ > of the callee’s business if I use inheritance in my options, config, setup > or any other plain object (one without behavior). Object.assign must honor > that. > > I asked in my first email: *What is the problem to which ignoring > inherited properties is the solution to?* > If you have an argument that I haven’t refuted yet, please share. > > Just search GitHub’s code for assign usage and you’ll see it fucking up > inheritance all over the place. > There’s even a IO.js issue for the same problem that I’m definitely going > to help fix: https://github.com/iojs/io.js/issues/62. > > Andri Möll: > > Nah, I’m saying inheritance is an implementation detail of my object. It’s >>> none of the receiver’s/callee’s business how I implemented that particular >>> interface (any agreed upon set of properties _is_ an interface). But the >>> moment someone passes my object to Object.assign, they get the wrong >>> output. Even if it should’ve been a no-op: `options = Object.assign({}, >>> options)`. >>> >> > Ignores getters? You mean merely reads them? That’s not ignoring. Getters >>>>> are an implementation detail of an interface. >>>>> >>>> Prototypes aren't only useful for sharing behavior. They’re just as >>>>> useful for *data objects and value types*. Nothing breaks when you >>>>> clone or assign them around. >>>>> >>>> > Inheritance? Inheritance is an implementation detail. A function receiving >>>>> an object must not care about its inheritance tree as long as it fulfills >>>>> the required interface. That’s what the LSP says as well. Even though >>>>> JavaScript has no explicit concept of interfaces or types, they’re implicit >>>>> in any function call. >>>>> >>>> > A. > > On Feb 27, 2015, at 23:13, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > FWIW I do like prototypal inheritance ... but ... > > On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote: > >> That is not what people relying in Object.assign and ES6 will write, >> because you cannot define properties in a generic class, only methods. >> >> >> Classes are just syntactic sugar over prototypes after all. >> > > except finally these behave like natives always have: non enumerable > methods / accessors ... those that even you said don't want on your way > > > >> I’m definitely going to continue promoting use of plain old prototypical >> approaches in addition to that because they're simple and elegant: >> > > objects will still be used for composing and whenever you > `Object.create(Object.getPrototypeOf(other))` you are still using > prototypal inheritance. > > None of this has ever been solved in `Object.assign` though ... > > > >> why waste computation power in constructors when you can do so once on >> the prototype. >> > > 'cause 99% of the time you need to initialize your PERSON with a `name` > property, as example ... do that in the object creation through an implicit > initializer as constructor is: done! > > > >> I find that an advantage of prototypal languages over classical ones. >> > > I guess you like `init` methods too then > > > > >> >> A bit of a plug in this regard, check out this simple observable >> implementation that supports inheritance: >> https://github.com/moll/js-concert >> Boy does this save computation. No need to bind listeners for every >> object (e.g. domain model) instance: >> Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t >> it? ;-) >> > > Check what DOM offered since about ever: EventListener interface: > http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener > > You inherit this: > > ```js > > class EventListener { > handleEvent(e) { > var type = 'on' + e.type; > if (type in this) this[type](e); > } > } > > ``` > > And BOOM, every class inheriting that will be able to create instances > usable as handlers, no need bind listeners to anything anymore! > > ```js > > class DaClicker extends EventListener { > constructor(el) { > el.addEventListener('click', this); > } > onclick(e) { > alert([e.type, this instanceof DaClicker]); > } > } > > var driver = new DaClicker(document); > > ``` > > How cool is that? Now, let's go back to `Object.assign` ... > > > > Well, that didn’t seem to prevent changing class method enumerability just >> a little time ago. >> > > and didn't affect `Object.assign` behavior ... we all agreed here > enumerability had to be changed in order to be consistent with native > classes and be able to extend them without causing unexpected behaviors ... > it was the last window before breaking classes forever, while > `Object.assign` is a method based on old ES3 concepts that has not much to > do with ES6 and that was never meant to be used to extend objects. It's the > wrong tool for the job, accessors are lost in the process, and everything > else is ignored, including inheritance. > > > >> Sweet story you made out of the example. :-) Coming back to non-prose for >> a sec, unless you get everyone to ignore Object.assign and use your >> function, there’s no point in proposing your functions. That’s what I’ve >> now repeated plenty of times. It’s going to hurt _us_ prototype-uses >> because _others_ will use Object.assign where they need not. >> > > There's no point in proposing `Object.assign` to deal with inheritance, > prototypal inheritance, and de-facto extend ability. `Object.assing` has > one well defined use case: copy own enumerable properties, that's it ... > **really** ... that's just it. Good for setup or config options, nothing > else! > > > > > >> Umm, that was already explained by Leon Arnott’s email: Object.assign is >> cowpath pavement. Everyone seems to like a for-in assignment helper. Two of >> most popular assign/extend implementation mentioned (jQuery, Underscore) >> have supported inheritance for _at least_ 7 years. Do you not find that as >> evidence “from the field"? >> > > common extend do not loop over inherited properties, if these do is > because these were written in an era where `Object.getPrototypeOf` and > `Object.setPrototypeOf` where missing. > > You talked about computation power and you want to loop over everything > per each `Object.assign` call ... I am sorry I don't follow you anymore > here! > > > >> >> Or am I preaching to the choir? Are you personally already in favor of >> supporting inheritance in Object.assign? >> > > `Object.assign` has **nothing to do with inheritance**, that's what I am > saying, not just supporting. > > > > >> Given what I’ve read from you so far you won’t be affected by it as it >> seems to me you prefer to use this prototypal language in a classical way. >> > > > No, I do like prototypal inheritance and I love the fact it's still the > root of JS inheritance. > > What is my personal position here is that `Object.assign` is the wrong > method/tool/function to do anything prototypal or classical inheritance > related. > > Developers should understand it, and I am realizing they don't ... like > not at all! > > Best Regards > > > >> >> A. >> >> On Feb 27, 2015, at 19:51, Andrea Giammarchi <andrea.giammarchi at gmail.com> >> wrote: >> >> That is not what people relying in Object.assign and ES6 will write, >> because you cannot define properties in a generic class, only methods. >> >> Moreover, back to your ES5/3compat example, if you have a person object, >> you **never** inherit name, you always have your own name as you explicitly >> set "John". >> >> You eventually inherit the surname, but that's indeed not your own so it >> should not be copied as such, it should stay there inherited unless you >> explicitly go to the inheritance office (the property descriptor officer) >> and ask for an own surname. >> >> Same is for all people from Estonia, they all inherit their native >> country when born, they have to hide it explicitly at the same "descriptor >> office" in order to make them their own country. >> >> But all this goes down to why/how/where you need to retrieve these info. >> That is the place you log through a for/in in order to reach all exposed >> (read enumerables) properties. >> That is where you log passing whatever it is through the function I've >> written. >> >> Before? country isan accessible info, as the surname and other inherited >> properties eventually would be, and only if re-set on top, will become own >> properties. >> >> At the end of the day, `Object.assign` has been already adopted and >> polyfilled and used for some time now, changing it now will probably break >> all code based on it. >> >> Again, I think this is the first time I hear someone wanting a new method >> being exactly like a for/in ... use for/in if that's what you need ( KISS ? >> ) >> >> Best Regards >> >> >> On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: >> >>> ES3 these are all enumerable, you don't want methods copied all over >>> your objects each time because that's the entire point of having prototypal >>> inheritance, right? If instead of inheriting and composing you copy >>> everything as enumerable, writable, and configurable, that's your choice, >>> not what I believe we all need. >>> >>> >>> Umm, that’s one tactic for sharing behavior. Yep. But I thought we >>> agreed Object.assign is more useful for data/record objects than for >>> objects with behavior. Ignoring inheritance because of methods is not an >>> argument then. >>> >>> You yourself said one shouldn’t use Object.assign for objects with >>>> behavior in the inheritance chain. And I agree. It’s pretty much only >>>> useful for data objects (a.k.a plain). Those have no methods in the >>>> inheritance chain one needs to ignore. >>>> >>> >>> meaning you are good to go with assign or the function I wrote for you. >>> >>> >>> Sadly not. Inheritance should not be conflicted with sharing behavior >>> (methods). Entirely orthogonal concepts. It’s very useful to inherit from >>> various data/record objects and pass those around. The receiver of such an >>> object need never know there’s inheritance involved. >>> >>> [ 1 ] What is the problem in accessing inherited values? >>> If you don't want to distinguish them, just don't and use a for/in >>> Why do you want now to change Object assign instead of simply using >>> for/in? This requirement is available since 1999 >>> >>> >>> They thing to remember here is _other people’s code_. My code perfectly >>> honors your inheritance chains when iterating or accessing properties. But >>> me doing that doesn’t imply everyone else won’t use Object.assign to set up >>> their defaults as is very convenient: `person = Object.assign({name: “”, >>> age: 0}, person)`. You think they won’t? They already do so with >>> Object.keys when it’s entirely unnecessary for 9/10 use-cases. >>> >>> You seem to be afraid of inheritance since you want to ignore it and >>> flat all the properties per each copied/enriched object. >>> I am back with previous [ 1 ] question then. >>> >>> >>> Nah, I’m saying inheritance is an implementation detail of my object. >>> It’s none of the receiver’s/callee’s business how I implemented that >>> particular interface (any agreed upon set of properties _is_ an interface). >>> But the moment someone passes my object to Object.assign, they get the >>> wrong output. Even if it should’ve been a no-op: `options = >>> Object.assign({}, options)`. >>> >>> You can define you r`toJSON` method that returns the result of the >>> for/in based function I've written for you. Is that retarded? >>> >>> >>> I’ll leave JSON out of this discussion. Yeah, I’d like to set >>> Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends >>> on it serializing only own properties. Ugh. >>> >>> Precisely ! So use inheritance instead of flattening/hiding it >>> everywhere. Use dictionaries and for/in when all this does not matter. >>> >>> I really don't see, with all possibilities you have to write the way you >>> want, and a function I wrote for you that does what you need, why bothering >>> `Object.assign` >>> >>> >>> But it’s not me who wants to flatten stuff. It’s the people who will >>> write functions or APIs that use Object.assign while setting their >>> defaults. I don’t mind them flattening, but only if they don’t lose half of >>> the properties to inheritance stripping while doing so. >>> >>> Am I explaining the problem wrong? I’m still surprised there are people >>> who don’t find the following behavior retarded: >>> >>> ``` >>> function logPerson(person) { console.log(“%s is from %s.”, person.name, >>> person.country) } >>> function logTraveler(person) { logPerson(Object.assign({name: >>> “Traveller”}, person)) } >>> >>> var PERSON = {name: “Unnamed”, country: “Estonia"} >>> var john = Object.create(PERSON) >>> john.name = “John” >>> >>> logPerson(john) // => John is from Estonia. >>> logTraveler(john) // => John is from undefined. >>> ``` >>> >>> While a little contrived, like I said, Object.assign and its equivalents >>> from libraries are already used to set defaults. >>> Just in case: please don’t propose replacing every Object.create with >>> Object.assign. >>> >>> A. >>> >>> On Feb 27, 2015, at 18:35, Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>> answering inline ... >>> >>> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >>> >>>> noone? JSLint doesn't even let you write a for/in loop if you don't >>>> have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>>> properties (included methods from old classes/ahem prototypes) reassigned >>>> everywhere. >>>> >>>> >>>> Huh? Old prototypes? Those prototypes have their properties set as >>>> non-enumerable since how long now? >>>> >>> >>> nope, I was rather talking about user-land defined "classes" through >>> prototypes. in ES3 these are all enumerable, you don't want methods copied >>> all over your objects each time because that's the entire point of having >>> prototypal inheritance, right? If instead of inheriting and composing you >>> copy everything as enumerable, writable, and configurable, that's your >>> choice, not what I believe we all need. >>> >>> >>> >>> >>>> You yourself said one shouldn’t use Object.assign for objects with >>>> behavior in the inheritance chain. And I agree. It’s pretty much only >>>> useful for data objects (a.k.a plain). Those have no methods in the >>>> inheritance chain one needs to ignore. >>>> >>> >>> meaning you are good to go with assign or the function I wrote for you. >>> >>> >>> >>> >>>> >>>> Again, I ask, *what is the problem to which ignoring inherited >>>> properties is the solution to?* >>>> >>>> >>> >>> [ 1 ] What is the problem in accessing inherited values? >>> >>> If you don't want to distinguish them, just don't and use a for/in >>> >>> Why do you want now to change Object assign instead of simply using >>> for/in? This requirement is available since 1999 >>> >>> >>> >>> >>>> I posit everyone wants inherited properties. Just half of the people >>>> have been FUDed into being afraid of inheritance. But arguments based on >>>> assumptions on what other people want are irrelevant because naive people >>>> are easy to influence. >>>> >>> >>> You seem to be afraid of inheritance since you want to ignore it and >>> flat all the properties per each copied/enriched object. >>> I am back with previous [ 1 ] question then. >>> >>> >>> >>> >>>> JSLint is how Douglas Crockford writes his code. That’s not an argument >>>> for right APIs. JSON.stringify is equally retarded with its inconsistent >>>> handling of inheritance, but that’s another matter. >>>> >>> >>> You can define you r`toJSON` method that returns the result of the >>> for/in based function I've written for you. Is that retarded? >>> >>> Moreover, you can recreate instances at parse time with a specialized >>> reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >>> Is that retarded? ( maybe this one is :P ) >>> >>> >>> >>>> >>>> And as I said below: until everyone also prefixes their obj.name uses >>>> with hasOwn: `*obj.hasOwnProperty(“name”) && obj.name >>>> <http://obj.name/>`*, skipping inherited properties is a fool’s >>>> errand. It causes *inconsistent APIs* because you don’t run your >>>> options et alii objects through inheritance strippers every time. And you >>>> shouldn’t. Or does anyone disagree with that? >>>> >>> >>> actually, following your logic you should never access that unless you >>> are sure it's also enumerable so ... >>> >>> `*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") >>> && **obj.name <http://obj.name/>`*` >>> >>> >>> >>>> >>>> This is a bigger problem than my use of Object.assign. Proliferation of >>>> Object.assign will prevent everyone else from relying on inheritance. And >>>> in a prototypal language I find that bad API design. >>>> >>> >>> Precisely ! So use inheritance instead of flattening/hiding it >>> everywhere. Use dictionaries and for/in when all this does not matter. >>> >>> I really don't see, with all possibilities you have to write the way you >>> want, and a function I wrote for you that does what you need, why bothering >>> `Object.assign` >>> >>> Best Regards >>> >>> >>> >>> >>>> >>>> A. >>>> >>>> On Feb 27, 2015, at 15:40, Andrea Giammarchi < >>>> andrea.giammarchi at gmail.com> wrote: >>>> >>>> noone? JSLint doesn't even let you write a for/in loop if you don't >>>> have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>>> properties (included methods from old classes/ahem prototypes) reassigned >>>> everywhere. >>>> >>>> If you deal with data objects and dictionaries yuo'll always have a >>>> flat structure, right? If you don't care about properties descriptors >>>> (getters and setters) you can always use a for/in >>>> >>>> ``` >>>> function flatEnumerables(a) { >>>> for (var c, k, i = 1; i < arguments.length; i++) { >>>> for (k in (c = arguments[i])) a[k] = c[k]; >>>> } >>>> return a; >>>> } >>>> ``` >>>> This would do what you are looking for (which is the first time I >>>> personally read/hear about somebody wanting `Object.assign` to behave like >>>> a for/in) >>>> >>>> Would that work? >>>> >>>> Best Regards >>>> >>>> >>>> >>>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>>> >>>>> You are talking about "flatting" all properties, which is an undesired >>>>> overhead. >>>>> >>>>> >>>>> Umm, Object.assign is as it is because of performance? I don’t think >>>>> it is nor is that a good reason. Every property access in JavaScript takes >>>>> inheritance into account and there are thousands more than a Object.assign >>>>> call here and there. >>>>> >>>>> But what's bugging me every time more, is that somebody had a very bad >>>>> idea to spread `Object.assign` as something good for inheritance or object >>>>> cloning. >>>>> >>>>> Where does this come from? `Object.assign` retrieves properties and >>>>> ignore getters and setters, is the last tool you want to use as >>>>> substitution principle because it breaks. >>>>> >>>>> >>>>> Ignores getters? You mean merely reads them? That’s not ignoring. >>>>> Getters are an implementation detail of an interface. >>>>> Prototypes aren't only useful for sharing behavior. They’re just as >>>>> useful for *data objects and value types*. Nothing breaks when you >>>>> clone or assign them around. >>>>> >>>>> Object.assign just read properties from one object and assign them to >>>>> another. Something you used to do by hand. It’s just shorter to type >>>>> assign(A, B) than type all properties of B out manually. If it’s _not_ >>>>> meant to be the function-equivalent of `*for (var key in source) >>>>> target[key] = source[key]*` then that’s too bad as my money is on >>>>> it’s going to be used as such. I definitely want to use it for that. >>>>> >>>>> But what's bugging me every time more, is that somebody had a very bad >>>>> idea to spread `Object.assign` as something good for inheritance or object >>>>> cloning. >>>>> >>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>>> way more problems than a missed flattered structure. >>>>> Can you explain what is your goal ? Wouldn't this work? >>>>> >>>>> >>>>> Inheritance? Inheritance is an implementation detail. A function >>>>> receiving an object must not care about its inheritance tree as long as it >>>>> fulfills the required interface. That’s what the LSP says as well. Even >>>>> though JavaScript has no explicit concept of interfaces or types, they’re >>>>> implicit in any function call. >>>>> >>>>> My goal is to save people from having to think every time they call a >>>>> function whether this 3rd party function ignores inherited properties or >>>>> not. If the callee uses Object.assign, it strips them out, if not, the >>>>> dot-operator takes it into account. Surely no-one’s expecting everyone to >>>>> prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) >>>>> && obj.name <http://obj.name/>`*. Why do it in Object.assigns then is >>>>> beyond me. Inconsistent and uncalled for. >>>>> >>>>> A. >>>>> >>>>> On Feb 27, 2015, at 14:24, Andrea Giammarchi < >>>>> andrea.giammarchi at gmail.com> wrote: >>>>> >>>>> You are talking about "flatting" all properties, which is an undesired >>>>> overhead. >>>>> >>>>> ```js >>>>> >>>>> var b = Object.create( >>>>> Object.getPrototypeOf(a) >>>>> ); >>>>> >>>>> Object.assign(b, a); >>>>> >>>>> ``` >>>>> >>>>> But what's bugging me every time more, is that somebody had a very bad >>>>> idea to spread `Object.assign` as something good for inheritance or object >>>>> cloning. >>>>> >>>>> Where does this come from? `Object.assign` retrieves properties and >>>>> ignore getters and setters, is the last tool you want to use as >>>>> substitution principle because it breaks. >>>>> >>>>> `Object.assign` is good only to define enumerable, writable, and >>>>> configurable properties, like configuration or setup objects. >>>>> >>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>>> way more problems than a missed flattered structure. >>>>> >>>>> Can you explain what is your goal ? Wouldn't this work? >>>>> >>>>> ```js >>>>> >>>>> var a = {}; // or anything else >>>>> >>>>> var b = Object.create( >>>>> Object.getPrototypeOf(a) >>>>> ); >>>>> >>>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>>> }); >>>>> >>>>> ``` >>>>> >>>>> >>>>> Best Regards >>>>> >>>>> >>>>> >>>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>>> >>>>>> Hello, >>>>>> >>>>>> Why does Object.assign ignore inherited enumerable properties? >>>>>> What is the problem to which ignoring inherited properties is the >>>>>> solution to? >>>>>> >>>>>> All I can see is that it prevents a useful use of inheritance. The Liskov >>>>>> substitution principle >>>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >>>>>> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>>>> >>>>>> - Everyone who’s messing with Object.prototype has to do it an >>>>>> non-enumerable style anyway. >>>>>> - Most uses of Object.assign will likely be for objects with a finite >>>>>> number of keys. Those form specific and implicit types from which people >>>>>> are likely to read with the dot-operator. That takes inheritance into >>>>>> account anyway. >>>>>> >>>>>> I don’t get the agenda to mess with object inheritance. If one wants >>>>>> methods to only be in the parent and data on the child (so Object.assign >>>>>> would only copy data), use a classical language. In a delegation-prototypal >>>>>> language one should be able to inherit freely because of LSP >>>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >>>>>> >>>>>> Andri >>>>>> >>>>>> _______________________________________________ >>>>>> 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/20150227/081781b1/attachment-0001.html>
Oh, I’ve forgotten we’ve had this argument with you over at the Node.js bug a while back. Long time no see.
- Did you even read the issue I linked to? It ended with agreement that IO.js should support inherited properties.
- @jdalton did not “exhaustively” answer with arguments relating to inheritance. He’s fortunately not someone to give final statements in Node.js behavior, and even if he were, discussions need to be over arguments and not on personalities or someone’s feelings. This isn’t kindergarten.
- There are more people in the world than us two to, so even if you and I reach a standstill, it doesn’t mean this shouldn’t be further discussed and acted upon.
Saying Object.assing assign is so because of Lodash.assign and Lodash.assign is so because of Object.assign is circular and meaningless. This thread here is precicely criticism of Object.assign’s behavior and needs to be discussed with arguments and counter-arguments relating only to inheritance.
Ignore my utility libraries. I don’t want to write libraries for a living. :-)
I understand your library was born believing
Object.assign
would have been the answer to all your problems, I'm afraid JS descriptors and inheritance are a bit more complicated than just own, enumerable, writable, properties.
[citation needed]. Seriously. Please share your counter-arguments and if I can, I’ll counter them or if not, agree. Relating to Object.assign in this thread, of course.
A.
Oh, I’ve forgotten we’ve had this argument with _you_ over at the Node.js bug a while back. Long time no see. 1) Did you even read the issue I linked to? It ended with _agreement_ that IO.js _should_ support inherited properties. 2) @jdalton did _not_ “exhaustively” answer with arguments relating to inheritance. He’s fortunately not someone to give final statements in Node.js behavior, and even if he were, discussions need to be over arguments and not on personalities or someone’s feelings. This isn’t kindergarten. 3) There are more people in the world than us two to, so even if you and I reach a standstill, it doesn’t mean this shouldn’t be further discussed and acted upon. Saying Object.assing assign is so because of Lodash.assign and Lodash.assign is so because of Object.assign is circular and meaningless. This thread here is precicely criticism of Object.assign’s behavior and needs to be discussed with arguments and counter-arguments relating only to inheritance. Ignore my utility libraries. I don’t want to write libraries for a living. :-) > I understand your library was born believing `Object.assign` would have been the answer to all your problems, I'm afraid JS descriptors and inheritance are a bit more complicated than just own, enumerable, writable, properties. [citation needed]. Seriously. Please share your counter-arguments and if I can, I’ll counter them or if not, agree. Relating to Object.assign in this thread, of course. A. On Feb 28, 2015, at 00:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > I think your issue is not real, since the bug you linked is indeed closed and the one you opened has been exhaustively answered bu John who's the main person behind lo-dash, the drop-in replacement for underscore. > https://github.com/joyent/node/issues/7587#issuecomment-42560846 > > and the "let it go" part is the one I'd like to +1 > https://github.com/joyent/node/issues/7587#issuecomment-42677422 > > There's nothing to add here, and this came after a discussion/link you should probably have linked before. > > I understand your library was born believing `Object.assign` would have been the answer to all your problems, I'm afraid JS descriptors and inheritance are a bit more complicated than just own, enumerable, writable, properties. > > Best Regards > > On Fri, Feb 27, 2015 at 10:30 PM, Andri Möll <andri at dot.ee> wrote: >> `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. >> What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. > > > Are we entirely missing each other? I’ve said a few times now: it’s _none_ of the callee’s business if I use inheritance in my options, config, setup or any other plain object (one without behavior). Object.assign must honor that. > > I asked in my first email: What is the problem to which ignoring inherited properties is the solution to? > If you have an argument that I haven’t refuted yet, please share. > > Just search GitHub’s code for assign usage and you’ll see it fucking up inheritance all over the place. > There’s even a IO.js issue for the same problem that I’m definitely going to help fix: https://github.com/iojs/io.js/issues/62. > > Andri Möll: >> Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. >> >> Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. >> Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. >> >> >> Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. > > A. > > On Feb 27, 2015, at 23:13, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > >> FWIW I do like prototypal inheritance ... but ... >> >> On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote: >>> That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. >> >> Classes are just syntactic sugar over prototypes after all. >> >> except finally these behave like natives always have: non enumerable methods / accessors ... those that even you said don't want on your way >> >> >> I’m definitely going to continue promoting use of plain old prototypical approaches in addition to that because they're simple and elegant: >> >> objects will still be used for composing and whenever you `Object.create(Object.getPrototypeOf(other))` you are still using prototypal inheritance. >> >> None of this has ever been solved in `Object.assign` though ... >> >> >> why waste computation power in constructors when you can do so once on the prototype. >> >> 'cause 99% of the time you need to initialize your PERSON with a `name` property, as example ... do that in the object creation through an implicit initializer as constructor is: done! >> >> >> I find that an advantage of prototypal languages over classical ones. >> >> I guess you like `init` methods too then >> >> >> >> >> A bit of a plug in this regard, check out this simple observable implementation that supports inheritance: https://github.com/moll/js-concert >> Boy does this save computation. No need to bind listeners for every object (e.g. domain model) instance: >> Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t it? ;-) >> >> Check what DOM offered since about ever: EventListener interface: >> http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener >> >> You inherit this: >> >> ```js >> >> class EventListener { >> handleEvent(e) { >> var type = 'on' + e.type; >> if (type in this) this[type](e); >> } >> } >> >> ``` >> >> And BOOM, every class inheriting that will be able to create instances usable as handlers, no need bind listeners to anything anymore! >> >> ```js >> >> class DaClicker extends EventListener { >> constructor(el) { >> el.addEventListener('click', this); >> } >> onclick(e) { >> alert([e.type, this instanceof DaClicker]); >> } >> } >> >> var driver = new DaClicker(document); >> >> ``` >> >> How cool is that? Now, let's go back to `Object.assign` ... >> >> >> >> Well, that didn’t seem to prevent changing class method enumerability just a little time ago. >> >> and didn't affect `Object.assign` behavior ... we all agreed here enumerability had to be changed in order to be consistent with native classes and be able to extend them without causing unexpected behaviors ... it was the last window before breaking classes forever, while `Object.assign` is a method based on old ES3 concepts that has not much to do with ES6 and that was never meant to be used to extend objects. It's the wrong tool for the job, accessors are lost in the process, and everything else is ignored, including inheritance. >> >> >> >> Sweet story you made out of the example. :-) Coming back to non-prose for a sec, unless you get everyone to ignore Object.assign and use your function, there’s no point in proposing your functions. That’s what I’ve now repeated plenty of times. It’s going to hurt _us_ prototype-uses because _others_ will use Object.assign where they need not. >> >> There's no point in proposing `Object.assign` to deal with inheritance, prototypal inheritance, and de-facto extend ability. `Object.assing` has one well defined use case: copy own enumerable properties, that's it ... **really** ... that's just it. Good for setup or config options, nothing else! >> >> >> >> >> Umm, that was already explained by Leon Arnott’s email: Object.assign is cowpath pavement. Everyone seems to like a for-in assignment helper. Two of most popular assign/extend implementation mentioned (jQuery, Underscore) have supported inheritance for _at least_ 7 years. Do you not find that as evidence “from the field"? >> >> common extend do not loop over inherited properties, if these do is because these were written in an era where `Object.getPrototypeOf` and `Object.setPrototypeOf` where missing. >> >> You talked about computation power and you want to loop over everything per each `Object.assign` call ... I am sorry I don't follow you anymore here! >> >> >> >> Or am I preaching to the choir? Are you personally already in favor of supporting inheritance in Object.assign? >> >> `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. >> >> >> >> Given what I’ve read from you so far you won’t be affected by it as it seems to me you prefer to use this prototypal language in a classical way. >> >> >> No, I do like prototypal inheritance and I love the fact it's still the root of JS inheritance. >> >> What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. >> >> Developers should understand it, and I am realizing they don't ... like not at all! >> >> Best Regards >> >> >> >> A. >> >> On Feb 27, 2015, at 19:51, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >> >>> That is not what people relying in Object.assign and ES6 will write, because you cannot define properties in a generic class, only methods. >>> >>> Moreover, back to your ES5/3compat example, if you have a person object, you **never** inherit name, you always have your own name as you explicitly set "John". >>> >>> You eventually inherit the surname, but that's indeed not your own so it should not be copied as such, it should stay there inherited unless you explicitly go to the inheritance office (the property descriptor officer) and ask for an own surname. >>> >>> Same is for all people from Estonia, they all inherit their native country when born, they have to hide it explicitly at the same "descriptor office" in order to make them their own country. >>> >>> But all this goes down to why/how/where you need to retrieve these info. That is the place you log through a for/in in order to reach all exposed (read enumerables) properties. >>> That is where you log passing whatever it is through the function I've written. >>> >>> Before? country isan accessible info, as the surname and other inherited properties eventually would be, and only if re-set on top, will become own properties. >>> >>> At the end of the day, `Object.assign` has been already adopted and polyfilled and used for some time now, changing it now will probably break all code based on it. >>> >>> Again, I think this is the first time I hear someone wanting a new method being exactly like a for/in ... use for/in if that's what you need ( KISS ? ) >>> >>> Best Regards >>> >>> >>> On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: >>>> ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. >>> >>> Umm, that’s one tactic for sharing behavior. Yep. But I thought we agreed Object.assign is more useful for data/record objects than for objects with behavior. Ignoring inheritance because of methods is not an argument then. >>> >>>> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >>>> >>>> meaning you are good to go with assign or the function I wrote for you. >>> >>> >>> Sadly not. Inheritance should not be conflicted with sharing behavior (methods). Entirely orthogonal concepts. It’s very useful to inherit from various data/record objects and pass those around. The receiver of such an object need never know there’s inheritance involved. >>> >>>> [ 1 ] What is the problem in accessing inherited values? >>>> If you don't want to distinguish them, just don't and use a for/in >>>> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 >>> >>> They thing to remember here is _other people’s code_. My code perfectly honors your inheritance chains when iterating or accessing properties. But me doing that doesn’t imply everyone else won’t use Object.assign to set up their defaults as is very convenient: `person = Object.assign({name: “”, age: 0}, person)`. You think they won’t? They already do so with Object.keys when it’s entirely unnecessary for 9/10 use-cases. >>> >>>> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >>>> I am back with previous [ 1 ] question then. >>> >>> >>> Nah, I’m saying inheritance is an implementation detail of my object. It’s none of the receiver’s/callee’s business how I implemented that particular interface (any agreed upon set of properties _is_ an interface). But the moment someone passes my object to Object.assign, they get the wrong output. Even if it should’ve been a no-op: `options = Object.assign({}, options)`. >>> >>>> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? >>> >>> >>> I’ll leave JSON out of this discussion. Yeah, I’d like to set Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends on it serializing only own properties. Ugh. >>> >>>> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. >>> >>>> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` >>> >>> >>> But it’s not me who wants to flatten stuff. It’s the people who will write functions or APIs that use Object.assign while setting their defaults. I don’t mind them flattening, but only if they don’t lose half of the properties to inheritance stripping while doing so. >>> >>> Am I explaining the problem wrong? I’m still surprised there are people who don’t find the following behavior retarded: >>> >>> ``` >>> function logPerson(person) { console.log(“%s is from %s.”, person.name, person.country) } >>> function logTraveler(person) { logPerson(Object.assign({name: “Traveller”}, person)) } >>> >>> var PERSON = {name: “Unnamed”, country: “Estonia"} >>> var john = Object.create(PERSON) >>> john.name = “John” >>> >>> logPerson(john) // => John is from Estonia. >>> logTraveler(john) // => John is from undefined. >>> ``` >>> >>> While a little contrived, like I said, Object.assign and its equivalents from libraries are already used to set defaults. >>> Just in case: please don’t propose replacing every Object.create with Object.assign. >>> >>> A. >>> >>> On Feb 27, 2015, at 18:35, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>> >>>> answering inline ... >>>> >>>> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >>>>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >>>> >>>> Huh? Old prototypes? Those prototypes have their properties set as non-enumerable since how long now? >>>> >>>> nope, I was rather talking about user-land defined "classes" through prototypes. in ES3 these are all enumerable, you don't want methods copied all over your objects each time because that's the entire point of having prototypal inheritance, right? If instead of inheriting and composing you copy everything as enumerable, writable, and configurable, that's your choice, not what I believe we all need. >>>> >>>> >>>> >>>> You yourself said one shouldn’t use Object.assign for objects with behavior in the inheritance chain. And I agree. It’s pretty much only useful for data objects (a.k.a plain). Those have no methods in the inheritance chain one needs to ignore. >>>> >>>> meaning you are good to go with assign or the function I wrote for you. >>>> >>>> >>>> >>>> >>>> Again, I ask, what is the problem to which ignoring inherited properties is the solution to? >>>> >>>> >>>> >>>> [ 1 ] What is the problem in accessing inherited values? >>>> >>>> If you don't want to distinguish them, just don't and use a for/in >>>> >>>> Why do you want now to change Object assign instead of simply using for/in? This requirement is available since 1999 >>>> >>>> >>>> >>>> I posit everyone wants inherited properties. Just half of the people have been FUDed into being afraid of inheritance. But arguments based on assumptions on what other people want are irrelevant because naive people are easy to influence. >>>> >>>> You seem to be afraid of inheritance since you want to ignore it and flat all the properties per each copied/enriched object. >>>> I am back with previous [ 1 ] question then. >>>> >>>> >>>> >>>> JSLint is how Douglas Crockford writes his code. That’s not an argument for right APIs. JSON.stringify is equally retarded with its inconsistent handling of inheritance, but that’s another matter. >>>> >>>> You can define you r`toJSON` method that returns the result of the for/in based function I've written for you. Is that retarded? >>>> >>>> Moreover, you can recreate instances at parse time with a specialized reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >>>> Is that retarded? ( maybe this one is :P ) >>>> >>>> >>>> >>>> And as I said below: until everyone also prefixes their obj.name uses with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`, skipping inherited properties is a fool’s errand. It causes inconsistent APIs because you don’t run your options et alii objects through inheritance strippers every time. And you shouldn’t. Or does anyone disagree with that? >>>> >>>> actually, following your logic you should never access that unless you are sure it's also enumerable so ... >>>> >>>> `obj.hasOwnProperty("name") && obj.propertyIsEnumerable("name") && obj.name`` >>>> >>>> >>>> >>>> This is a bigger problem than my use of Object.assign. Proliferation of Object.assign will prevent everyone else from relying on inheritance. And in a prototypal language I find that bad API design. >>>> >>>> Precisely ! So use inheritance instead of flattening/hiding it everywhere. Use dictionaries and for/in when all this does not matter. >>>> >>>> I really don't see, with all possibilities you have to write the way you want, and a function I wrote for you that does what you need, why bothering `Object.assign` >>>> >>>> Best Regards >>>> >>>> >>>> >>>> >>>> A. >>>> >>>> On Feb 27, 2015, at 15:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>> >>>>> noone? JSLint doesn't even let you write a for/in loop if you don't have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited properties (included methods from old classes/ahem prototypes) reassigned everywhere. >>>>> >>>>> If you deal with data objects and dictionaries yuo'll always have a flat structure, right? If you don't care about properties descriptors (getters and setters) you can always use a for/in >>>>> >>>>> ``` >>>>> function flatEnumerables(a) { >>>>> for (var c, k, i = 1; i < arguments.length; i++) { >>>>> for (k in (c = arguments[i])) a[k] = c[k]; >>>>> } >>>>> return a; >>>>> } >>>>> ``` >>>>> This would do what you are looking for (which is the first time I personally read/hear about somebody wanting `Object.assign` to behave like a for/in) >>>>> >>>>> Would that work? >>>>> >>>>> Best Regards >>>>> >>>>> >>>>> >>>>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>>>>> You are talking about "flatting" all properties, which is an undesired overhead. >>>>> >>>>> Umm, Object.assign is as it is because of performance? I don’t think it is nor is that a good reason. Every property access in JavaScript takes inheritance into account and there are thousands more than a Object.assign call here and there. >>>>> >>>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>>>> >>>>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>>>> >>>>> >>>>> Ignores getters? You mean merely reads them? That’s not ignoring. Getters are an implementation detail of an interface. >>>>> Prototypes aren't only useful for sharing behavior. They’re just as useful for data objects and value types. Nothing breaks when you clone or assign them around. >>>>> >>>>> Object.assign just read properties from one object and assign them to another. Something you used to do by hand. It’s just shorter to type assign(A, B) than type all properties of B out manually. If it’s _not_ meant to be the function-equivalent of `for (var key in source) target[key] = source[key]` then that’s too bad as my money is on it’s going to be used as such. I definitely want to use it for that. >>>>> >>>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>>> >>>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>>>> Can you explain what is your goal ? Wouldn't this work? >>>>> >>>>> Inheritance? Inheritance is an implementation detail. A function receiving an object must not care about its inheritance tree as long as it fulfills the required interface. That’s what the LSP says as well. Even though JavaScript has no explicit concept of interfaces or types, they’re implicit in any function call. >>>>> >>>>> My goal is to save people from having to think every time they call a function whether this 3rd party function ignores inherited properties or not. If the callee uses Object.assign, it strips them out, if not, the dot-operator takes it into account. Surely no-one’s expecting everyone to prefix _every_ obj.name use with hasOwn: `obj.hasOwnProperty(“name”) && obj.name`. Why do it in Object.assigns then is beyond me. Inconsistent and uncalled for. >>>>> >>>>> A. >>>>> >>>>> On Feb 27, 2015, at 14:24, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>>> >>>>>> You are talking about "flatting" all properties, which is an undesired overhead. >>>>>> >>>>>> ```js >>>>>> >>>>>> var b = Object.create( >>>>>> Object.getPrototypeOf(a) >>>>>> ); >>>>>> >>>>>> Object.assign(b, a); >>>>>> >>>>>> ``` >>>>>> >>>>>> But what's bugging me every time more, is that somebody had a very bad idea to spread `Object.assign` as something good for inheritance or object cloning. >>>>>> >>>>>> Where does this come from? `Object.assign` retrieves properties and ignore getters and setters, is the last tool you want to use as substitution principle because it breaks. >>>>>> >>>>>> `Object.assign` is good only to define enumerable, writable, and configurable properties, like configuration or setup objects. >>>>>> >>>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have way more problems than a missed flattered structure. >>>>>> >>>>>> Can you explain what is your goal ? Wouldn't this work? >>>>>> >>>>>> ```js >>>>>> >>>>>> var a = {}; // or anything else >>>>>> >>>>>> var b = Object.create( >>>>>> Object.getPrototypeOf(a) >>>>>> ); >>>>>> >>>>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>>>> }); >>>>>> >>>>>> ``` >>>>>> >>>>>> >>>>>> Best Regards >>>>>> >>>>>> >>>>>> >>>>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>>>> Hello, >>>>>> >>>>>> Why does Object.assign ignore inherited enumerable properties? >>>>>> What is the problem to which ignoring inherited properties is the solution to? >>>>>> >>>>>> All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>>>> >>>>>> - Everyone who’s messing with Object.prototype has to do it an non-enumerable style anyway. >>>>>> - Most uses of Object.assign will likely be for objects with a finite number of keys. Those form specific and implicit types from which people are likely to read with the dot-operator. That takes inheritance into account anyway. >>>>>> >>>>>> I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP. >>>>>> >>>>>> Andri >>>>>> >>>>>> _______________________________________________ >>>>>> 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/20150228/ba90477d/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150228/ba90477d/attachment-0001.p7s>
lodash has more downloads than underscore and it does not suffer these kind of "little gotchas": twitter.com/jdalton/status/568575738086993920
It's a huge community and JD agrees with Leon Arnott points, after all points he, me, and others, alrThiseady made about this matter.
This discussion landed here after tons of bikesheds already, and I'm fool enough to keep answering but few already probably thought "get a room" or something similar, so I'll happily stop here.
This is the outcome from my point of view: twitter.com/WebReflection/status/571442010265149441
Please try to understand you are targeting the wrong method to implement what you suggest, or feel free to explain to everyone here how inheritance should work in JS, I'm pretty sure we all don't have a clue so you can tell us how is that.
Best
lodash has more downloads than underscore and it does not suffer these kind of "little gotchas": https://twitter.com/jdalton/status/568575738086993920 It's a huge community and JD agrees with Leon Arnott points, after all points he, me, and others, alrThiseady made about this matter. This discussion landed here after tons of bikesheds already, and I'm fool enough to keep answering but few already probably thought "get a room" or something similar, so I'll happily stop here. This is the outcome from my point of view: https://twitter.com/WebReflection/status/571442010265149441 Please try to understand you are targeting the wrong method to implement what you suggest, or feel free to explain to everyone here how inheritance should work in JS, I'm pretty sure we all don't have a clue so you can tell us how is that. Best Regards On Fri, Feb 27, 2015 at 10:52 PM, Andri Möll <andri at dot.ee> wrote: > Oh, I’ve forgotten we’ve had this argument with _you_ over at the Node.js > bug a while back. Long time no see. > > 1) Did you even read the issue I linked to? It ended with _agreement_ that > IO.js _should_ support inherited properties. > 2) @jdalton did _not_ “exhaustively” answer with arguments relating to > inheritance. He’s fortunately not someone to give final statements in > Node.js behavior, and even if he were, discussions need to be over > arguments and not on personalities or someone’s feelings. This isn’t > kindergarten. > 3) There are more people in the world than us two to, so even if you and I > reach a standstill, it doesn’t mean this shouldn’t be further discussed and > acted upon. > > Saying Object.assing assign is so because of Lodash.assign and > Lodash.assign is so because of Object.assign is circular and meaningless. > This thread here is precicely criticism of Object.assign’s behavior and > needs to be discussed with arguments and counter-arguments relating only to > inheritance. > > Ignore my utility libraries. I don’t want to write libraries for a living. > :-) > > I understand your library was born believing `Object.assign` would have > been the answer to all your problems, I'm afraid JS descriptors and > inheritance are a bit more complicated than just own, enumerable, writable, > properties. > > > [citation needed]. Seriously. Please share your counter-arguments and if I > can, I’ll counter them or if not, agree. Relating to Object.assign in this > thread, of course. > > A. > > On Feb 28, 2015, at 00:40, Andrea Giammarchi <andrea.giammarchi at gmail.com> > wrote: > > I think your issue is not real, since the bug you linked is indeed closed > and the one you opened has been exhaustively answered bu John who's the > main person behind lo-dash, the drop-in replacement for underscore. > https://github.com/joyent/node/issues/7587#issuecomment-42560846 > > and the "let it go" part is the one I'd like to +1 > https://github.com/joyent/node/issues/7587#issuecomment-42677422 > > There's nothing to add here, and this came after a discussion/link you > should probably have linked before. > > I understand your library was born believing `Object.assign` would have > been the answer to all your problems, I'm afraid JS descriptors and > inheritance are a bit more complicated than just own, enumerable, writable, > properties. > > Best Regards > > On Fri, Feb 27, 2015 at 10:30 PM, Andri Möll <andri at dot.ee> wrote: > >> `Object.assign` has **nothing to do with inheritance**, that's what I am >> saying, not just supporting. >> >> What is my personal position here is that `Object.assign` is the wrong >> method/tool/function to do anything prototypal or classical inheritance >> related. >> >> >> Are we entirely missing each other? I’ve said a few times now: it’s >> _none_ of the callee’s business if I use inheritance in my options, config, >> setup or any other plain object (one without behavior). Object.assign must >> honor that. >> >> I asked in my first email: *What is the problem to which ignoring >> inherited properties is the solution to?* >> If you have an argument that I haven’t refuted yet, please share. >> >> Just search GitHub’s code for assign usage and you’ll see it fucking up >> inheritance all over the place. >> There’s even a IO.js issue for the same problem that I’m definitely going >> to help fix: https://github.com/iojs/io.js/issues/62. >> >> Andri Möll: >> >> Nah, I’m saying inheritance is an implementation detail of my object. >>>> It’s none of the receiver’s/callee’s business how I implemented that >>>> particular interface (any agreed upon set of properties _is_ an interface). >>>> But the moment someone passes my object to Object.assign, they get the >>>> wrong output. Even if it should’ve been a no-op: `options = >>>> Object.assign({}, options)`. >>>> >>> >> Ignores getters? You mean merely reads them? That’s not ignoring. Getters >>>>>> are an implementation detail of an interface. >>>>>> >>>>> Prototypes aren't only useful for sharing behavior. They’re just as >>>>>> useful for *data objects and value types*. Nothing breaks when you >>>>>> clone or assign them around. >>>>>> >>>>> >> Inheritance? Inheritance is an implementation detail. A function >>>>>> receiving an object must not care about its inheritance tree as long as it >>>>>> fulfills the required interface. That’s what the LSP says as well. Even >>>>>> though JavaScript has no explicit concept of interfaces or types, they’re >>>>>> implicit in any function call. >>>>>> >>>>> >> A. >> >> On Feb 27, 2015, at 23:13, Andrea Giammarchi <andrea.giammarchi at gmail.com> >> wrote: >> >> FWIW I do like prototypal inheritance ... but ... >> >> On Fri, Feb 27, 2015 at 8:45 PM, Andri Möll <andri at dot.ee> wrote: >> >>> That is not what people relying in Object.assign and ES6 will write, >>> because you cannot define properties in a generic class, only methods. >>> >>> >>> Classes are just syntactic sugar over prototypes after all. >>> >> >> except finally these behave like natives always have: non enumerable >> methods / accessors ... those that even you said don't want on your way >> >> >> >>> I’m definitely going to continue promoting use of plain old prototypical >>> approaches in addition to that because they're simple and elegant: >>> >> >> objects will still be used for composing and whenever you >> `Object.create(Object.getPrototypeOf(other))` you are still using >> prototypal inheritance. >> >> None of this has ever been solved in `Object.assign` though ... >> >> >> >>> why waste computation power in constructors when you can do so once on >>> the prototype. >>> >> >> 'cause 99% of the time you need to initialize your PERSON with a `name` >> property, as example ... do that in the object creation through an implicit >> initializer as constructor is: done! >> >> >> >>> I find that an advantage of prototypal languages over classical ones. >>> >> >> I guess you like `init` methods too then >> >> >> >> >>> >>> A bit of a plug in this regard, check out this simple observable >>> implementation that supports inheritance: >>> https://github.com/moll/js-concert >>> Boy does this save computation. No need to bind listeners for every >>> object (e.g. domain model) instance: >>> Model.prototype.on(“change”, onChange) is all you need. Beautiful, isn’t >>> it? ;-) >>> >> >> Check what DOM offered since about ever: EventListener interface: >> http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener >> >> You inherit this: >> >> ```js >> >> class EventListener { >> handleEvent(e) { >> var type = 'on' + e.type; >> if (type in this) this[type](e); >> } >> } >> >> ``` >> >> And BOOM, every class inheriting that will be able to create instances >> usable as handlers, no need bind listeners to anything anymore! >> >> ```js >> >> class DaClicker extends EventListener { >> constructor(el) { >> el.addEventListener('click', this); >> } >> onclick(e) { >> alert([e.type, this instanceof DaClicker]); >> } >> } >> >> var driver = new DaClicker(document); >> >> ``` >> >> How cool is that? Now, let's go back to `Object.assign` ... >> >> >> >> Well, that didn’t seem to prevent changing class method enumerability >>> just a little time ago. >>> >> >> and didn't affect `Object.assign` behavior ... we all agreed here >> enumerability had to be changed in order to be consistent with native >> classes and be able to extend them without causing unexpected behaviors ... >> it was the last window before breaking classes forever, while >> `Object.assign` is a method based on old ES3 concepts that has not much to >> do with ES6 and that was never meant to be used to extend objects. It's the >> wrong tool for the job, accessors are lost in the process, and everything >> else is ignored, including inheritance. >> >> >> >>> Sweet story you made out of the example. :-) Coming back to non-prose >>> for a sec, unless you get everyone to ignore Object.assign and use your >>> function, there’s no point in proposing your functions. That’s what I’ve >>> now repeated plenty of times. It’s going to hurt _us_ prototype-uses >>> because _others_ will use Object.assign where they need not. >>> >> >> There's no point in proposing `Object.assign` to deal with inheritance, >> prototypal inheritance, and de-facto extend ability. `Object.assing` has >> one well defined use case: copy own enumerable properties, that's it ... >> **really** ... that's just it. Good for setup or config options, nothing >> else! >> >> >> >> >> >>> Umm, that was already explained by Leon Arnott’s email: Object.assign is >>> cowpath pavement. Everyone seems to like a for-in assignment helper. Two of >>> most popular assign/extend implementation mentioned (jQuery, Underscore) >>> have supported inheritance for _at least_ 7 years. Do you not find that as >>> evidence “from the field"? >>> >> >> common extend do not loop over inherited properties, if these do is >> because these were written in an era where `Object.getPrototypeOf` and >> `Object.setPrototypeOf` where missing. >> >> You talked about computation power and you want to loop over everything >> per each `Object.assign` call ... I am sorry I don't follow you anymore >> here! >> >> >> >>> >>> Or am I preaching to the choir? Are you personally already in favor of >>> supporting inheritance in Object.assign? >>> >> >> `Object.assign` has **nothing to do with inheritance**, that's what I am >> saying, not just supporting. >> >> >> >> >>> Given what I’ve read from you so far you won’t be affected by it as it >>> seems to me you prefer to use this prototypal language in a classical way. >>> >> >> >> No, I do like prototypal inheritance and I love the fact it's still the >> root of JS inheritance. >> >> What is my personal position here is that `Object.assign` is the wrong >> method/tool/function to do anything prototypal or classical inheritance >> related. >> >> Developers should understand it, and I am realizing they don't ... like >> not at all! >> >> Best Regards >> >> >> >>> >>> A. >>> >>> On Feb 27, 2015, at 19:51, Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>> That is not what people relying in Object.assign and ES6 will write, >>> because you cannot define properties in a generic class, only methods. >>> >>> Moreover, back to your ES5/3compat example, if you have a person object, >>> you **never** inherit name, you always have your own name as you explicitly >>> set "John". >>> >>> You eventually inherit the surname, but that's indeed not your own so it >>> should not be copied as such, it should stay there inherited unless you >>> explicitly go to the inheritance office (the property descriptor officer) >>> and ask for an own surname. >>> >>> Same is for all people from Estonia, they all inherit their native >>> country when born, they have to hide it explicitly at the same "descriptor >>> office" in order to make them their own country. >>> >>> But all this goes down to why/how/where you need to retrieve these info. >>> That is the place you log through a for/in in order to reach all exposed >>> (read enumerables) properties. >>> That is where you log passing whatever it is through the function I've >>> written. >>> >>> Before? country isan accessible info, as the surname and other inherited >>> properties eventually would be, and only if re-set on top, will become own >>> properties. >>> >>> At the end of the day, `Object.assign` has been already adopted and >>> polyfilled and used for some time now, changing it now will probably break >>> all code based on it. >>> >>> Again, I think this is the first time I hear someone wanting a new >>> method being exactly like a for/in ... use for/in if that's what you need ( >>> KISS ? ) >>> >>> Best Regards >>> >>> >>> On Fri, Feb 27, 2015 at 5:27 PM, Andri Möll <andri at dot.ee> wrote: >>> >>>> ES3 these are all enumerable, you don't want methods copied all over >>>> your objects each time because that's the entire point of having prototypal >>>> inheritance, right? If instead of inheriting and composing you copy >>>> everything as enumerable, writable, and configurable, that's your choice, >>>> not what I believe we all need. >>>> >>>> >>>> Umm, that’s one tactic for sharing behavior. Yep. But I thought we >>>> agreed Object.assign is more useful for data/record objects than for >>>> objects with behavior. Ignoring inheritance because of methods is not an >>>> argument then. >>>> >>>> You yourself said one shouldn’t use Object.assign for objects with >>>>> behavior in the inheritance chain. And I agree. It’s pretty much only >>>>> useful for data objects (a.k.a plain). Those have no methods in the >>>>> inheritance chain one needs to ignore. >>>>> >>>> >>>> meaning you are good to go with assign or the function I wrote for you. >>>> >>>> >>>> Sadly not. Inheritance should not be conflicted with sharing behavior >>>> (methods). Entirely orthogonal concepts. It’s very useful to inherit from >>>> various data/record objects and pass those around. The receiver of such an >>>> object need never know there’s inheritance involved. >>>> >>>> [ 1 ] What is the problem in accessing inherited values? >>>> If you don't want to distinguish them, just don't and use a for/in >>>> Why do you want now to change Object assign instead of simply using >>>> for/in? This requirement is available since 1999 >>>> >>>> >>>> They thing to remember here is _other people’s code_. My code perfectly >>>> honors your inheritance chains when iterating or accessing properties. But >>>> me doing that doesn’t imply everyone else won’t use Object.assign to set up >>>> their defaults as is very convenient: `person = Object.assign({name: “”, >>>> age: 0}, person)`. You think they won’t? They already do so with >>>> Object.keys when it’s entirely unnecessary for 9/10 use-cases. >>>> >>>> You seem to be afraid of inheritance since you want to ignore it and >>>> flat all the properties per each copied/enriched object. >>>> I am back with previous [ 1 ] question then. >>>> >>>> >>>> Nah, I’m saying inheritance is an implementation detail of my object. >>>> It’s none of the receiver’s/callee’s business how I implemented that >>>> particular interface (any agreed upon set of properties _is_ an interface). >>>> But the moment someone passes my object to Object.assign, they get the >>>> wrong output. Even if it should’ve been a no-op: `options = >>>> Object.assign({}, options)`. >>>> >>>> You can define you r`toJSON` method that returns the result of the >>>> for/in based function I've written for you. Is that retarded? >>>> >>>> >>>> I’ll leave JSON out of this discussion. Yeah, I’d like to set >>>> Object.prototype.toJSON, but I’m afraid there’s code somewhere that depends >>>> on it serializing only own properties. Ugh. >>>> >>>> Precisely ! So use inheritance instead of flattening/hiding it >>>> everywhere. Use dictionaries and for/in when all this does not matter. >>>> >>>> I really don't see, with all possibilities you have to write the way >>>> you want, and a function I wrote for you that does what you need, why >>>> bothering `Object.assign` >>>> >>>> >>>> But it’s not me who wants to flatten stuff. It’s the people who will >>>> write functions or APIs that use Object.assign while setting their >>>> defaults. I don’t mind them flattening, but only if they don’t lose half of >>>> the properties to inheritance stripping while doing so. >>>> >>>> Am I explaining the problem wrong? I’m still surprised there are people >>>> who don’t find the following behavior retarded: >>>> >>>> ``` >>>> function logPerson(person) { console.log(“%s is from %s.”, person.name, >>>> person.country) } >>>> function logTraveler(person) { logPerson(Object.assign({name: >>>> “Traveller”}, person)) } >>>> >>>> var PERSON = {name: “Unnamed”, country: “Estonia"} >>>> var john = Object.create(PERSON) >>>> john.name = “John” >>>> >>>> logPerson(john) // => John is from Estonia. >>>> logTraveler(john) // => John is from undefined. >>>> ``` >>>> >>>> While a little contrived, like I said, Object.assign and its >>>> equivalents from libraries are already used to set defaults. >>>> Just in case: please don’t propose replacing every Object.create with >>>> Object.assign. >>>> >>>> A. >>>> >>>> On Feb 27, 2015, at 18:35, Andrea Giammarchi < >>>> andrea.giammarchi at gmail.com> wrote: >>>> >>>> answering inline ... >>>> >>>> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <andri at dot.ee> wrote: >>>> >>>>> noone? JSLint doesn't even let you write a for/in loop if you don't >>>>> have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>>>> properties (included methods from old classes/ahem prototypes) reassigned >>>>> everywhere. >>>>> >>>>> >>>>> Huh? Old prototypes? Those prototypes have their properties set as >>>>> non-enumerable since how long now? >>>>> >>>> >>>> nope, I was rather talking about user-land defined "classes" through >>>> prototypes. in ES3 these are all enumerable, you don't want methods copied >>>> all over your objects each time because that's the entire point of having >>>> prototypal inheritance, right? If instead of inheriting and composing you >>>> copy everything as enumerable, writable, and configurable, that's your >>>> choice, not what I believe we all need. >>>> >>>> >>>> >>>> >>>>> You yourself said one shouldn’t use Object.assign for objects with >>>>> behavior in the inheritance chain. And I agree. It’s pretty much only >>>>> useful for data objects (a.k.a plain). Those have no methods in the >>>>> inheritance chain one needs to ignore. >>>>> >>>> >>>> meaning you are good to go with assign or the function I wrote for you. >>>> >>>> >>>> >>>> >>>>> >>>>> Again, I ask, *what is the problem to which ignoring inherited >>>>> properties is the solution to?* >>>>> >>>>> >>>> >>>> [ 1 ] What is the problem in accessing inherited values? >>>> >>>> If you don't want to distinguish them, just don't and use a for/in >>>> >>>> Why do you want now to change Object assign instead of simply using >>>> for/in? This requirement is available since 1999 >>>> >>>> >>>> >>>> >>>>> I posit everyone wants inherited properties. Just half of the people >>>>> have been FUDed into being afraid of inheritance. But arguments based on >>>>> assumptions on what other people want are irrelevant because naive people >>>>> are easy to influence. >>>>> >>>> >>>> You seem to be afraid of inheritance since you want to ignore it and >>>> flat all the properties per each copied/enriched object. >>>> I am back with previous [ 1 ] question then. >>>> >>>> >>>> >>>> >>>>> JSLint is how Douglas Crockford writes his code. That’s not an >>>>> argument for right APIs. JSON.stringify is equally retarded with its >>>>> inconsistent handling of inheritance, but that’s another matter. >>>>> >>>> >>>> You can define you r`toJSON` method that returns the result of the >>>> for/in based function I've written for you. Is that retarded? >>>> >>>> Moreover, you can recreate instances at parse time with a specialized >>>> reviver: https://gist.github.com/WebReflection/87e41c09691edf9432da >>>> Is that retarded? ( maybe this one is :P ) >>>> >>>> >>>> >>>>> >>>>> And as I said below: until everyone also prefixes their obj.name uses >>>>> with hasOwn: `*obj.hasOwnProperty(“name”) && obj.name >>>>> <http://obj.name/>`*, skipping inherited properties is a fool’s >>>>> errand. It causes *inconsistent APIs* because you don’t run your >>>>> options et alii objects through inheritance strippers every time. And you >>>>> shouldn’t. Or does anyone disagree with that? >>>>> >>>> >>>> actually, following your logic you should never access that unless you >>>> are sure it's also enumerable so ... >>>> >>>> `*obj.hasOwnProperty("name")** && **obj.propertyIsEnumerable("name") >>>> && **obj.name <http://obj.name/>`*` >>>> >>>> >>>> >>>>> >>>>> This is a bigger problem than my use of Object.assign. Proliferation >>>>> of Object.assign will prevent everyone else from relying on inheritance. >>>>> And in a prototypal language I find that bad API design. >>>>> >>>> >>>> Precisely ! So use inheritance instead of flattening/hiding it >>>> everywhere. Use dictionaries and for/in when all this does not matter. >>>> >>>> I really don't see, with all possibilities you have to write the way >>>> you want, and a function I wrote for you that does what you need, why >>>> bothering `Object.assign` >>>> >>>> Best Regards >>>> >>>> >>>> >>>> >>>>> >>>>> A. >>>>> >>>>> On Feb 27, 2015, at 15:40, Andrea Giammarchi < >>>>> andrea.giammarchi at gmail.com> wrote: >>>>> >>>>> noone? JSLint doesn't even let you write a for/in loop if you don't >>>>> have `obj.hasOwnProperty(key)` in it, and usually nobody wants inherited >>>>> properties (included methods from old classes/ahem prototypes) reassigned >>>>> everywhere. >>>>> >>>>> If you deal with data objects and dictionaries yuo'll always have a >>>>> flat structure, right? If you don't care about properties descriptors >>>>> (getters and setters) you can always use a for/in >>>>> >>>>> ``` >>>>> function flatEnumerables(a) { >>>>> for (var c, k, i = 1; i < arguments.length; i++) { >>>>> for (k in (c = arguments[i])) a[k] = c[k]; >>>>> } >>>>> return a; >>>>> } >>>>> ``` >>>>> This would do what you are looking for (which is the first time I >>>>> personally read/hear about somebody wanting `Object.assign` to behave like >>>>> a for/in) >>>>> >>>>> Would that work? >>>>> >>>>> Best Regards >>>>> >>>>> >>>>> >>>>> On Fri, Feb 27, 2015 at 12:56 PM, Andri Möll <andri at dot.ee> wrote: >>>>> >>>>>> You are talking about "flatting" all properties, which is an >>>>>> undesired overhead. >>>>>> >>>>>> >>>>>> Umm, Object.assign is as it is because of performance? I don’t think >>>>>> it is nor is that a good reason. Every property access in JavaScript takes >>>>>> inheritance into account and there are thousands more than a Object.assign >>>>>> call here and there. >>>>>> >>>>>> But what's bugging me every time more, is that somebody had a very >>>>>> bad idea to spread `Object.assign` as something good for inheritance or >>>>>> object cloning. >>>>>> >>>>>> Where does this come from? `Object.assign` retrieves properties and >>>>>> ignore getters and setters, is the last tool you want to use as >>>>>> substitution principle because it breaks. >>>>>> >>>>>> >>>>>> Ignores getters? You mean merely reads them? That’s not ignoring. >>>>>> Getters are an implementation detail of an interface. >>>>>> Prototypes aren't only useful for sharing behavior. They’re just as >>>>>> useful for *data objects and value types*. Nothing breaks when you >>>>>> clone or assign them around. >>>>>> >>>>>> Object.assign just read properties from one object and assign them to >>>>>> another. Something you used to do by hand. It’s just shorter to type >>>>>> assign(A, B) than type all properties of B out manually. If it’s _not_ >>>>>> meant to be the function-equivalent of `*for (var key in source) >>>>>> target[key] = source[key]*` then that’s too bad as my money is on >>>>>> it’s going to be used as such. I definitely want to use it for that. >>>>>> >>>>>> But what's bugging me every time more, is that somebody had a very >>>>>> bad idea to spread `Object.assign` as something good for inheritance or >>>>>> object cloning. >>>>>> >>>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>>>> way more problems than a missed flattered structure. >>>>>> Can you explain what is your goal ? Wouldn't this work? >>>>>> >>>>>> >>>>>> Inheritance? Inheritance is an implementation detail. A function >>>>>> receiving an object must not care about its inheritance tree as long as it >>>>>> fulfills the required interface. That’s what the LSP says as well. Even >>>>>> though JavaScript has no explicit concept of interfaces or types, they’re >>>>>> implicit in any function call. >>>>>> >>>>>> My goal is to save people from having to think every time they call a >>>>>> function whether this 3rd party function ignores inherited properties or >>>>>> not. If the callee uses Object.assign, it strips them out, if not, the >>>>>> dot-operator takes it into account. Surely no-one’s expecting everyone to >>>>>> prefix _every_ obj.name use with hasOwn: `*obj.hasOwnProperty(“name”) >>>>>> && obj.name <http://obj.name/>`*. Why do it in Object.assigns then >>>>>> is beyond me. Inconsistent and uncalled for. >>>>>> >>>>>> A. >>>>>> >>>>>> On Feb 27, 2015, at 14:24, Andrea Giammarchi < >>>>>> andrea.giammarchi at gmail.com> wrote: >>>>>> >>>>>> You are talking about "flatting" all properties, which is an >>>>>> undesired overhead. >>>>>> >>>>>> ```js >>>>>> >>>>>> var b = Object.create( >>>>>> Object.getPrototypeOf(a) >>>>>> ); >>>>>> >>>>>> Object.assign(b, a); >>>>>> >>>>>> ``` >>>>>> >>>>>> But what's bugging me every time more, is that somebody had a very >>>>>> bad idea to spread `Object.assign` as something good for inheritance or >>>>>> object cloning. >>>>>> >>>>>> Where does this come from? `Object.assign` retrieves properties and >>>>>> ignore getters and setters, is the last tool you want to use as >>>>>> substitution principle because it breaks. >>>>>> >>>>>> `Object.assign` is good only to define enumerable, writable, and >>>>>> configurable properties, like configuration or setup objects. >>>>>> >>>>>> Are you dealing with prototypes and `Object.assign` ? You gonna have >>>>>> way more problems than a missed flattered structure. >>>>>> >>>>>> Can you explain what is your goal ? Wouldn't this work? >>>>>> >>>>>> ```js >>>>>> >>>>>> var a = {}; // or anything else >>>>>> >>>>>> var b = Object.create( >>>>>> Object.getPrototypeOf(a) >>>>>> ); >>>>>> >>>>>> Object.getOwnPropertyNames(a).forEach(function (k) { >>>>>> Object.defineProperty(b, k, Object.getOwnPropertyDescriptor(a, k)); >>>>>> }); >>>>>> >>>>>> ``` >>>>>> >>>>>> >>>>>> Best Regards >>>>>> >>>>>> >>>>>> >>>>>> On Fri, Feb 27, 2015 at 11:52 AM, Andri Möll <andri at dot.ee> wrote: >>>>>> >>>>>>> Hello, >>>>>>> >>>>>>> Why does Object.assign ignore inherited enumerable properties? >>>>>>> What is the problem to which ignoring inherited properties is the >>>>>>> solution to? >>>>>>> >>>>>>> All I can see is that it prevents a useful use of inheritance. The Liskov >>>>>>> substitution principle >>>>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle> was >>>>>>> mentioned 27 years ago in ’87. Why is Object.assign breaking it? >>>>>>> >>>>>>> - Everyone who’s messing with Object.prototype has to do it an >>>>>>> non-enumerable style anyway. >>>>>>> - Most uses of Object.assign will likely be for objects with a >>>>>>> finite number of keys. Those form specific and implicit types from which >>>>>>> people are likely to read with the dot-operator. That takes inheritance >>>>>>> into account anyway. >>>>>>> >>>>>>> I don’t get the agenda to mess with object inheritance. If one wants >>>>>>> methods to only be in the parent and data on the child (so Object.assign >>>>>>> would only copy data), use a classical language. In a delegation-prototypal >>>>>>> language one should be able to inherit freely because of LSP >>>>>>> <https://en.wikipedia.org/wiki/Liskov_substitution_principle>. >>>>>>> >>>>>>> Andri >>>>>>> >>>>>>> _______________________________________________ >>>>>>> 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/20150227/d1d4552e/attachment-0001.html>
On Fri Feb 27 2015 at 5:31:51 PM Andri Möll <andri at dot.ee> wrote:
Object.assign
has nothing to do with inheritance, that's what I am saying, not just supporting.What is my personal position here is that
Object.assign
is the wrong method/tool/function to do anything prototypal or classical inheritance related.Are we entirely missing each other? I’ve said a few times now: it’s none of the callee’s business if I use inheritance in my options, config, setup or any other plain object (one without behavior). Object.assign must honor that.
I asked in my first email: What is the problem to which ignoring inherited properties is the solution to? If you have an argument that I haven’t refuted yet, please share.
Just search GitHub’s code for assign usage and you’ll see it fucking up inheritance all over the place.
So there is code misusing Object.assign? This operation is not for inheritance, it's for batch property assignment of own properties.
On Fri Feb 27 2015 at 5:31:51 PM Andri Möll <andri at dot.ee> wrote: > `Object.assign` has **nothing to do with inheritance**, that's what I am > saying, not just supporting. > > What is my personal position here is that `Object.assign` is the wrong > method/tool/function to do anything prototypal or classical inheritance > related. > > > Are we entirely missing each other? I’ve said a few times now: it’s _none_ > of the callee’s business if I use inheritance in my options, config, setup > or any other plain object (one without behavior). Object.assign must honor > that. > > I asked in my first email: *What is the problem to which ignoring > inherited properties is the solution to?* > If you have an argument that I haven’t refuted yet, please share. > > Just search GitHub’s code for assign usage and you’ll see it fucking up > inheritance all over the place. > So there is code misusing Object.assign? This operation is _not_ for inheritance, it's for batch property assignment of own properties. Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150227/07e9e9e3/attachment.html>
So there is code misusing Object.assign? This operation is not for inheritance, it's for batch property assignment of own properties.
Sorry, I assumed my point was clear from previous emails and used "fucking up inheritance” as a reference. I meant not that it doesn’t create a new object with the same inheritance tree, but that it ignores inherited properties in the source when assigning them. Properties that when using the dot operator would’ve been taken into account:
opts.silent
vs
opts = Object.assign({}, opts)
opts.silent
What’s the argument for not assigning all enumerable properties? What’s the more important use case over those I’ve described in my previous emails?
A.
> So there is code misusing Object.assign? This operation is _not_ for inheritance, it's for batch property assignment of own properties. Sorry, I assumed my point was clear from previous emails and used "fucking up inheritance” as a reference. I meant not that it doesn’t create a new object with the same inheritance tree, but that it ignores inherited properties in the source when assigning them. Properties that when using the dot operator would’ve been taken into account: ``` opts.silent ``` vs ``` opts = Object.assign({}, opts) opts.silent ``` What’s the argument for not assigning all enumerable properties? What’s the more important use case over those I’ve described in my previous emails? A. On Feb 28, 2015, at 01:58, Rick Waldron <waldron.rick at gmail.com> wrote: > > > On Fri Feb 27 2015 at 5:31:51 PM Andri Möll <andri at dot.ee> wrote: >> `Object.assign` has **nothing to do with inheritance**, that's what I am saying, not just supporting. > >> What is my personal position here is that `Object.assign` is the wrong method/tool/function to do anything prototypal or classical inheritance related. > > > Are we entirely missing each other? I’ve said a few times now: it’s _none_ of the callee’s business if I use inheritance in my options, config, setup or any other plain object (one without behavior). Object.assign must honor that. > > I asked in my first email: What is the problem to which ignoring inherited properties is the solution to? > If you have an argument that I haven’t refuted yet, please share. > > Just search GitHub’s code for assign usage and you’ll see it fucking up inheritance all over the place. > > So there is code misusing Object.assign? This operation is _not_ for inheritance, it's for batch property assignment of own properties. > > Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150228/be8febc8/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4786 bytes Desc: not available URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150228/be8febc8/attachment-0001.p7s>
On 27/02/2015, at 16:16, Andri Möll wrote:
because every object inherits from Object.prototype
[ {} instanceof Object, Object.create(null) instanceof Object ] -> [true, false]
On 27/02/2015, at 16:16, Andri Möll wrote: >> because every object inherits from Object.prototype [ {} instanceof Object, Object.create(null) instanceof Object ] -> [true, false] -- ( Jorge )();
Hello,
Why does Object.assign ignore inherited enumerable properties? What is the problem to which ignoring inherited properties is the solution to?
All I can see is that it prevents a useful use of inheritance. The Liskov substitution principle was mentioned 27 years ago in ’87. Why is Object.assign breaking it?
I don’t get the agenda to mess with object inheritance. If one wants methods to only be in the parent and data on the child (so Object.assign would only copy data), use a classical language. In a delegation-prototypal language one should be able to inherit freely because of LSP.
Andri