Создайте класс JS: IIFE и прототип возврата

Посмотрим на два примера, в которых я попытаюсь объяснить, что я хочу понять.

var Car = function(){
  // Init class
  function Car() { };
  // Private func/vars
  var private = { color:'red' };
  // Public func/vars
  Car.prototype = {
    newColor: function(color) { private.color = color },
    getColor: function() { return private.color }
  };

  return Car.prototype; // return with prototype
};

var myCar = new Car();

и

var Car = (function(){
  // Init class
  function Car() { };
  // Private func/vars
  var private = { color:'red' };
  // Public func/vars
  Car.prototype = {
    newColor: function(color) { private.color = color },
    getColor: function() { return private.color }
  };

  return Car; // avoid prototype adding parentheses on next line;
})();

var myCar = new Car();

Посмотрим!, Оба класса создаются как выражение функции, и оба работают одинаково. Единственные различия между ними: Первый возвращает функцию Car со свойством прототипа. Вторая работа возвращает функцию Car, избегая свойства прототипа и вместо этого использует IIFE.

В чем разница между использованием return Car.prototype; и избежанием IIFE и использованием return Car; с использованием IIFE (круглые скобки в конце объявления класса).

Ответ 1

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

Первый пример - бит нечетный и не совсем корректно создает конструктор. Строка

return Car.prototype; // return with prototype

заставляет функцию Car просто всегда возвращать литерал объекта, который вы ранее назначили Car.prototype. Это переопределяет нормальное поведение функции, вызываемой с помощью new


Отметим только одну вещь:

Car.prototype = {
   newColor: function(color) { private.color = color },
   getColor: function() { return private.color }
};

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

Car.prototype = {
   newColor: function(color) { private.color = color },
   getColor: function() { return private.color }
};
Car.prototype.constructor = Car;   // <-------- add this line

Или измените приведенное выше на

Car.prototype.newColor = function(color) { private.color = color };
Car.prototype.getColor = function() { return private.color };