You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
map, filter and slice return a new array
find returns an element
reduce returns a reduced value
push returns length
TypeErrors get thrown when a value is not of the expected type.
SyntaxErrors get thrown when you've written something that isn't valid JavaScript, for example when you've written the word return as retrun.
ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.
bind() only returns a copy of the bound function
call() executes the bound function immediately
Falsy values:
undefined
null
NaN
0, -0
'' (empty string)
false
public - доступны как в классах, в которых они объявлены, так и в классах потомках. Также к публичным членам можно обращаться через экземпляры класса
protected - доступны только контексту класса, в котором они объявлены, а также всем его потомкам. Не доступны у экземпляров
private - доступны только контексту класса, в котором они объявлены. Не доступны у экземпляров и потомков
abstract - создается класс, в нем методы которые работают с абстракными данными, и их надо переназначить в потомке
readonly - нельзя изменять у экземпляров
Для вставки специальных знаков в строки, нужно записывать / перед ними, называется escaping:
"He said \"Hi!\""; // He said Hi!
'He said "Hi!"'; // He said Hi!
`He said \'Hi!\'`; // Wrong punctuatin, but just for example
Список таких знаков (escape sequences) вместе с символами ****\u*hhhh* в кодировке Unicode с шестнадцатеричным (hexadecimal) кодом:
Unicode character value
Escape sequence
Meaning
Category
\u0008
\b
Backspace
\u000C
\f
Form feed
White space
\u000A
\n
Line feed (new line)
Line terminator
\u000D
\r
Carriage return
Line terminator
\u0009
\t
Tab
White space
\u000B
\v
Vertical tab
White space
\u0027
'
Single quotation mark (')
\u0022
"
Double quotation mark (")
\u005C
\
Backslash
\u0020
Space
White space
\u00A0
Nonbreaking space
White space
\u2028
Line separator
Line terminator
\u2029
Paragraph separator
Line terminator
\uFEFF
Byte order mark
White space
JavaScript имеет набор встроенных операторов математического присваивания, которые упрощают вычисление нового значения и присваивают ему одну и ту же переменную без записи переменной дважды:
let x = 4;
x += 2; // x equals 6
let y = 4;
y -= 2; // y equals 2
let z = 4;
z *= 2; // z equals 8
Инкремент и декремент
Одной из наиболее частых операций в JavaScript, как и во многих других языках программирования, является увеличение или уменьшение переменной на единицу.
Инкремент ++ увеличивает на 1:
let i = 2;
i++; // более короткая запись для i = i + 1.
console.log(i); // 3
Декремент -- уменьшает на 1:
let i = 2;
i--; // более короткая запись для i = i - 1.
console.log(i); // 1
Вызывать эти операторы можно не только после переменной i++ (постфиксная форма), но и перед переменной ++i (префиксная форма).
Обе эти формы записи делают одно и то же. Но есть разница и она видна только в том случае, когда нужно не только увеличить или уменьшить переменную, но и использовать результат в том же выражении, например:
let i = 1;
let a = ++i;
console.log(a);
// -> 2
Вызов ++i увеличит переменную, а затем вернёт ее значение в a. Так что в a попадёт значение i после увеличения.
Постфиксная форма i++ отличается от префиксной ++i тем, что возвращает старое значение, бывшее до увеличения. В примере ниже в a попадёт старое значение i, равное 1:
let i = 1;
let a = i++;
console.log(a);
// -> 1
Если результат оператора не используется, а нужно только увеличить или уменьшить переменную – без разницы, какую форму использовать:
let i = 0;
i++;
++i;
console.log(i);
// -> 2
Инкремент и декремент можно использовать в любых выражениях. При этом он имеет более высокий приоритет и выполняется раньше, чем арифметические операции:
let i = 1;
console.log(2 * ++i);
// -> 4
let i = 1;
console.log( 2 * i++);
// -> 2, выполнился раньше но значение вернул старое
console.log(i);
// -> 2
console.log(2 * i++);
// -> 4
console.log(i);
// -> 3
Экспоненциальный оператор
Новый в ES7 оператор ** позволяет возводить в степень:
const square = (x) => x**2;
square(2);
// -> 4
Выражения, утверждения и среда
К примеру если выражение (expression -то, что производит значение) соотносится с обычным предложением, как его фрагмент, то утверждение (statement) соотносится с целым предложением. Программа представляет собой набор утверждений.
Самый простой пример утверждения это выражение с ; после него:
1;
!false;
Точку запятой можно ставить не всегда, но сложно отследить когда она нужна, по-этому лучше ставить всегда.
Среда (environment) - это набор переменных, которые определены. Системы JavaScript всегда помещают ряд полезных стандартных переменных в вашу среду.
Свойства
Instance (экземпляр объекта) - это отдельный случай (или объект) типа данных. Каждый экземпляр, например такой как строка Hello, содержит дополнительную информацию.
Почти все значения в JavaScript имеют свойства. Исключением является null и undefined:
null.length;
// -> TypeError: null has no properties
Можно вычислить количество символов в строке при помощи свойства .length:
console.log('Hello'.length);
А так же .log является свойством в выражении console.log.
Два типичных способа доступа к свойствам в JavaScript - это точка и квадратные скобки. Оба value.x и value[x] получают доступ к свойству value, но не обязательно к одному и тому же. Разница заключается в том, как они интерпретируется. При использовании точки, слово после точки является буквальным именем свойства. При использовании квадратных скобок выражение между скобками оценивается (evaluats) для получения имени свойства.
Таким образом, если название свойства name, нужно писать value.name. Если нужно извлечь свойство названное по имени значения заложенное в переменной i, нужно писать value[i]. Свойством может быть любая строка, но нотация с точкой (dot notation) работает только с правильными именами переменных. Таким образом, если нужно получить доступ к свойству, названному “2” или “John Doe”, нужно использовать квадратные скобки: value[2] или значение ["John Doe"].
Методы экземпляров объектов по определению требуют, чтобы был создан экземпляр, прежде чем можно будет их использовать. Для того чтобы вызвать метод без экземпляра, можно использовать библиотеки JavaScript. Библиотеки содержат методы, которые можно вызывать, не создавая экземпляр.
Библиотека [Math](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math) является одной из таких коллекций, содержащая математические методы.
Можно испольховать метод .random(), чтобы сгенерировать случайное число:
console.log(Math.random()); // random number between 0 and 1
Можно задать число в пределах которого должна производится генерация просто умножив на него:
Math.random() * 50;
В этом случае ответ будет скорее всего десятичным числом. Для того чтобы округлить число, есть метод Math.floor():
Процесс конвертации функции, которая принимает несколько аргументов в фукцию, которая принимает их одновременно:
const multiply = (a, b) => a * b;
multiply(3, 4);
// -> 12
const curriedMultiply = (a) => (b) => a * b; // стрелки это функции
// старая версия
var curriedMultiply = function curriedMultiply(a) {
return function (b) {
return a * b;
};
};
// тоже самое, что и closure
curriedMultiply(3)(4);
// -> 12
const multiplyBy5 = curriedMultiply(5);
multiplyBy5(5)
// -> 25
Таким образом первая функция принимает параметр a и вызывает вторую функция, которая перемножает a и b.
Compose
Слияние двух функций воедино, для формирования третьей функции, в которой результат одной функции является аргументом для другой:
const compose = (f, g) => (a) => f(g(a));
const sum = (num) => num + 1;
compose(sum, sum)(5);
// 1. const compose = (f, g) => (a) => f(g(5));
// 2. const compose = (f, g) => (a) => f(6);
// 3. const compose = (f, g) => (a) => 7;
// старая версия, f & g становятся функциями
var compose = function compose(f, g) {
return function (a) {
return f(g(a));
}
};
var sum = function sum(num) {
return num + 1
};
compose(sum, sum)(5);
Generators
Generators are a special kind of function with the ability to pause itself, and resume later, allowing other code to run in the meantime.
The code decides that it has to wait, so it lets other code “in the queue” to run, and keeps the right to resume its operations “when the thing it’s waiting for” is done.
All this is done with a single, simple keyword: yield. When a generator contains that keyword, the execution is halted.
A generator can contain many yield keywords, thus halting itself multiple times, and it’s identified by the *function keyword, which is not to be confused with the pointer dereference operator used in lower level programming languages such as C, C++ or Go.
Generators enable whole new paradigms of programming in JavaScript, allowing:
2-way communication while a generator is running
long-lived while loops which do not freeze your program
Here is an example of a generator which explains how it all works.
function *calculator(input) {
var doubleThat = 2 * (yield (input / 2))
var another = yield (doubleThat)
return (input * doubleThat * another)
}
We initialize it with
const calc = calculator(10)
Then we start the iterator on our generator:
calc.next()
This first iteration starts the iterator. The code returns this object:
{
done: false
value: 5
}
What happens is: the code runs the function, with input = 10 as it was passed in the generator constructor. It runs until it reaches the yield, and returns the content of yield: input / 2 = 5. So we got a value of 5, and the indication that the iteration is not done (the function is just paused).
In the second iteration we pass the value 7:
calc.next(7)
and what we got back is:
{
done: false
value: 14
}
7 was placed as the value of doubleThat. Important: you might read like input / 2 was the argument, but that’s just the return value of the first iteration. We now skip that, and use the new input value, 7, and multiply it by 2.
We then reach the second yield, and that returns doubleThat, so the returned value is 14.
In the next, and last, iteration, we pass in 100
calc.next(100)
and in return we got
{
done: true
value: 14000
}
As the iteration is done (no more yield keywords found) and we just return (input * doubleThat * another) which amounts to 10 * 14 * 100.
Объекты
Объекты (objects) JavaScript - это контейнеры, которые могут хранить данные (произвольные коллекции свойств) и функции. Данные, хранящиеся в объекте, не упорядочены - можно получить к нему доступ только путем вызова связанного с ним ключа (key).
Можно создать объект с парами ключ-значение (key-value), используя следующий синтаксис:
let restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine Pesto'],
open: function() { // это и есть метод
console.log('${this.name} is open!');
}
};
Описание:
let restaurant создает переменную restaurant, которая хранит объект.
Объект создается в фигурных скобках {}.
name, seatingCapacity, hasDineInSpecial, и entrees это все ключи.
Каждый ключ разделен с его соответствующим значением двоеточием :.
Каждая пара разделяется запятой ,.
Доступ к свойствам объекта
Наиболее распространенным способом доступа к значению ключа является использование точечной нотации (dot notation).
Другой способ доступа к значению ключа - это обозначение в виде скобок.
Точно так же, как с точечной нотацией, можно использовать скобки открытия [ и закрытия ] для доступа к ключу. Синтаксис выглядит так:
let restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto']
};
console.log(restaurant['entrees']);
// -> ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto']
Одно преимущество нотации со скобками над точечной нотацией, заключающееся в том, что можно использовать переменные внутри скобок для выбора ключей объекта:
let meal = 'none';
let time = 12;
// We'll use military time for this example, counting hours 0-23.
const restaurantSpecials = {
breakfast: 'The breakfast special is 20% off freshly squeezed orange juice',
lunch: 'The lunch special is 10% off appetizers',
none: 'There are no specials currently'
};
if (time < 11) { // 11 am
meal = 'breakfast';
} else if (time < 17) { // 5 pm
meal = 'lunch';
}
console.log(restaurantSpecials[meal]);
// -> The lunch special is 10% off appetizers
Добавление и измерение свойств
Объекты считаются изменчивыми (mutable), что означает, их можно изменить после создания. Даже если объект сохранен в переменной const, все равно можно добавлять и редактировать пары ключ-значение внутри него, не вызывая ошибки.
Когда объекты имеют пары ключ-функция, функция называется методом (method):
const restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
openRestaurant: () => {
return 'Unlock the door, flip the open sign. We are open for business!';
},
closeRestaurant: () => {
return 'Lock the door, flip the open sign. We are closed.'
}
};
console.log(restaurant.openRestaurant());
// -> Unlock the door, flip the open sign. We are open for business!
console.log(restaurant.closeRestaurant());
// -> Lock the door, flip the open sign. We are closed.
В примере созданы два метода .openRestaurant() и .closeRestaurant(), при помощи синтаксиса со стрелкой в объекте restaurant.
Новый синтаксис ES6
Новый синтаксис записи методов не нуждается в стрелках и двоеточии с ключом функции:
const restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
openRestaurant() {
return 'Unlock the door, flip the open sign. We are open for business!';
},
closeRestaurant() {
return 'Lock the door, flip the open sign. We are closed.'
}
А так же, для того чтобы задать переменные определенным значениям ключей, например:
Иногда нужно добавить переменные в объект и сделать так, чтобы свойства были равны значениям:
const a = "Simon";
const b = true;
const c = {};
const obj = {
a: a,
b: b,
c: c,
}
Теперь можно делать это так:
const obj = {a, b, c}
Дескриптор this
Можно создать методы, которые работают с данными внутри одного и того же объекта, например свойство hasDineInSpecial в методе .openRestaurant():
const restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
openRestaurant() {
if (hasDineInSpecial) {
return 'Unlock the door, post the special on the board, then flip the open sign.';
} else {
return 'Unlock the door, then flip the open sign.';
}
}
};
console.log(restaurant.openRestaurant());
// -> ReferenceError: hasDineInSpecial is not defined
Ошибка происходит из-за того, что hasDineInSpecial вне области действия .openRestaurant().
Нужно использовать дескриптор this чтобы получить доступ к свойствам внутри того же объекта:
const restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
openRestaurant: function() {
if (this.hasDineInSpecial) {
return 'Unlock the door, post the special on the board, then flip the open sign.'
} else {
return 'Unlock the door, then flip the open sign.'
}
}
}
console.log(restaurant.openRestaurant());
// -> Unlock the door, post the special on the board, then flip the open sign.
this.hasDineInSpecial внутри объекта это тоже самое, что обращаться к restaurant.hasDineInSpecial вне объекта.
Значение this, при использовании в объекте, является сам объект. В Javascript this относится к объекту, который мы вызываем внутри.
let yourObj = {
name: 'Timer'
};
yourObj.sayHello = myObj.sayHello;
// Sets the sayHello method on yourObj to be the sayHello method on yourObj
Если вызвать yourObj.sayHello(), он вернет 'Timer says hello!'. this в примере вызван в объекте yourObj, который ограничен областью действия свойств внутри yourObj.
Область действия this с функциями со стрелкой наследуется от контекста. В обычных функциях this всегда относится к ближайшей функции, тогда как в функция со стрелкой эта проблема решена и больше не нужно писать var that = this.
Операторы delete и in
Унарный оператор при обращении к свойству удаляет его. Это не очень популярно, но возможно:
let anObject = {left: 1, right: 2};
console.log(anObject.left);
// → 1
delete anObject.left;
console.log(anObject.left);
// → undefined
console.log("left" in anObject);
// → false
console.log("right" in anObject);
// → true
Унарный оператор in сообщает есть ли у объекта то или иное свойство.
Методы объектов
Чтобы перечислить все свойства объекта можно использовать функцию Object.keys:
Методы getter и setter получают и устанавливают свойства внутри объекта. Существует несколько преимуществ использования этих методов для получения и установки свойств напрямую:
Можно проверить, действительны ли данные до установки свойства.
Можно выполнить действие над данными во время получения или установки свойства.
Можно контролировать, какие свойства могут быть установлены и извлечены.
Setters
Например:
let restaurant = {
name: 'Italian Bistro',
seatingCapacity: 120,
hasDineInSpecial: true,
entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine Pesto']
}
Ключ seatingCapacity содержит значение 120. Если он изменится, нужно проверить его годность. Например, метод должен проверить, является ли поле seatingCapacity числом, равным 150, а не строкой 'one hundred fifty``'. Можно записать это в метод setter следующим образом:
let restaurant = {
_name: 'Italian Bistro',
_seatingCapacity: 120,
_hasDineInSpecial: true,
_entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
set seatingCapacity(newCapacity) {
if (typeof newCapacity === 'number') {
this._seatingCapacity = newCapacity;
console.log(`${newCapacity} is valid input.`);
} else {
console.log(`Change ${newCapacity} to a number.`)
}
}
}
Описание:
Нужно добавить имена свойств с символами подчеркивания. _ используется до названия свойства, чтобы обозначить, что его значение не должно быть изменено напрямую с помощью другого кода. Рекомендуется добавлять подчеркивания для всех свойств и создавать setters для всех атрибутов, к которым нужно получить доступ позже в своем коде.
Метод setter set seatingCapacity() принимает newCapacity как переменную. Переменная newCapacity содержит новое значение, которое будет хранится в _seatingCapacity.
Внутри setter .seatingCapacity() используется условный оператор (conditional statement), чтобы проверить, что переменная newCapacity с новым значением - это число.
Если переменная число (правельный ввод), используется this._seatingCapacity для изменения значения, присвоенного _seatingCapacity.
Методы setter вызываются так же, как обычные свойства:
// Sets the _seatingCapacity value to 150
restaurant.seatingCapacity = 150;
// -> 150 is valid input.
Getters
Getters используются для получения значений свойств внутри объекта:
let restaurant = {
_name: 'Italian Bistro',
_seatingCapacity: 120,
_hasDineInSpecial: true,
_entrees: ['Penne alla Bolognese', 'Chicken Cacciatore', 'Linguine pesto'],
// setters получают значение и могут например проверять новое значение
set seatingCapacity(newCapacity) {
if (typeof newCapacity === 'number') {
this._seatingCapacity = newCapacity;
} else {
console.log(`Change ${newCapacity} to a number.`)
}
},
// getters служат для вывода значения в преобразованном виде
get seatingCapacity() {
console.log(`There are ${this._seatingCapacity} seats at Italian Bistro.`);
return this._seatingCapacity;
}
}
Метод getter вызывается так же, как свойство без метода:
Классы (classes) - это инструмент, который разработчики используют для быстрого создания подобных объектов, а так же отличный способ уменьшить повторяющийся код и время отладки.
Constructor
Синтаксис классов и объектов схож, но есть один отличительный метод - конструктор (constructor). JavaScript вызывает constructor() каждый раз когда создается новый экземпляр объекта (instance) класса с использованием new:
class Dog {
constructor(name) {
this.name = name;
this.behavior = 0;
}
}
Описание:
Dog это название класса.
JavaScript будет вызывать (invoke) метод constructor() каждый раз когда создается новый экземпляр объекта класса Dog.
Метод constructor() принимает один аргумент, name.
Внутри constructor() используется дескриптор this. В контексте класса, this относится к экземпляру объекта этого класса.
После this.name, создается свойтво behavior, которое будет отслеживать количество раз, когда собака плохо себя ведет. Свойство behavior всегда инициализируется нулем.
Instance
Экземпляр (instance) это объект, который содержит названия свойств и методы класса, но с уникальными значениями свойств, например:
class Dog {
constructor(name) {
this.name = name;
this.behavior = 0;
}
}
const halley = new Dog('Halley'); // создает новый экземпляр Dog
console.log(halley.name); // выводит значение имени, сохраненное в halley
// -> "Halley"
console.log(halley instanceof Dog); // проверить является ли halley представителем класса Dog
// -> true
Описание:
Новая переменная halley будет содержать экземпляр класса Dog.
После класса Dog, используется дескриптор new чтобы создать новый экземпляр класса Dog. new вызывает constructor(), запускает код внутри него и затем возвращает новый экземпляр.
Строка 'Halley' передаеся в конструктор Dog, который устанавливает имя 'Halley' для свойства name.
И наконец значение сохраненное в ключе name в объекте halley выводит 'Halley' в консоль.
Методы
Синтаксис классов методов, setters и getters такой же как для объектов, за исключением того, что нельзя включать запятые между методами:
class Dog {
constructor(name) {
this._name = name;
this._behavior = 0;
}
get name() {
return this._name;
}
get behavior() {
return this._behavior;
}
incrementBehavior() {
this._behavior++;
}
}
Вызов методов
Синтаксис вызова свойств или методов такой же как у объектов - нужно после экземпляра добавить точку, затем имя свойства или метода. Для методов так же нужно добавлять открывающие и закрывающие круглые скобки.
В примере созданы два экземпляра, nikko and bradford:
let nikko = new Dog('Nikko'); // создать собаку Nikko
nikko.incrementBehavior(); // добавить 1 к поведению экзепляра nikko
let bradford = new Dog('Bradford'); // создать собаку Bradford
console.log(nikko.behavior); // -> 1
console.log(bradford.behavior); // -> 0
Наследование
Для примера сделан новый класс Cat. Он разделяет пару свойств (_name и _behavior) и метод .incrementBehavior() с классом Dog. Так же у класса Cat есть дополнительное свойство _usesLitter, которое содержит логическое значение, чтобы указать, может ли кошка использовать свой ящик для мусора 🐱:
class Cat {
constructor(name, usesLitter) {
this._name = name;
this._usesLitter = usesLitter;
this._behavior = 0;
}
get name() {
return this._name;
}
get usesLitter() {
return this._usesLitter;
}
get behavior() {
return this._behavior;
}
incrementBehavior() {
this._behavior++;
}
}
Когда несколько классов делят свойства или методы, они становятся кандидатами наследования (inheritance) - инструмент, который разработчики используют для уменьшения количества кода, который им нужно написать.
С наследованием можно создать родительский (parent) класс, также известный как супер класс (superclass), со свойствами и методами, которые разделяют несколько дочерних (child) классов, также называемых подклассами (subclasses). Дочерние классы наследуют свойства и методы из своего родительского класса.
class Animal {
constructor(name) {
this._name = name;
this._behavior = 0;
}
get name() {
return this._name;
}
get behavior() {
return this._behavior;
}
incrementBehavior() {
this._behavior++;
}
hello() {
return 'Hello, I am ' + this._name + '.'
}
}
Используя общие свойства и методы в родительском классе Animal, можно распространить их на подкласс Cat:
Дескриптор extends делает методы класса Animal доступными в классе cat.
Конструктор вызывается, когда создается новый объект Cat, который принимает два аргумента - name и usesLitter.
Дескриптор super вызывает конструктор родительского класса. В этом случае, super(name) передает аргумент имени класса Cat в конструктор класса Animal. Когда выполняется конструктор Animal, он устанавливает this._name = name; для новых экзепляров Cat.
Свойство _usesLitter уникально для класса Cat, и устанавливается только для конструктора Cat.
📝 Примечание: super вызывается в первой строке constructor(), а затем устанавливается свойство usesLitter во второй строке. В constructor() всегда надо вызывать метод super, прежде чем использовать this - иначе JavaScript выдаст ошибку (reference error).
Ниже создан новый экземпляр Cat и вызвано его имя, таким же образом, как и для класса Dog:
const bryceCat = new Cat('Bryce', false);
console.log(bryceCat._name); // -> Bryce
В результате класс Cat имеет доступ к Animal getters и методу .incrementBehavior().
Класс Cat наследует свойство _behavior, getter behavior, и метод .incrementBehavior() класса Animal.
Когда был создан экземпляр bryceCat, конструктор Animal установил значение 0 свойству _behavior.
Первая строчка вызывает наследуемый метод .incrementBehavior(), который увеличивает свойство _behavior в bryceCat на 1.
На второй строчке вызывается getter behavior.
В дополнение к унаследованным функциям дочерние классы могут содержать свои собственные свойства, getters, setters и методы.
Ниже добавлен getter usesLitter. Синтаксис создания getters, setters и методов такой же, как и в любом другом классе:
class Cat extends Animal {
constructor(name, usesLitter) {
super(name);
this._usesLitter = usesLitter;
}
get usesLitter() {
return this._usesLitter;
}
hello() {
return super.hello() + ' I am a cat.'
}
}
Добавился getter usesLitter в классе Cat, который возвращает значение, сохраненное в _usesLitter.
Для того, чтобы сделать дополнительный подкласс Dog:
class Dog extends Animal {
constructor(name) {
super(name);
}
}
Данный класс Dog имеет те же свойства, getters, setters, и методы, что и класс Dog, который был сделан без наследования, и на четверть меньше.
Статические методы
Иногда нужны классы, методы которых не доступны в отдельных экземплярах объектов, но которые можно вызывать прямо из класса.
Например класс Date — можно создать экземпляр Date чтобы представить любую дату, и вызвать статический (static) метод, такой как Date.now(), который возвращает текущую дату прямо из класса. Метод .now() статический, таким образом его можно вызвать прямо из класса, но не из его экземпляра.
Используя дескриптор static, можно создать статический метод generateName в классе Animal, который возвращает случайное имя при вызове:
Из-за ключевого слова static, можно получить доступ к .generateName() добавив его только к классу Animal используя следующий синтаксис:
console.log(Animal.generateName()); // returns a name
Нельзя получить доступ к .generateName() из экзепляра класса Animal или экзепляров его подклассов:
const tyson = new Animal('Tyson');
tyson.generateName(); // TypeError
DOM
На самом базовом уровне веб-сайт состоит из HTML-документа. Браузер, используемый для просмотра веб-сайта, представляет собой программу, которая интерпретирует HTML и CSS и отображает стили, содержимое и структуру на странице, которую вы видите.
Помимо синтаксического анализа (parsing) стилей и структуры HTML и CSS, браузер создает представление документа, известного как объектная модель документа (Document Object Model). Эта модель предоставляет JavaScript доступ к текстовому содержимому и элементам документа веб-сайта в виде объектов.
Объект**document**
Объект document это встроенный объект у которого есть много свойств (properties) и методов (methods), к которым можно получить доступ для изменения сайтов.
Разница между DOM и HTML-кодом
Есть несколько различий между созданной браузером DOM и исходным кодом HTML:
DOM изменяется на стороне клиента JavaScript
Браузер автоматически исправляет ошибки в исходном коде
Манипуляция DOM
Селекторы элементов
DOM структурирован как дерево объектов, называемых узлами (nodes), и узлы могут быть текстом, комментариями или элементами.