> 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 <[email protected]> 
wrote:

> answering inline ...
> 
> On Fri, Feb 27, 2015 at 2:22 PM, Andri Möll <[email protected]> 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 <[email protected]> 
> 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 <[email protected]> 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 <[email protected]> 
>> 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 <[email protected]> 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
>>> [email protected]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>> 
>>> 
>> 
>> 
> 
> 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to