Статьи

JavaScript для Java-разработчиков. Часть 1. Отсутствие классов, инсталирование объектов.

Я работал в основном с Java за 9 лет своего опыта разработки. В те годы я работал со многими другими разработчиками Java, и одной из общих черт многих из них является то, что им не нравится (иногда даже ненавидит) JavaScript.

Я признаю, что Javascript никогда не был моим любимым языком, но я признаю, что это мощный и все более полезный язык, чтобы знать и понимать.

В этом кратком руководстве мы попытаемся объяснить некоторые моменты, которые, как мне кажется, заставляют разработчиков Java чувствовать, что они ненавидят JavaScript.

  1. Отсутствие классов и инстанцирующих объектов
  2. Наследование и инкапсуляция
  3. Пакет и организационный код
  4. Функциональное программирование и функции обратного вызова

В этом первом посте я расскажу о пункте № 1 .

Отсутствие классов и инстанцирующих объектов

В Java все, что мы программируем, существует внутри класса — даже самым простым программам нужен класс. Классы используются больше всего на свете как образец для создания объектов. Следующий код показывает простой класс в Java:

class Simple {
  private String propertyA;
  private String propertyB;

  public Simple(String a, String b){
    this.propertyA = a;
    this.propertyB = b;
  }

  public String concatenateAandB(){
    return propertyA + propertyB;
  }
}

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

Simple instance = new Simple("hello ", "world");
System.out.println(instance.concatenateAandB());

Это напечатало бы привет мир к консоли. Итак, как бы мы сделали что-то простое с JavaScript? Прежде всего, давайте вспомним, что в JavaScript нет такого понятия, как классы. Однако предыдущий код легко воспроизводится в JavaScript. Я покажу код, а затем объясню, как он работает:

function Simple(a, b) {
  var propertyA = a;
  var propertyB = b;

  this.concatenateAandB = function() {
    return propertyA + propertyB;
  }
}

Способ выполнить это очень похож на версию Java. Мы создаем экземпляр и вызываем метод:

var instance = new Simple("hello", "world");
console.log(instance.concatenateAandB());

Как вы можете видеть, функциональность здесь очень похожа — главное отличие состоит в том, что вместо того, чтобы иметь класс и конструктор для этого класса, у нас есть изолированная функция, которая, как правило, начинается с заглавной буквы, когда мы этого хотим. работать конструктором. Ничто кроме этого соглашения не мешает нам делать function simple(a, b) {.

Simpleэто стандартная функция JavaScript. Однако, как вы можете видеть, мы назвали его нестандартным способом, используя newключевое слово. Вы можете вызвать эту функцию, как Simple("hello", "world")показано на следующем фрагменте кода:

Simple("hello ", "world");
console.log(window.concatenateAandB());  

Во втором сценарии мы видим, что мы не создаем новый экземпляр с помощью new, а вызываем функцию напрямую, как любую другую функцию JavaScript. Это приводит к вызову функции с использованием текущего объекта в качестве объекта this (в данном случае объекта окна ). При использовании newключевого слова, вместо того , чтобы использовать текущий объект , как это , новый пустой объект создается и один используется в качестве контекста функции. Кроме того, при использовании newсозданный объект экземпляра возвращается вызовом метода.

Это одна из самых важных вещей, которую нужно знать при работе с объектами в JavaScript. Функции ведут себя по-разному, когда вызываются с помощью newили когда не используются new. В первом случае новый пустой объект ({}) создается и используется как контекст this внутри функции. Когда функция вызывается без newключевого слова, текущий объект this ( окно, если вы вызываете с верхнего уровня) используется в качестве контекста внутри функции, и новый экземпляр не создается.

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

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