Разница между классом (Java) и закрытием (Javascript)? - PullRequest
6 голосов
/ 28 апреля 2009

Я не понимаю, как замыкание сильнее, чем класс. Похоже, я могу добиться того же поведения закрытия с помощью класса. Любая помощь будет оценена

Ответы [ 5 ]

11 голосов
/ 28 апреля 2009

Закрытия - это бедняки / Объекты - это бедняки

Пожалуйста, смотрите: крышки и объекты

Для ленивых:

Почтенный мастер Qc Na был гуляет со своим учеником Антоном. Надеясь подсказать мастеру в обсуждение Антон сказал: «Мастер, у меня есть слышал, что объекты очень хорошие вещь - это правда? "Qc Na посмотрел жалко на своего ученика и ответил, «Глупый ученик - объекты - это просто закрытие бедного человека. "

Наказанный, Антон ушел из его хозяин и вернулся в свою камеру, намерение изучать замыкания. Он внимательно прочитайте всю "Лямбду: Ultimate ... "серия статей и ее двоюродные братья, и реализовали небольшой Схема интерпретатора с основанная на замыкании объектная система. Он многому научился и с нетерпением ждал информируя своего хозяина о своем прогрессе.

На своей следующей прогулке с Qc Na, Антон попытался произвести впечатление на своего хозяина говоря: «Учитель, я усердно изучил вопрос, а теперь разбираюсь что объекты действительно бедняки замыкания. "Qc Na ответил, ударив Антон со своей палкой, говоря: «Когда ты научишься? Закрытия плохие мужской объект ". В этот момент Антон стал просветленным.

- Антон ван Страатен

4 голосов
/ 28 апреля 2009

Различия между классом и закрытием уже были объяснены другими. Я просто хотел отметить, что во многих местах Java API, где язык, который их поддерживает, будет / может использовать замыкания, используется анонимная реализация интерфейса. Например, рассмотрите код ниже:

JButton btn = new JButton("Say Hello");
btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageBox("Hello");
    }
});

В этом случае можно сказать, что анонимный ActionListener действует как замыкание, если Java допускает замыкания, код может выглядеть следующим образом: (с использованием синтаксиса c ++ 0x-esque)

JButton btn = new JButton("Say Hello");
btn.addActionListener([]=>(ActionEvent e){JOption.showMessageBox("Hello");});

В этом тривиальном случае основное различие между закрытием и анонимной реализацией интерфейса (AII) заключается в том, что:

  1. Метод AII имеет более строгую проверку типов, чем замыкание. (Системы замыкания могут быть сделаны для более строгой проверки типов, но в целом они не проверяются)
  2. Синтаксис закрытия требует меньше ввода. Похоже, это основной недостаток, который возникает после того, как вы изучаете Java, достаточно долго аргументы замыканий.

Мне еще предстоит столкнуться с ситуацией, когда AII не может делать то, что нужно делать. Да, есть еще типизация и другой интерфейс для определения, но система работает, и, IMHO, более мощная, так как вам не нужно использовать AII, а можно использовать полноценный класс со своими собственными методами, данными-членами и конструктором. , Пример - слушатель действия, который открывает контекстное меню. Если вы создаете класс, который реализует ActionListener и принимает JMenu в качестве аргумента, вы можете сделать:

btn.addActionListener( new ContextMenuActionListener(myMenu) );

Это выглядит чище (для меня), чем решение типа boost: bind type.

[]=>(ActionListener) myContextPopupClosure = []=>(ActionListener E){ ... };
...
btn.addActionListener( Closure.bind1(myContextPopupClosure,myMenu) );

или около того

EDIT:

Проработав вчера вечером много работы с дженериками, я понял одно преимущество замыканий над AII. В приведенных выше примерах я предполагал, что замыкание будет иметь тип [] => (ActionEvent), но в действительности оно может иметь тип [] => (? Super ActionEvent). Это значит:

[]=>(Object) c = []=>(Object o) { System.exit(0); }
btn.addActionClosure( c );
window.addMouseMovedClosure( c );
//Each method in MouseMotion listener would need it's own closure.
//So I 'invented' an API change.

Будет компилироваться. Это может оказаться полезным, когда вам нужно сделать одно и то же в ответ на несколько событий.

Другой пример. Это закрытие может быть добавлено в любое место, которое занимает закрытие. Если его добавить к чему-либо как ActionListener или MouseListener, он будет регистрировать вызовы.

[]=>(Object ... objs) log = []=>(Object ... obj) {for(Object o:obj){logObject(o);}}
4 голосов
/ 28 апреля 2009

A closure и class - две совершенно разные вещи.

Неправильно говорить, что «class сильнее, чем closure». или наоборот.

Они делают совершенно разные вещи.

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

A class - это определение объекта. Класс определяет поведение и содержимое экземпляров класса.

2 голосов
/ 28 апреля 2009

Я не уверен, что привело вас к этому вопросу, но то, что вам сказали или что вы прочитали, сильно ввело вас в заблуждение.

В целом, игнорируя язык, замыкание и класс являются совершенно не связанными структурами / соглашениями в программировании.

1 голос
/ 28 апреля 2009

Это хороший вопрос, но он мог бы быть лучше сформулирован:

«В чем сходства и различия между объектами Java и замыканиями JavaScript»?

Сходства: они оба имеют постоянное состояние в своих локальных переменных. Их методы имеют доступ к этим переменным состояния.

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

newXY = function(x,y) {

    var that = {};//Instantiate new object
    var x = parseFloat(x);
    var y = parseFloat(y);

    that.xtimesy = function() {
      return x*y;
    }(); // <-- Notice the immediate invocation of the function, here.

    return that;
};

Таким образом, вы можете написать код, подобный этому фрагменту, скопированный / вставленный из оболочки носорога :

js> var foo = newXY(2,5);
js> foo.xtimesy;
10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...