Вопрос об эффективности закрытия / инкапсуляции в JavaScript - PullRequest
8 голосов
/ 13 июня 2011

Я немного новичок в JavaScript, так что терпите меня, если это глупый вопрос.

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

var obj = function () {
    var val;
    return {
        setVal: function(newVal) {
            val = newVal;
        },
        getVal: function() {
            return val;
        }
    };
};

Предполагая, что мой синтаксис правильный, это определяет класс с "частным" свойством с именем "value", с методами для установки / получения свойства. Теперь я создам два объекта из этого класса:

var myObj = obj();
var yourObj = obj();

Создает ли это отдельный метод setVal () и getVal () для каждого объекта? Если нет, то почему? Если так, это серьезная проблема при создании эффективных веб-приложений? Стоит ли компромисс (если есть) эффективности с закрытием в большинстве / всех контекстах? Я тупой?

Спасибо, Gerard

Ответы [ 2 ]

3 голосов
/ 13 июня 2011
var obj = function () {
    var val;
    return {
        setVal: function(newVal) {
            val = newVal;
        },
        getVal: function() {
            return val;
        }
    };
};

что эта функция делает следующим образом:

  • создает переменную с именем val
  • создает новый объект
  • создает новую функцию и назначаетв поле setVal
  • создайте новую функцию и назначьте ее в поле getVal
  • возвращаемый объект.

Таким образом, вы всегда создаете 4 новые вещи.

На самом деле это не проблема, если на странице меньше 1000 объектов.Рефакторинг его - это микрооптимизация.

Альтернативой может быть не полагаться на локальные переменные и использовать this._val, чтобы указать, что val является частным.

0 голосов
/ 13 июня 2011

Концептуально.Однако, поскольку это такой распространенный шаблон, современные JIT-разработчики JavaScript знают, как его оптимизировать, чтобы в памяти хранилась только одна копия кода с соответствующими перенаправлениями указателей, чтобы он работал с соответствующим закрытием.

РЕДАКТИРОВАТЬ: хотя я не очень разбираюсь в исходном коде, вот несколько основных доказательств. Загрузите выпуск канала Chrome dev и сделайте снимки кучи до и после запуска следующего кода:

var obj = /* as above */;

var objs = [];
for (var i = 0; i < 10000; ++i) {
    objs.push(obj());
}

Затем сделайте то же самое для этого кода:

function Obj() { }
Obj.prototype.setVal = function (value) { this._val = value; };
Obj.prototype.getVal = function () { return this._val; };

var objs = [];
for (var i = 0; i < 10000; ++i) {
    objs.push(new Obj());
}

В обоих случаях вы найдете снимки кучи, которые показывают одинаковые числа для «кода», так что, действительно, описанная мной оптимизация выполняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...