Почему coffeescript генерирует такие классы? - PullRequest
7 голосов
/ 12 января 2011

С учетом следующего кода coffeescript:

class Animal
  constructor: (@name) ->
  speak: (things) -> "My name is #{@name} and I like #{things}"

Это генерируется:

var Animal = (function() {
  function Animal(name) {
    this.name = name;
  }
  Animal.prototype.speak = function(things) {
    return "My name is " + this.name + " and I like " + things;
  };
  return Animal;
})();

Но почему не генерируется этот более идиоматический код?

var Animal = function Animal(name) {
  this.name = name;
};
Animal.prototype.speak = function(things) {
  return "My name is " + this.name + " and I like " + things;
};

Я знаю, что coffeescript оборачивает множество вещей в анонимных функциях, чтобы контролировать утечку области, но что здесь может быть утечка?

Ответы [ 3 ]

12 голосов
/ 12 января 2011

Сгенерированный код позволяет надежно иметь именованные функции в Internet Explorer. (В данном случае «Animal».) Если вы просто используете именованную функцию в области видимости верхнего уровня, она будет конфликтовать с любыми объявлениями var Animal =, которые могут присутствовать ... даже в более низких областях, что будет препятствовать правильной ссылке , Чтобы обойти ошибку IE, мы включаем функцию-обертку вокруг определения класса.

2 голосов
/ 18 августа 2012

Метод CoffeeScript также имеет преимущества для минимизации.

С мой другой ответ :

Для большинства разумных классов замыкание, генерируемое CoffeeScript, генерирует меньший минимизированный вывод. Закрывающая оболочка составляет 25 байтов минимизированных служебных данных, но она избавляет вас от повторения имени класса , сохраняя k * N байтов (k = букв в имени, N = num-of -refs). например, если класс, подобный BoilerPlateThingyFactory, имеет 2+ метода, оболочка замыкания генерирует меньший минимизированный код.



подробнее ...

Код, сгенерированный Coffee с использованием замыкания, уменьшается до:

// Uglify '1.js' = 138 bytes (197 w/ whitespace):

var Animal=function(){function e(e){this.name=e}return e.prototype.speak=function(e){return"My name is "+this.name+" and I like "+e},e}();

// with whitespace ("uglifyjs -b"):

var Animal = function() {
    function e(e) {
        this.name = e;
    }
    return e.prototype.speak = function(e) {
        return "My name is " + this.name + " and I like " + e;
    }, e;
}();

Альтернативная «идиоматическая» реализация Ryeguy сводится к следующему:

// Uglify '2.js' = 119 bytes (150 w/ whitespace):

var Animal=function(t){this.name=t};Animal.prototype.speak=function(e){return"My name is "+this.name+" and I like "+e};

// with whitespace ("uglifyjs -b"):

var Animal = function(t) {
    this.name = t;
};

Animal.prototype.speak = function(e) {
    return "My name is " + this.name + " and I like " + e;
};

Обратите внимание, что имя «Животное» существует только один раз в форме «Кофе» и N = 2 раза в «идиоматической» переменной Ригью. Теперь «Животное» состоит всего из 6 букв, и есть только 1 метод, поэтому кофе здесь должен проигрывать на 25-6 = 19 байт. Сверяясь с моим минимизированным кодом, это 138 байтов до 119 байтов, для дельты ... 19 байтов. Добавьте еще 4 метода, и преимущество переключится на Кофе. И это не просто методы; константы классов и другие типы ссылок тоже учитываются.

2 голосов
/ 12 января 2011

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

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