Подтвердить что ты не робот

Являются ли частные члены javascript в классах причиной огромных издержек памяти?

В JavaScript поля объекта всегда "общедоступны":

function Test() {
  this.x_ = 15;
}
Test.prototype = {
  getPublicX: function() {
    return this.x_;
  }
};
new Test().getPublicX();       // using the getter
new Test().x_;                 // bypassing the getter

но вы можете имитировать поле "private", используя локальную переменную и используя закрытие в качестве получателя:

function Test() {
  var x = 15;
  this.getPrivateX = function() {
    return x;
  };
}
new Test().getPrivateX();       // using the getter
// ... no way to access x directly: it a local variable out of scope

Одно из отличий заключается в том, что при "общедоступном" подходе каждый экземпляр getter является одним и тем же функциональным объектом:

console.assert(t1.getPublicX === t2.getPublicX);

тогда как при подходе "private" каждый экземпляр getter представляет собой отдельный объект функции:

console.assert(t1.getPrivateX != t2.getPrivateX);

Мне интересно об использовании этого подхода в памяти. Поскольку каждый экземпляр имеет отдельный getPrivateX, это вызовет огромные издержки памяти, если я создам, скажем, 10k экземпляры?

Тест производительности при создании экземпляров классов с частными и открытыми членами:

Jsperf

4b9b3361

Ответ 1

Конечно, это создало бы издержки памяти. В публичном случае ваша функция относится к prototype не к экземпляру, что означает, что есть только один экземпляр, если только вы специально не даете конкретному объекту собственный экземпляр этой функции. В частном случае функция принадлежит экземпляру, что означает, что вам необходимо выполнить управление памятью.

Я имею в виду следующее:

var t1 = new Test();
t1.getPublicX = function () {
    return true;
}

var t2 = new Test();

t1.getPublicX(); // Returns true
t2.getPublicX(); // Returns 15

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

Я также должен добавить, что понятие public и private в javascript не совсем то же самое, что и в C++. В C++ private инкапсулирует член для доступа только изнутри класса, который в javascript вы все равно можете получить доступ к элементу из любого места.

И еще после короткого теста накладные расходы на самом деле несущественны. Вкладка занимает более 40 МБ (с загрузкой Google), чем без нее, как показано на скриншоте ниже:

enter image description here

Ссылка на полноразмерное изображение.