Максимальное кол-во Геттеров и Сеттеров

Искал информацию в оф. документациях, но так ничего и не нашел.

Какое максимально количество Getter и Setter может быть в одном объекте?

Правильно ли вообще в одном объекте устанавливать больше одного Getter и Setter?

Пример кода:

let obj = {};

Object.defineProperties(obj,{

getterAndSetter:{
set(setName){
//Какой-то код      
},

set(setAge){
//Какой-то код  
},

get(){
//Какой-то код      
},

get(){
//Какой-то код      
}   
},
})

Ответы (4 шт):

Автор решения: Alexey Ten

У вас написана какая-то глупость. В объекте по определению не может быть повторяющихся ключей, так что ваша запись:

{
set(setName){
//Какой-то код      
},

set(setAge){
//Какой-то код  
},

get(){
//Какой-то код      
},

get(){
//Какой-то код      
}   
}

эквивалентна

{
/*
set(setName){
//Какой-то код      
},
*/
set(setAge){
//Какой-то код  
},
/*
get(){
//Какой-то код      
},
*/
get(){
//Какой-то код      
}   
}

т.е. из одноимённых свойств игнорируются все кроме последнего.

Именно поэтому непонятно чего же вы хотите добиться этим кодом.

→ Ссылка
Автор решения: Zoodogood
let obj = {
    get name(){ /* */ }
}

Используйте ключевые слова get илиset перед именем свойства


В случае Object.defineProperties Вы немного запутались:
То что Вы вводили похоже на синтаксис к функции defineProperty, возможно, искали в нескольких источниках.

Правильное написание будет таким:

Object.defineProperties(obj, {
  "getAge": {
      get: () => {/**/}
   },
   "setAge": {
      ...
    },
   ...
})

или для defineProperty

Object.property(obj, "getAge",  { get: () => {/**/} });

Пояснение: во всех трёх случаях мы указываем имя свойства

→ Ссылка
Автор решения: Qwertiy

Много. Похоже, пока память не кончится.

~async function() {
  for (var obj=Object.create(null), n=0; ; ++n) {
    try {
      Object.defineProperty(obj, n, {
        get() { return 0 },
        set(x) {},
      })
    } catch (err) {
      console.log("Added " + n + " props", err)
    }

    if (n % 1000000 === 0) {
      console.log(`Keys: ${n}\nMemory: ${performance.memory.usedJSHeapSize}`)
      await new Promise(resolve => setTimeout(resolve, 100))
    }
  }
}()
.as-console-wrapper.as-console-wrapper { max-height: 100vh }

→ Ссылка
Автор решения: Grundy

Явного ограничения на количество свойств (полей, методов) в объекте нет.


Object.defineProperties позволяет определить сразу несколько свойств у объекта. Для этого, вторым параметром в данный метод передается объект настроек, имеющий следующую структуру:

{
    [propertyName]: propertyDescriptor
}

То есть, каждый ключ объекта отвечает за имя нового свойства, значение, соответствующее этому ключу определяет тип и настройки нового свойства.

Свойства в объекте могут быть двух типов:

  1. Свойства, которые непосредственно хранят какие-то данные. Данному типу соответствует следующая структура propertyDescriptor

    {
        value: ... // определяет значение свойства
        writable: boolean // определяет, можно ли изменить значение свойства с помощью оператора присваивания
        // общие настройки 
        enumerable: boolean // определяет перечислимое ли свойство
        configurable: boolean // определяет, можно ли удалить свойство либо изменить его тип
    }
    
  2. Свойства, которые могут предоставлять доступ к каким-то данным. Данному типу соответствует следующая структура propertyDescriptor

    {
        get: function(){...} // определяет getter
        set: function(value){...}// определяет setter
        // общие настройки 
        enumerable: boolean // определяет перечислимое ли свойство
        configurable: boolean // определяет, можно ли удалить свойство либо изменить его тип
    }
    

В коде в вопросе идет попытка передать некорректный propertyDescriptor для свойства getterAndSetter вместо этого необходимо было сделать два отдельных свойства для name и age

let obj = {};

Object.defineProperties(obj, {

  name: {
    set(value) {
      console.log('set name:', value);
    },
    get() {
      console.log('get name');
    },
  },
  age: {
    set(value) {
      console.log('set age:', value);
    },
    get() {
      console.log('get age');
    }
  }
});

obj.name = "new name";
obj.name;
obj.age = "new age";
obj.age;

В примере выше видно, что для обоих свойств вызываются и геттеры и сеттеры.

Так как эти свойства не хранят данные, чтобы значения запоминались нужно либо добавить соответствующие свойства, либо сохранять/получать значения из каких либо других переменных:

var globalAge = 10;
let obj = {};

Object.defineProperties(obj, {
  $name: {
    value: 'Name',
    writable: true
  },
  name: {
    set(value) {
      console.log('set name:', value);
      this.$name = value;
    },
    get() {
      console.log('get name');
      return this.$name;
    },
  },
  age: {
    set(value) {
      console.log('set age:', value);
      globalAge = value;
    },
    get() {
      console.log('get age');
      return globalAge;
    }
  }
});

console.log('obj.name:', obj.name);
obj.name = "new name";
console.log('obj.name:', obj.name);

console.log('obj.age:', obj.age);
obj.age = "new age";
console.log('obj.age:', obj.age);

→ Ссылка