Вопросы о Javascript, на которые я не мог ответить во время собеседований (часть 2)

Сегодняшняя цель?

Сегодня мы продолжим с того места, где мы уехали. Разрешите еще раз резюмировать то, что мы делали в первой статье, на случай, если вы не читали первую часть. В этой статье я рассмотрю некоторые из основных концепций javascript, которые мне задали во время собеседований, с целью помочь другим людям вроде меня, которые любят писать код на javascript, но не смогли пройти это важное интервью. Не читали первую часть? Смотрите здесь!

Итак, начнем с концепций

«Разница между функциями-прототипами и классами»

Начнем с функций-прототипов. Итак, что это такое? Чтобы ответить на этот вопрос, во-первых, нам нужно знать, что такое прототип в Javascript. По определению:

«Прототипы - это механизм, с помощью которого объекты могут совместно использовать / наследовать функции друг друга»

Итак, за очень страшным словом кроется очень простое значение! Значит ли это, что Javascript похож на любой объектно-ориентированный язык? Можно так сказать, но правила здесь не такие строгие, так что это определенно зависит от человека, пишущего код.

Вы помните, что мы использовали «функцию» позади «прототипа»? Ага, у нас есть функция fill, которая создает объект-прототип. Итак, как нам их написать? Ответ такой же, как и для любой другой функции. Возьмем здесь пример:

function Car(name, type, buildYear) {
  this.name = name;
  this.type = type;
  this.buildYear = buildYear;
}
let Honda = new Car("civic", "sedan", "2020");
console.log(Honda);
// Output
Object {
  buildYear: "2020",
  name: "civic",
  type: "sedan"
}

Вот и все, у нас только что появился новый объект с прототипом, который мы только что определили.

ПРИМЕЧАНИЕ: попробуйте сделать это с помощью ES6 и посмотрите, что у вас получится;)

Теперь, если вы присмотритесь, вы увидите, что это очень похоже на то, что мы делаем в Java, где вы создаете класс, а затем создаете его экземпляр с помощью ключевого слова new. Правильно? Так что перейдем к занятиям!

Какие классы в javascript? По определению:

«Классы - это шаблоны, используемые для создания объекта»

Но это то, что мы сделали в функциях прототипа! Правильно?

Ага, абсолютно! Но наряду с этим мы можем писать внутри него функции для работы с данными, которые мы объявили внутри класса. Кроме того, в документации упоминается, что классы построены на прототипах, но имеют синтаксические различия.

Итак, как нам писать классы? Именно так:

class Car {
  constructor(name, type, buildYear) {
    this.name = name;
    this.type = type;
    this.buildYear = buildYear;
  }
}
let Honda = new Car("civic", "sedan", "2020");
console.log(Honda);
// Output
Object {
  buildYear: "2020",
  name: "civic",
  type: "sedan"
}

Как и любой объектно-ориентированный язык, классы javascript также будут иметь конструктор, который будет использоваться для создания объектов. Но помните, мы упоминали функции для изменения данных? Давайте сделаем это:

class Car {
  constructor(name, type, buildYear) {
    this.name = name;
    this.type = type;
    this.buildYear = buildYear;
  }
  
  addPremiumFeatures(bool) {
    this.premiumFeatures = bool
  }
}
let Honda = new Car("civic", "sedan", "2020");
Honda.addPremiumFeatures(true);
console.log(Honda);
// Output
Object {
  buildYear: "2020",
  name: "civic",
  premiumFeatures: true,
  type: "sedan"
}

Видеть, что? Это так просто! Это очень простой пример, но вы можете сделать гораздо больше, если у вас есть четкие концепции.

Итак, вот и все, в чем разница между функциями-прототипами и классами в Javascript!

«Как вы добавляете свои пользовательские функции в импортированную библиотеку? Без изменения кода в библиотеке? »

Во-первых, давайте поговорим о том, как я пришел к этому вопросу в интервью. Интервьюер попросил меня создать класс калькулятора на javascript и включить в этот класс add, subtract, multiply and divide методы для выполнения операций с двумя числами. Итак, я сделал что-то вроде этого:

class Calculator {
  
  add(x, y) {
    return x + y;
  };
  
  subtract(x, y) {
    return x - y;
  };
  
  multiply(x, y) {
    return x * y;
  }
  
  divide(x, y) {
    return x / y;
  };
}
let x = new Calculator();
console.log(x.add(2,3));         //5
console.log(x.subtract(2,3));    //-1
console.log(x.multiply(2,3));    //6
console.log(x.divide(2,3));      //0.6666666666666666

И я подумал: "Ура!" Я понял это. Затем последовал следующий вопрос, и он попросил меня добавить новый метод в класс под названием modulo, не записывая его внутри класса. Он сказал: «Предположим, вы куда-то импортируете эту библиотеку и не хотите менять исходный класс, потому что это будет глобальным изменением и может повлиять на другие места, где используется класс», и я подумал, хорошо! ты прав! Но я не знаю, как это сделать! Итак, я попытался вспомнить все, что мог, о javascript, но не смог его понять и сказал ему, что не знаю. Но сразу после интервью я поискал и узнал, что использование prototypes было ответом здесь! Ты можешь в это поверить? Прототипы! Те, которые мы только что обсудили. Итак, вот и ответ:

import Calculator from './path/to/Calculator';
// You add a property modulo to the class calculator using the prototype!
Calculator.prototype.modulo = (x, y) => {
  return x % y
}
let x = new Calculator();
console.log(x.add(2,3));         //5
console.log(x.subtract(2,3));    //-1
console.log(x.multiply(2,3));    //6
console.log(x.divide(2,3));      //0.6666666666666666
console.log(x.modulo(2,3));      //2

Хотел бы я знать ответ тогда и избавить себя от смущения, но ладно, теперь я знаю, и вы тоже!

Вывод

На этом завершается часть 2 «Вопросы Javascript, на которые я не мог ответить во время собеседования». Надеюсь, вам понравилось, и вы узнали что-то новое! Если это так или иначе помогло вам, не забудьте дать аплодисменты статье и оставить комментарий! Кроме того, у меня есть еще несколько тем, поэтому я скоро напишу часть 3! Так что следите за этим. Спасибо, что нашли время и прочитали это! До скорого :)