rest getters and setters (sorry, __noSuchMethod__ again)

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

rest getters and setters (sorry, __noSuchMethod__ again)

Tobias Buschor-2
I realy like the possibility to react to dynamic properties, like what you can do with Proxies.
But Proxies are not the (my) perfect solution.


```
class items {
    constructor() {
        return new Proxy(this, {
            get(target, name) {
                if (name[0] === '$') return target.getItem(name.substr(1)).value;
                return target[name];
            }
        });
    }
    getItem(id) {
        return this._item[id];
    }
}

myItems = new items(); // [1]
myItems.$1
```

[1] this direct returns a Proxy for the newly created Object, ok..
i can do "myItems.$3" instead of "myItems.getItem(4)";


but i can not act like this inside the Object, because i am not working with the Proxy

```
class items {
    getItem3(){
        return this.$3;
    }
}
```

I have to do this instead...

```
class items {
    getItem3(){
        return this.getItem(3);
    }
}
```

What about something like getters and setters for the rest (undefined properties)?

```
class items {
    get...(name){
        if (name[0] === '$') return this.getItem(name.substr(1)).value;
    }
    set...(name, value){
        // implement setter for unknown
    }
}
```


Maybe a stupid idea and certainly not thought through.
But what do you think?






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: rest getters and setters (sorry, __noSuchMethod__ again)

Logan Smyth
but i can not act like this inside the Object, because i am not working with the Proxy

You're not quite taking into account the behavior of `this` in JS. `this` is set at call-time, so when you do

```
class items {
    // ...

    getItem3(){
        return this.$3;
    }
}
```

`this` depends on how `getItem3` was called. In your case if you do

```
myItems = new items();
myItems.getItem3();
```
`this` will be `myItems` because that is how you have called it, meaning that `getItems3()` will behave just like if you had done `myItems.$3`.

Your code works as expected in this Fiddle: https://jsfiddle.net/2dgefd9d/

On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor <[hidden email]> wrote:
I realy like the possibility to react to dynamic properties, like what you can do with Proxies.
But Proxies are not the (my) perfect solution.


```
class items {
    constructor() {
        return new Proxy(this, {
            get(target, name) {
                if (name[0] === '$') return target.getItem(name.substr(1)).value;
                return target[name];
            }
        });
    }
    getItem(id) {
        return this._item[id];
    }
}

myItems = new items(); // [1]
myItems.$1
```

[1] this direct returns a Proxy for the newly created Object, ok..
i can do "myItems.$3" instead of "myItems.getItem(4)";


but i can not act like this inside the Object, because i am not working with the Proxy

```
class items {
    getItem3(){
        return this.$3;
    }
}
```

I have to do this instead...

```
class items {
    getItem3(){
        return this.getItem(3);
    }
}
```

What about something like getters and setters for the rest (undefined properties)?

```
class items {
    get...(name){
        if (name[0] === '$') return this.getItem(name.substr(1)).value;
    }
    set...(name, value){
        // implement setter for unknown
    }
}
```


Maybe a stupid idea and certainly not thought through.
But what do you think?






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



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: rest getters and setters (sorry, __noSuchMethod__ again)

Tobias Buschor-2
wow, you are right!

But this does not work.
It returns "undefined"

```
class items {
    // ...
    get item3(){
        return this.$3;
    }
}
```

```
myItems = new items();
console.log( myItems.item3 );
```


I see, the getter is called on the object itself and not on the proxy....











2017-07-29 2:05 GMT+02:00 Logan Smyth <[hidden email]>:
but i can not act like this inside the Object, because i am not working with the Proxy

You're not quite taking into account the behavior of `this` in JS. `this` is set at call-time, so when you do

```
class items {
    // ...

    getItem3(){
        return this.$3;
    }
}
```

`this` depends on how `getItem3` was called. In your case if you do

```
myItems = new items();
myItems.getItem3();
```
`this` will be `myItems` because that is how you have called it, meaning that `getItems3()` will behave just like if you had done `myItems.$3`.

Your code works as expected in this Fiddle: https://jsfiddle.net/2dgefd9d/

On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor <[hidden email]> wrote:
I realy like the possibility to react to dynamic properties, like what you can do with Proxies.
But Proxies are not the (my) perfect solution.


```
class items {
    constructor() {
        return new Proxy(this, {
            get(target, name) {
                if (name[0] === '$') return target.getItem(name.substr(1)).value;
                return target[name];
            }
        });
    }
    getItem(id) {
        return this._item[id];
    }
}

myItems = new items(); // [1]
myItems.$1
```

[1] this direct returns a Proxy for the newly created Object, ok..
i can do "myItems.$3" instead of "myItems.getItem(4)";


but i can not act like this inside the Object, because i am not working with the Proxy

```
class items {
    getItem3(){
        return this.$3;
    }
}
```

I have to do this instead...

```
class items {
    getItem3(){
        return this.getItem(3);
    }
}
```

What about something like getters and setters for the rest (undefined properties)?

```
class items {
    get...(name){
        if (name[0] === '$') return this.getItem(name.substr(1)).value;
    }
    set...(name, value){
        // implement setter for unknown
    }
}
```


Maybe a stupid idea and certainly not thought through.
But what do you think?






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





--
Freundliche Grüsse
Tobias Buschor

shwups GmbH
Unterlindenberg 206
9427 Wolfhalden

+41 76 321 23 21
shwups.ch


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: rest getters and setters (sorry, __noSuchMethod__ again)

Logan Smyth
I almost mentioned that last time, alas. You have a bug in your proxy `get` handler. It should be:
```
get(target, name, receiver) {
    if (name[0] === '$') return target.getItem(name.substr(1));

    return Reflect.get(target, name, receiver);
}
```
The third argument `receiver` being the important part here. `Reflect.get(target, name, receiver)` is the correct reproduction of the default non-proxy `get` behavior. `target[name]` is close, but loses information, causing the bad behavior you are seeing. `target` is the actual target initially passed to `new Proxy`, while `receiver` is the object that was actually used to access the property, which is the actual proxy object in this case.


On Fri, Jul 28, 2017 at 5:37 PM, Tobias Buschor <[hidden email]> wrote:
wow, you are right!

But this does not work.
It returns "undefined"

```
class items {
    // ...
    get item3(){
        return this.$3;
    }
}
```

```
myItems = new items();
console.log( myItems.item3 );
```


I see, the getter is called on the object itself and not on the proxy....











2017-07-29 2:05 GMT+02:00 Logan Smyth <[hidden email]>:
but i can not act like this inside the Object, because i am not working with the Proxy

You're not quite taking into account the behavior of `this` in JS. `this` is set at call-time, so when you do

```
class items {
    // ...

    getItem3(){
        return this.$3;
    }
}
```

`this` depends on how `getItem3` was called. In your case if you do

```
myItems = new items();
myItems.getItem3();
```
`this` will be `myItems` because that is how you have called it, meaning that `getItems3()` will behave just like if you had done `myItems.$3`.

Your code works as expected in this Fiddle: https://jsfiddle.net/2dgefd9d/

On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor <[hidden email]> wrote:
I realy like the possibility to react to dynamic properties, like what you can do with Proxies.
But Proxies are not the (my) perfect solution.


```
class items {
    constructor() {
        return new Proxy(this, {
            get(target, name) {
                if (name[0] === '$') return target.getItem(name.substr(1)).value;
                return target[name];
            }
        });
    }
    getItem(id) {
        return this._item[id];
    }
}

myItems = new items(); // [1]
myItems.$1
```

[1] this direct returns a Proxy for the newly created Object, ok..
i can do "myItems.$3" instead of "myItems.getItem(4)";


but i can not act like this inside the Object, because i am not working with the Proxy

```
class items {
    getItem3(){
        return this.$3;
    }
}
```

I have to do this instead...

```
class items {
    getItem3(){
        return this.getItem(3);
    }
}
```

What about something like getters and setters for the rest (undefined properties)?

```
class items {
    get...(name){
        if (name[0] === '$') return this.getItem(name.substr(1)).value;
    }
    set...(name, value){
        // implement setter for unknown
    }
}
```


Maybe a stupid idea and certainly not thought through.
But what do you think?






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





--
Freundliche Grüsse
Tobias Buschor

shwups GmbH
Unterlindenberg 206
9427 Wolfhalden

<a href="tel:+41%2076%20321%2023%2021" value="+41763212321" target="_blank">+41 76 321 23 21
shwups.ch



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: rest getters and setters (sorry, __noSuchMethod__ again)

Tobias Buschor-2
Ok, thank you Logan.

Still have to digest :)

I'm now fine with proxies, you can ignore this post.



2017-07-29 2:50 GMT+02:00 Logan Smyth <[hidden email]>:
I almost mentioned that last time, alas. You have a bug in your proxy `get` handler. It should be:
```
get(target, name, receiver) {
    if (name[0] === '$') return target.getItem(name.substr(1));

    return Reflect.get(target, name, receiver);
}
```
The third argument `receiver` being the important part here. `Reflect.get(target, name, receiver)` is the correct reproduction of the default non-proxy `get` behavior. `target[name]` is close, but loses information, causing the bad behavior you are seeing. `target` is the actual target initially passed to `new Proxy`, while `receiver` is the object that was actually used to access the property, which is the actual proxy object in this case.


On Fri, Jul 28, 2017 at 5:37 PM, Tobias Buschor <[hidden email]> wrote:
wow, you are right!

But this does not work.
It returns "undefined"

```
class items {
    // ...
    get item3(){
        return this.$3;
    }
}
```

```
myItems = new items();
console.log( myItems.item3 );
```


I see, the getter is called on the object itself and not on the proxy....











2017-07-29 2:05 GMT+02:00 Logan Smyth <[hidden email]>:
but i can not act like this inside the Object, because i am not working with the Proxy

You're not quite taking into account the behavior of `this` in JS. `this` is set at call-time, so when you do

```
class items {
    // ...

    getItem3(){
        return this.$3;
    }
}
```

`this` depends on how `getItem3` was called. In your case if you do

```
myItems = new items();
myItems.getItem3();
```
`this` will be `myItems` because that is how you have called it, meaning that `getItems3()` will behave just like if you had done `myItems.$3`.

Your code works as expected in this Fiddle: https://jsfiddle.net/2dgefd9d/

On Fri, Jul 28, 2017 at 4:48 PM, Tobias Buschor <[hidden email]> wrote:
I realy like the possibility to react to dynamic properties, like what you can do with Proxies.
But Proxies are not the (my) perfect solution.


```
class items {
    constructor() {
        return new Proxy(this, {
            get(target, name) {
                if (name[0] === '$') return target.getItem(name.substr(1)).value;
                return target[name];
            }
        });
    }
    getItem(id) {
        return this._item[id];
    }
}

myItems = new items(); // [1]
myItems.$1
```

[1] this direct returns a Proxy for the newly created Object, ok..
i can do "myItems.$3" instead of "myItems.getItem(4)";


but i can not act like this inside the Object, because i am not working with the Proxy

```
class items {
    getItem3(){
        return this.$3;
    }
}
```

I have to do this instead...

```
class items {
    getItem3(){
        return this.getItem(3);
    }
}
```

What about something like getters and setters for the rest (undefined properties)?

```
class items {
    get...(name){
        if (name[0] === '$') return this.getItem(name.substr(1)).value;
    }
    set...(name, value){
        // implement setter for unknown
    }
}
```


Maybe a stupid idea and certainly not thought through.
But what do you think?






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





--
Freundliche Grüsse
Tobias Buschor

shwups GmbH
Unterlindenberg 206
9427 Wolfhalden

<a href="tel:+41%2076%20321%2023%2021" value="+41763212321" target="_blank">+41 76 321 23 21
shwups.ch



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




--
Freundliche Grüsse
Tobias Buschor

shwups GmbH
Unterlindenberg 206
9427 Wolfhalden

+41 76 321 23 21
shwups.ch


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: rest getters and setters (sorry, __noSuchMethod__ again)

Allen Wirfs-Brock
In reply to this post by Logan Smyth

On Jul 28, 2017, at 5:50 PM, Logan Smyth <[hidden email]> wrote:


    return Reflect.get(target, name, receiver);
}
```
The third argument `receiver` being the important part here. `Reflect.get(target, name, receiver)` is the correct reproduction of the default non-proxy `get` behavior. `target[name]` is close, but loses information, causing the bad behavior you are seeing. `target` is the actual target initially passed to `new Proxy`, while `receiver` is the object that was actually used to access the property, which is the actual proxy object in this case.


yes, the is exactly the reason for the 3rd parameter of Reflect.get

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