Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Ignoring properties #37

Open
ashsearle opened this issue Mar 20, 2017 · 5 comments
Open

Ignoring properties #37

ashsearle opened this issue Mar 20, 2017 · 5 comments

Comments

@ashsearle
Copy link

There's a little bit of discussion in issue #16 about filtering or ignoring properties.

let x = {a: 1, b: 2, c: 3, md5: '83b0f2d70d7546ee634f801264c4a9b3'};
let { md5, ...y } = x;

The problem with this is the introduction of the unwanted variable md5. This can be avoided by using:

let { md5: {}, ...y } = x;

This approach also works with computed property names:

let x = {a: 1, b: 2, c: 3, md5: '83b0f2d70d7546ee634f801264c4a9b3'};
let omit = 'md5';
let { [omit]: {}, ...y } = x;

However, this code is at risk of a Cannot destructure undefined error if the property value is null or undefined.

We need another way.

Array destructing allows this:

let x = [1, 2, 3]
let [ , ...y ] = x; // → y = [2, 3]

Perhaps this would the closest comparable syntax:

let x = {a: 1, b: 2, c: 3, md5: '83b0f2d70d7546ee634f801264c4a9b3'};
let { md5:, ...y } = x;

let omit = 'md5';
let { [omit]:, ...z } = x;

Does this proposal require anything other than making the AssignmentElement optional in the AssignmentProperty production?

@YarnSphere
Copy link

Not sure this is relevant; just adding to the discussion.

Note that in the array case, this is valid syntax:

let x = [1, , 3]

Whereas for objects, this isn't:

let x = {a: 1, b: , c: 3}

Still, I like your proposal; seems better than using a variable name such as _ as proposed in Known Issues.

@YarnSphere
Copy link

On another note, what about spreading?

let o = {a: 1, b: 2}
let oCloneMinusB = {...o, b: }

Should this be supported?
In this case "b" in oCloneMinusB should return false; i.e. b shouldn't be set to undefined.

@ashsearle
Copy link
Author

Using a legal variable name such as _ seems like a bad idea to me. But using null would make some semantic sense (comparable to sending things to /dev/null.)

I'd be happy with:

let x = {a: 1, b: 2, c: 3, md5: '83b0f2d70d7546ee634f801264c4a9b3'};
let { md5: null, ...y } = x;

let omit = 'md5';
let { [omit]: null, ...z } = x;

But if that was supported, I'd expect to be able to do something similar with arrays:

let x = [1, 2, 3]
let [null, ...y ] = x; // → y = [2, 3]

@Jamesernator
Copy link

I definitely wouldn't like to see special casing _, null makes some intuitive sense, however I think the most obvious would be something like void or ! (from the other thread) would make more sense at a glance:

let { void md5, a, b, ...z } = x
// Or
let { !md5, a, b, ...z } = x

The easiest way for now would just be to use a function:

function skip(obj, props) {
    const result = { ...obj };
    for (const prop in props) {
        delete result[prop]
    }
    return result
}

let { a, b, ...z } = skip(x, ['md5'])

// And if either the bind or pipeline operator is added it could be improved
// to something more readable:
let { a, b, ...z } = x::skip('md5', ...othersToSkip)
let { a, b, ...z } = x |> skip('md5', ...othersToSkip)

@ashsearle
Copy link
Author

@nunocastromartins I'd like to respond to a couple of things in your comments:

let x = [1, , 3];
console.log(Object.keys(x)); // ["0", "2"]

There would be no benefit to supporting this syntax in object literals:

let x = {a: 1, b: , c: 3}
console.log(Object.keys(x)); // ["a", "c"] - so why mention 'b' at all?

To address your second comment: no I don't think that syntax should be supported; mainly because there's nothing comparable to support spreading arrays while excluding specific indexes.

Note: your example would naturally be written as:

let o = {a: 1, b: 2}
// let oCloneMinusB = {...o, b: } // not supported
let { b:, ...oCloneMinusB } = o; // do this instead

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants