Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   JS.next(стандарты, фичи, движки) (https://javascript.ru/forum/offtopic/50248-js-next-standarty-fichi-dvizhki.html)

nerv_ 29.09.2015 16:55

Как сделать свойства перебираемыми при описании геттеров/сеттеров es6?
'use strict';

const __PROP = Symbol();

class Foo {
  constructor() {
    this.prop = 1;
  }
  get prop() {
    return this[__PROP];
  }
  set prop(value) {
    this[__PROP] = value;
  }
}

let bar = new Foo();

console.log(bar.prop); // 1
console.log(Object.keys(bar)); // []



Это возможно БЕЗ пронографии вида?
'use strict';


const __PROP = Symbol();


class Foo {
  constructor() {
    Object.defineProperty(this, 'prop', {
        enumerable: true,
        get() {
            return this[__PROP];
        },
        set(value) {
            this[__PROP] = value;
        }
    });
    this.prop = 1;
  }
}


let bar = new Foo()


console.log(bar.prop); // 1
console.log(Object.keys(bar)); // ["prop"]

FINoM 29.09.2015 17:01

nerv_, полагаю, никак. А в каких задачах ты юзаешь акцессоры, если не секрет?

nerv_ 29.09.2015 17:20

Цитата:

Сообщение от FINoM
А в каких задачах ты юзаешь акцессоры

много где :) Например, при работе с localStorage.

Допустим:
store.prop // читает из localStorage
store.prop = 1 // пишет в localStorage

FINoM 29.09.2015 17:47

nerv_, я просто не могу упустить возможности порекомендовать тебе заюзать Матрешку. Сейчас функции, которые работают с объектами вынесены в небольшую либу, которая находится в папке /magic репки.
class Foo {
  constructor() {
    magic.on(this, 'change:prop', evt => localStorage.prop = this.prop);
  }
}


И не нужно городить огороды с символами.

trikadin 29.09.2015 19:14

nerv_, так ты тут хочешь сделать enumerable свойство, которое объявлено в прототипе объекта. Если ты хочешь, чтобы оно было доступно именно в объекте, то придётся объявлять его на самом объекте, ничего не попишешь :С

Если у тебя таких свойств много -- сделай ф-цию, которая будет пробегать по obj.__proto__, находить все элементы, для которых Object.getOwnPropertyDescriptor возвращает объект, в котором есть геттер, и ставить их самому объекту. Это, конечно, тоже извращение, но хотя бы инкапсулированное извращение.

trikadin 29.09.2015 19:30

Во, меня проперло)

Посмотреть.

devote 30.09.2015 00:12

'use strict';

const __PROP = Symbol();

class Foo {
  constructor() {
    Object.getOwnPropertyNames(this.__proto__).forEach((key) => {
      var descriptor = Object.getOwnPropertyDescriptor(this.__proto__, key);
      if (descriptor && (typeof descriptor.get === "function" || typeof descriptor.set === "function")) {
        descriptor.enumerable = true;
        Object.defineProperty(this, key, descriptor);
      }
    });



    this.prop = 1;
  }

  get prop() {
    return this[__PROP];
  }

  set prop(value) {
    this[__PROP] = value;
  }
}

let bar = new Foo();

console.log(bar.prop); // 1
console.log(Object.keys(bar)); // ["prop"]

trikadin 30.09.2015 00:15

devote, лаконичнее, плюсую) Не додумался использовать объект, полученный от Object.getOwnPropertyDescriptor, использовать в Object.defineProperty)

nerv_ 01.10.2015 13:27

Цитата:

Сообщение от FINoM
я просто не могу упустить возможности порекомендовать тебе заюзать Матрешку

Зачем она здесь? В моем примере символ для:
1. приватности
2. скорости набора кода
3. лучшего сжатия кода

Цитата:

Сообщение от trikadin
так ты тут хочешь сделать enumerable свойство, которое объявлено в прототипе объекта.

нет другого способа в es6 объявлять геттеры и сеттеры в классах

devote, спасибо.
Цитата:

Сообщение от devote
var self = this;

не надо (на первый взгляд), т.к. arrow function

Я для наглядности для себя сделал так
'use strict';


const __PROP = Symbol();


class Foo {
  constructor() {
    this.__setEnumerable('prop', true);
    this.prop = 1;
  }
  get prop() {
    return this[__PROP];
  }
  set prop(value) {
    this[__PROP] = value;
  }
  __setEnumerable(prop, state) {
    let prototype = this.constructor.prototype;
    let descriptor = Object.getOwnPropertyDescriptor(prototype, prop);
    descriptor.enumerable = state;
    Object.defineProperty(this, prop, descriptor);
  }
}


let bar = new Foo();

console.log(bar.prop); // 1
console.log(Object.keys(bar)); // ["prop"]


Жалко, что так нельзя:
class Foo {
  constructor() {
    this.prop.__enumerable = true;
    this.prop = 1;
  }
}

FINoM 01.10.2015 13:32

Цитата:

Сообщение от nerv_
1. приватности
2. скорости набора кода
3. лучшего сжатия кода

Я ничего не навязываю, просто не совсем тебя понимаю.

1. В матрешке вся информация о "специальных" свойствах хранится в свойстве-объекте Symbol(matreshka).
2. Эм, тут вообще не понял. Твой синтаксис с символами выглядит жирно.
3. А сжатие тут причем? Или ты имеешь в виду, что не хочешь тащить зависимость? Тогда ОК.


Часовой пояс GMT +3, время: 20:51.