Как в JS лучше реализовать функции-синонимы?

Допустим, я пишу JS-библитеку и хочу, чтобы некоторые функции были доступны по более, чем одному имени — в предметной области есть несколько устоявшихся обозначений одного понятия.

Например, в графике прозрачность цвета/слоя бывает обозначают как alpha и как opacity. В некоторых контекстах традиционно применяется первое, в других второе — но в обощенном случае термины можно считать эквивалентными.

Это была преамбула, теперь фабула.


Я задумался, что дает нам такая конструкция?
x = y = function() { ... }

Это будут две раздельно существующие функции-копии? Или две ссылки на физически одну функцию?


Делаем простой тест в консоли Хрома:
x = y = function(i) { return i*i; }
x(5) // 25
y(5) // 25
y = function(i) { return i*i*i; }
y(5) // 125
x(5) // 25


Выходит, что это независимые копии? То есть это двойное/тройное/итд использование памяти.


Как это можно обойти? Есть ли на этот счет какие-то общепринятые методики, best practices, так сказать?

Или моя проверка была некорректна?
  • Вопрос задан
  • 3075 просмотров
Пригласить эксперта
Ответы на вопрос 6
Riateche
@Riateche
После первой строчки x и y будут ссылками на одну и ту же функцию. Когда вы присваиваете новое значение y, то y становится ссылкой на новую функцию, а x продолжает ссылаться на старую.
Ответ написан
lastwish
@lastwish
Как вариант, для того, чтобы разные поля имели «общее значение», можно реализовать подобие private-поля и геттеров-сеттеров:

  var obj = (function () {
    
    var _alpha;
    function alpha(value) {
      // общая для синонимов функция get/set
      if (arguments.length) {
        _alpha = value;
      }
      else {
        return _alpha;
      }
    }
    
    return { 
      // "public", объявление синонимов
      alpha: alpha,
      opacity: alpha
    }

  }());

  obj.alpha(.5);
  console.log(obj.alpha()); // 0.5
  console.log(obj.opacity()); // 0.5

  obj.opacity(.75);
  console.log(obj.alpha()); // 0.75
  console.log(obj.opacity()); // 0.75
Ответ написан
KAdot
@KAdot
В JS переменные передаются по копии ссылки. Подробнее можно почитать тут.
Ответ написан
Комментировать
spmbt
@spmbt
Всё скаазал Riateche; можно добавить, что когда делаете
function(i) { return i*i*i; }
, создаётся новая функция, потому что всякая function(i) {} означает создание новой (почти то же, что new Function(), но по методу исполнения совсем не то, вторая не рекомендуется из-за неявного eval). Поэтому ничего удивительного, что тест показал, что функции разные. А присваивание функций — это присваивание объектов, которое идёт по ссылке.
Ответ написан
spmbt
@spmbt
Всё скаазал Riateche; можно добавить, что когда делаете
function(i) { return i*i*i; }
, создаётся новая функция, потому что всякая function(i) {} означает создание новой (почти то же, что new Function(), но по методу исполнения совсем не то, вторая не рекомендуется из-за неявного eval). Поэтому ничего удивительного, что тест показал, что функции разные. А присваивание функций — это присваивание объектов, которое идёт по ссылке.
Ответ написан
Комментировать
spmbt
@spmbt
Всё скаазал Riateche; можно добавить, что когда делаете
function(i) { return i*i*i; }
, создаётся новая функция, потому что всякая function(i) {} означает создание новой (почти то же, что new Function(), но по методу исполнения совсем не то, вторая не рекомендуется из-за неявного eval). Поэтому ничего удивительного, что тест показал, что функции разные. А присваивание функций — это присваивание объектов, которое идёт по ссылке.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы