Синтаксис JavaScript
Эту статью необходимо обновить . Причина: новые функции/версии теперь в JavaScript. ( ноябрь 2020 г. ) |
Синтаксис . JavaScript — это набор правил, которые определяют правильно структурированную программу JavaScript
В приведенных ниже примерах используется функция журнала объекта консоли, присутствующая в большинстве браузеров для стандартного вывода текста .
JavaScript В стандартной библиотеке отсутствует официальная стандартная функция вывода текста (за исключением document.write
). Учитывая, что JavaScript в основном используется для написания сценариев на стороне клиента в современных веб-браузерах и что почти все веб-браузеры предоставляют функцию оповещения, alert
также может быть использован, но обычно не используется.
Происхождение
[ редактировать ]Брендан Эйх резюмировал происхождение синтаксиса в первом параграфе спецификации JavaScript 1.1. [1] [2] следующее:
JavaScript заимствует большую часть своего синтаксиса из Java , но также наследует от Awk и Perl , с некоторым косвенным влиянием Self в своей системе прототипов объектов.
Основы
[ редактировать ]Чувствительность к регистру
[ редактировать ]JavaScript чувствителен к регистру . Обычно имя конструктора начинается с заглавной буквы , а имя функции или переменной — со строчной.
Пример:
var a = 5;
console.log(a); // 5
console.log(A); // throws a ReferenceError: A is not defined
Пробелы и точки с запятой
[ редактировать ]В отличие от C , пробелы в исходном коде JavaScript могут напрямую влиять на семантику . Точки с запятой завершают операторы в JavaScript. Из-за автоматической вставки точки с запятой (ASI) некоторые операторы, которые правильно сформированы при анализе новой строки, будут считаться завершенными, как если бы точка с запятой была вставлена непосредственно перед новой строкой. Некоторые авторитетные специалисты советуют явно указывать точку с запятой, завершающую оператор, поскольку это может уменьшить непреднамеренные последствия автоматической вставки точки с запятой. [3]
Есть две проблемы: пять токенов могут либо начинать оператор, либо быть продолжением полного оператора; и пять ограниченных постановок, где разрывы строк не допускаются в определенных позициях, что потенциально может привести к неправильному синтаксическому анализу.
Пять проблемных токенов — это открывающая скобка» (
", открывающая скобка" [
", слэш" /
", плюс" +
", и минус" -
". Из них открывающая скобка часто встречается в шаблоне выражения функции, вызываемой непосредственно , а открывающая скобка встречается иногда, а другие встречаются довольно редко. Пример:
a = b + c
(d + e).foo()
// Treated as:
// a = b + c(d + e).foo();
с предложением завершить предыдущий оператор точкой с запятой.
Некоторые предлагают вместо этого использовать точку с запятой в строках, начинающихся с ' (
' или ' [
', чтобы строка случайно не соединилась с предыдущей. Это называется защитной точкой с запятой и особенно рекомендуется, поскольку в противном случае код может стать неоднозначным при его перестановке. Например:
a = b + c
;(d + e).foo()
// Treated as:
// a = b + c;
// (d + e).foo();
Начальные точки с запятой также иногда используются в начале библиотек JavaScript, если они добавляются к другой библиотеке, в которой отсутствует конечная точка с запятой, поскольку это может привести к неоднозначности исходного оператора.
Пять ограниченных постановок: return
, throw
, break
, continue
и пост-инкремент/декремент. Во всех случаях вставка точек с запятой не решает проблему, но делает анализируемый синтаксис понятным, что облегчает обнаружение ошибки. return
и throw
принять необязательное значение, в то время как break
и continue
возьмите дополнительную метку. Во всех случаях рекомендуется размещать значение или метку в той же строке, что и оператор. Чаще всего это проявляется в операторе return, где можно вернуть литерал большого объекта, который может быть случайно помещен в начало новой строки. Для пост-инкремента/декремента существует потенциальная неоднозначность с пре-инкрементом/декрементом, и снова рекомендуется просто хранить их в одной строке.
return
a + b;
// Returns undefined. Treated as:
// return;
// a + b;
// Should be written as:
// return a + b;
Комментарии
[ редактировать ]Синтаксис комментариев такой же, как в C++ , Swift и многих других языках.
// a short, one-line comment
/* this is a long, multi-line comment
about my script. May it one day
be great. */
/* Comments /* may not be nested */ Syntax error */
Переменные
[ редактировать ]Переменные в стандартном JavaScript не имеют прикрепленного типа , поэтому любое значение (каждое значение имеет тип) может быть сохранено в любой переменной. Начиная с ES6 , шестой версии языка, переменные можно было объявлять с помощью var
для переменных области действия функции и let
или const
которые предназначены для переменных уровня блока . До ES6 переменные можно было объявлять только с помощью var
заявление. Значения, присвоенные переменным, объявленным с помощью const
изменить нельзя, но можно изменить их свойства. var
больше не следует использовать, поскольку let
и const
поддерживаются современными браузерами. [4] переменной Идентификатор должен начинаться с буквы, подчеркивания ( _
) или знак доллара ( $
), а последующие символы также могут быть цифрами ( 0-9
). JavaScript чувствителен к регистру, поэтому символы верхнего регистра от «A» до «Z» отличаются от символов нижнего регистра от «a» до «z».
Начиная с JavaScript 1.5, ISO 8859-1 или Unicode (или букв \uXXXX
escape-последовательности Юникода) можно использовать в идентификаторах. [5] В некоторых реализациях JavaScript знак (@) может использоваться в идентификаторе, но это противоречит спецификациям и не поддерживается в новых реализациях. [ нужна ссылка ]
Обзор и подъем
[ редактировать ]Переменные, объявленные с помощью var
на лексически ограничены функциональном уровне , а те, у которых let
или const
иметь область действия на уровне блока . Поскольку объявления обрабатываются до выполнения любого кода, переменную можно назначить и использовать до ее объявления в коде. [6] Это называется hoisting , и это эквивалентно прямому объявлению переменных в верхней части функции или блока. [7]
С var
, let
, и const
заявления, поднимается только декларация; задания не поднимаются. Таким образом var x = 1
оператор в середине функции эквивалентен var x
оператор объявления в верхней части функции и x = 1
оператор присваивания в этой точке в середине функции. Это означает, что к значениям нельзя получить доступ до их объявления; прямая ссылка невозможна. С var
значение переменной undefined
пока он не будет инициализирован. Переменные, объявленные с помощью let
или const
к ним невозможно получить доступ, пока они не будут инициализированы, поэтому обращение к таким переменным раньше приведет к ошибке.
Объявления функций, которые объявляют переменную и присваивают ей функцию, аналогичны операторам переменных, но помимо поднятия объявления они также поднимают присвоение – как если бы весь оператор находился в верхней части содержащей функции – и, таким образом, Также возможна прямая ссылка: расположение оператора функции внутри вмещающей функции не имеет значения. Это отличается от функционального выражения, присваиваемого переменной в var
, let
, или const
заявление.
Так, например,
var func = function() { .. } // declaration is hoisted only
function func() { .. } // declaration and assignment are hoisted
Ограничение области действия блока можно выполнить, обернув весь блок в функцию и затем выполнив ее (это называется шаблоном выражения функции с немедленным вызовом ) или путем объявления переменной с использованием let
ключевое слово.
Декларация и поручение
[ редактировать ]Переменные, объявленные вне области видимости, являются глобальными . Если переменная объявлена в более высокой области, к ней могут получить доступ дочерние области.
Когда JavaScript пытается разрешить идентификатор, он просматривает его в локальной области. Если этот идентификатор не найден, он ищет следующую внешнюю область и так далее по цепочке областей, пока не достигнет глобальной области , где находятся глобальные переменные. Если он все еще не найден, JavaScript выдаст ошибку. ReferenceError
исключение.
При назначении идентификатора JavaScript выполняет точно такой же процесс для получения этого идентификатора, за исключением того, что если он не найден в глобальной области видимости , он создаст «переменную» в области, в которой он был создан. [8] Как следствие, никогда не объявленная переменная будет глобальной, если она ей присвоена. Объявление переменной (с ключевым словом var
) в глобальной области видимости (т.е. вне тела любой функции (или блока в случае let/const)), присвоение никогда не объявляемого идентификатора или добавление свойства к глобальному объекту (обычно window ) также создаст новую глобальную переменную.
JavaScript Обратите внимание, что строгий режим запрещает присвоение необъявленной переменной, что позволяет избежать загрязнения глобального пространства имен.
Примеры
[ редактировать ]Вот несколько примеров объявлений и области видимости переменных:
var x1 = 0; // A global variable, because it is not in any function
let x2 = 0; // Also global, this time because it is not in any block
function f() {
var z = 'foxes', r = 'birds'; // 2 local variables
m = 'fish'; // global, because it wasn't declared anywhere before
function child() {
var r = 'monkeys'; // This variable is local and does not affect the "birds" r of the parent function.
z = 'penguins'; // Closure: Child function is able to access the variables of the parent function.
}
twenty = 20; // This variable is declared on the next line, but usable anywhere in the function, even before, as here
var twenty;
child();
return x1 + x2; // We can use x1 and x2 here, because they are global
}
f();
console.log(z); // This line will raise a ReferenceError exception, because the value of z is no longer available
for (let i = 0; i < 10; i++) console.log(i);
console.log(i); // throws a ReferenceError: i is not defined
for (const i = 0; i < 10; i++) console.log(i); // throws a TypeError: Assignment to constant variable
for (const i of [1,2,3]) console.log(i); //will not raise an exception. i is not reassigned but recreated in every iteration
const pi; // throws a SyntaxError: Missing initializer in const declaration
Примитивные типы данных
[ редактировать ]Язык JavaScript предоставляет шесть примитивных типов данных :
- Неопределенный
- Число
- БигИнт
- Нить
- логическое значение
- Символ
Некоторые из примитивных типов данных также предоставляют набор именованных значений, которые представляют собой границы типов. Эти именованные значения описаны в соответствующих разделах ниже.
Неопределенный
[ редактировать ]Значение «неопределено» присваивается всем неинициализированным переменным , а также возвращается при проверке свойств объекта, которые не существуют. В логическом контексте неопределенное значение считается ложным значением.
Примечание: undefined считается настоящим примитивным типом. Если не преобразовано явно, неопределенное значение может вести себя неожиданно по сравнению с другими типами, которые в логическом контексте оцениваются как false.
let test; // variable declared, but not defined, ...
// ... set to value of undefined
const testObj = {};
console.log(test); // test variable exists, but value not ...
// ... defined, displays undefined
console.log(testObj.myProp); // testObj exists, property does not, ...
// ... displays undefined
console.log(undefined == null); // unenforced type during check, displays true
console.log(undefined === null); // enforce type during check, displays false
Примечание. Для неопределенного не существует встроенного языкового литерала. Таким образом (x === undefined)
не является надежным способом проверить, является ли переменная неопределенной, поскольку в версиях до ECMAScript 5 кому-либо разрешено писать var undefined = "I'm defined now";
. Более надежный подход заключается в сравнении с использованием (typeof x === 'undefined')
.
Подобные функции не будут работать должным образом:
function isUndefined(x) { let u; return x === u; } // like this...
function isUndefined(x) { return x === void 0; } // ... or that second one
function isUndefined(x) { return (typeof x) === "undefined"; } // ... or that third one
Вот, звоню isUndefined(my_var)
поднимает вопрос Ошибка ссылки , если my_var — неизвестный идентификатор, тогда как typeof my_var === 'undefined'
нет.
Число
[ редактировать ]Числа представлены в двоичном формате в виде IEEE 754 двойных чисел с плавающей запятой . Хотя этот формат обеспечивает точность почти 16 значащих цифр , он не всегда может точно представлять действительные числа, включая дроби.
Это становится проблемой при сравнении или форматировании чисел. Например:
console.log(0.2 + 0.1 === 0.3); // displays false
console.log(0.94 - 0.01); // displays 0.9299999999999999
В результате такая процедура, как Метод toFixed() следует использовать для округления чисел всякий раз, когда они форматируются для вывода .
Числа могут быть указаны в любом из следующих обозначений:
345; // an "integer", although there is only one numeric type in JavaScript
34.5; // a floating-point number
3.45e2; // another floating-point, equivalent to 345
0b1011; // a binary integer equal to 11
0o377; // an octal integer equal to 255
0xFF; // a hexadecimal integer equal to 255, digits represented by the ...
// ... letters A-F may be upper or lowercase
Также есть числовой разделитель, _ (подчеркивание), представленное в ES2021:
// Note: Wikipedia syntax doesn't support numeric separators yet
1_000_000_000; // Used with big numbers
1_000_000.5; // Support with decimals
1_000e1_000; // Support with exponents
// Support with binary, octals and hex
0b0000_0000_0101_1011;
0o0001_3520_0237_1327;
0xFFFF_FFFF_FFFF_FFFE;
// But you can't use them next to a non-digit number part, or at the start or end
_12; // Variable is not defined (the underscore makes it a variable identifier)
12_; // Syntax error (cannot be at the end of numbers)
12_.0; // Syntax error (doesn't make sense to put a separator next to the decimal point)
12._0; // Syntax error
12e_6; // Syntax error (next to "e", a non-digit. Doesn't make sense to put a separator at the start)
1000____0000; // Syntax error (next to "_", a non-digit. Only 1 separator at a time is allowed
Экстенты +∞ , −∞ и NaN (Not a Number) числового типа могут быть получены двумя программными выражениями:
Infinity; // positive infinity (negative obtained with -Infinity for instance)
NaN; // The Not-A-Number value, also returned as a failure in ...
// ... string-to-number conversions
Бесконечность и NaN — числа:
typeof Infinity; // returns "number"
typeof NaN; // returns "number"
Эти три специальных значения соответствуют и ведут себя так, как их описывает IEEE-754 .
Конструктор Number (используемый как функция) или унарный + или - могут использоваться для выполнения явного числового преобразования:
const myString = "123.456";
const myNumber1 = Number(myString);
const myNumber2 = +myString;
При использовании в качестве конструктора оболочка создается числовой объект- (хотя от него мало пользы):
const myNumericWrapper = new Number(123.456);
Однако NaN не равен самому себе:
const nan = NaN;
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(NaN !== NaN); // true
console.log(nan !== nan); // true
// You can use the isNaN methods to check for NaN
console.log(isNaN("converted to NaN")); // true
console.log(isNaN(NaN)); // true
console.log(Number.isNaN("not converted")); // false
console.log(Number.isNaN(NaN)); // true
БигИнт
[ редактировать ]BigInts можно использовать для произвольно больших целых чисел . Особенно целые числа больше 2. 53 - 1, которое является наибольшим числом, которое JavaScript может надежно представить с помощью примитива Number и представлено константой Number.MAX_SAFE_INTEGER.
При делении BigInts результаты усекаются .
Нить
[ редактировать ]Строка в JavaScript — это последовательность символов. В JavaScript строки можно создавать напрямую (как литералы), помещая последовательность символов в двойные (") или одинарные (') кавычки. Такие строки должны быть записаны в одной строке, но могут включать экранированные символы новой строки (например, \ n). Стандарт JavaScript позволяет использовать символ обратной кавычки (`, он же серьезный акцент или обратный кавычек) для кавычек многострочных литеральных строк, а также литералов шаблонов, которые допускают интерполяцию вычисляемых выражений с принудительным типом внутри строки. [9]
const greeting = "Hello, World!";
const anotherGreeting = 'Greetings, people of Earth.';
const aMultilineGreeting = `Warm regards,
John Doe.`
// Template literals type-coerce evaluated expressions and interpolate them into the string.
const templateLiteral = `This is what is stored in anotherGreeting: ${anotherGreeting}.`;
console.log(templateLiteral); // 'This is what is stored in anotherGreeting: 'Greetings, people of Earth.''
Доступ к отдельным символам внутри строки можно получить с помощью charAt метод (предоставленный String.prototype ). Это предпочтительный способ доступа к отдельным символам внутри строки, поскольку он также работает в несовременных браузерах:
const h = greeting.charAt(0);
В современных браузерах доступ к отдельным символам внутри строки (как к строкам, состоящим только из одного символа) можно получить с помощью тех же обозначений, что и к массивам:
const h = greeting[0];
Однако строки JavaScript неизменяемы :
greeting[0] = "H"; // Fails.
Применение оператора равенства ("==") к двум строкам возвращает true, если строки имеют одинаковое содержимое, что означает: одинаковую длину и содержащую одинаковую последовательность символов (для алфавитов важен регистр). Таким образом:
const x = "World";
const compare1 = ("Hello, " + x == "Hello, World"); // Here compare1 contains true.
const compare2 = ("Hello, " + x == "hello, World"); // Here compare2 contains ...
// ... false since the ...
// ... first characters ...
// ... of both operands ...
// ... are not of the same case.
Кавычки одного типа не могут быть вложенными, если они не экранированы .
let x = '"Hello, World!" he said.'; // Just fine.
x = ""Hello, World!" he said."; // Not good.
x = "\"Hello, World!\" he said."; // Works by escaping " with \"
The Конструктор String создает строковый объект (объект, обертывающий строку):
const greeting = new String("Hello, World!");
Эти объекты имеют valueOf , возвращающий примитивную строку, заключенную в них:
const s = new String("Hello !");
typeof s; // Is 'object'.
typeof s.valueOf(); // Is 'string'.
Равенство между двумя Строковые объекты ведут себя не так, как строковые примитивы:
const s1 = new String("Hello !");
const s2 = new String("Hello !");
s1 == s2; // Is false, because they are two distinct objects.
s1.valueOf() == s2.valueOf(); // Is true.
логическое значение
[ редактировать ]JavaScript предоставляет логический тип данных с правда и ложные литералы. Оператор typeof возвращает строку «логическое» для этих примитивных типов . При использовании в логическом контексте 0 , -0 , нулевой , НЭН , undefined и пустая строка ( "" ) оценить как false из-за автоматического преобразования типов . Все остальные значения ( дополняющие предыдущий список) оцениваются как true , включая строки "0" , «ложь» и любой объект.
Преобразование типов
[ редактировать ]Автоматическое приведение типов с помощью операторов сравнения на равенство ( ==
и !=
) можно избежать, используя операторы сравнения с проверкой типа ( ===
и !==
).
Когда требуется преобразование типов, JavaScript преобразует Логическое значение , Число , Строка или Операнды объекта следующие: [10]
- Число и строка
- Строка преобразуется в числовое значение. JavaScript пытается преобразовать строковый числовой литерал в значение числового типа. Во-первых, математическое значение получается из строкового числового литерала. Затем это значение округляется до ближайшего значения числового типа.
- логическое значение
- Если один из операндов является логическим, логический операнд преобразуется в 1, если он true или 0, если это так ЛОЖЬ .
- Объект
- Если объект сравнивается с числом или строкой, JavaScript пытается вернуть значение по умолчанию для объекта. Объект преобразуется в примитивное строковое или числовое значение с помощью метода .valueOf() или .toString() методы объекта. Если это не удается, генерируется ошибка времени выполнения.
Дуглас Крокфорд защищает термины « истинный » и « ложный » для описания того, как значения различных типов ведут себя при оценке в логическом контексте, особенно в отношении крайних случаев. [11]
Бинарные логические операторы возвращали логическое значение в ранних версиях JavaScript, но теперь вместо этого они возвращают один из операндов. Возвращается левый операнд, если его можно оценить как: false , в случае соединения : ( a && b
), или верно , в случае дизъюнкции : ( a || b
); в противном случае возвращается правый операнд. Автоматическое приведение типов с помощью операторов сравнения может отличаться для случаев смешанных логических и числовых операндов (включая строки, которые могут быть оценены как числа, или объекты, которые могут быть оценены как такие строки), поскольку логический операнд будет сравниваться как числовое значение. Это может быть неожиданно. Выражение можно явно привести к логическому примитиву, удвоив оператор логического отрицания : ( !! ), используя Boolean() или с помощью условного оператора : ( c ? t : f
).
// Automatic type coercion
console.log(true == 2 ); // false... true → 1 !== 2 ← 2
console.log(false == 2 ); // false... false → 0 !== 2 ← 2
console.log(true == 1 ); // true.... true → 1 === 1 ← 1
console.log(false == 0 ); // true.... false → 0 === 0 ← 0
console.log(true == "2"); // false... true → 1 !== 2 ← "2"
console.log(false == "2"); // false... false → 0 !== 2 ← "2"
console.log(true == "1"); // true.... true → 1 === 1 ← "1"
console.log(false == "0"); // true.... false → 0 === 0 ← "0"
console.log(false == "" ); // true.... false → 0 === 0 ← ""
console.log(false == NaN); // false... false → 0 !== NaN
console.log(NaN == NaN); // false...... NaN is not equivalent to anything, including NaN.
// Type checked comparison (no conversion of types and values)
console.log(true === 1); // false...... data types do not match
// Explicit type coercion
console.log(true === !!2); // true.... data types and values match
console.log(true === !!0); // false... data types match, but values differ
console.log( 1 ? true : false); // true.... only ±0 and NaN are "falsy" numbers
console.log("0" ? true : false); // true.... only the empty string is "falsy"
console.log(Boolean({})); // true.... all objects are "truthy"
Оператор new можно использовать для создания оболочки объекта для логического примитива. Однако оператор typeof не возвращает логическое значение для оболочки объекта, оно возвращает объект . Поскольку все объекты оцениваются как правда , такой метод, как .valueOf() или .toString() необходимо использовать для получения завернутого значения. Для явного приведения к логическому типу Mozilla рекомендует использовать Boolean() (без Функция new ) предпочтительнее использовать логический объект.
const b = new Boolean(false); // Object false {}
const t = Boolean(b); // Boolean true
const f = Boolean(b.valueOf()); // Boolean false
let n = new Boolean(b); // Not recommended
n = new Boolean(b.valueOf()); // Preferred
if (0 || -0 || "" || null || undefined || b.valueOf() || !new Boolean() || !t) {
console.log("Never this");
} else if ([] && {} && b && typeof b === "object" && b.toString() === "false") {
console.log("Always this");
}
Символ
[ редактировать ]Новое в ECMAScript6. Символ — это уникальный и неизменяемый идентификатор.
Пример:
let x = Symbol(1);
const y = Symbol(1);
x === y; // => false
const symbolObject = {};
const normalObject = {};
// since x and y are unique,
// they can be used as unique keys in an object
symbolObject[x] = 1;
symbolObject[y] = 2;
symbolObject[x]; // => 1
symbolObject[y]; // => 2
// as compared to normal numeric keys
normalObject[1] = 1;
normalObject[1] = 2; // overrides the value of 1
normalObject[1]; // => 2
// changing the value of x does not change the key stored in the object
x = Symbol(3);
symbolObject[x]; // => undefined
// changing x back just creates another unique Symbol
x = Symbol(1);
symbolObject[x]; // => undefined
Есть также хорошо известные символы .
Один из которых Symbol.iterator
; если что-то реализуется Symbol.iterator
, это итеративно:
const x = [1, 2, 3, 4]; // x is an Array
x[Symbol.iterator] === Array.prototype[Symbol.iterator]; // and Arrays are iterable
const xIterator = x[Symbol.iterator](); // The [Symbol.iterator] function should provide an iterator for x
xIterator.next(); // { value: 1, done: false }
xIterator.next(); // { value: 2, done: false }
xIterator.next(); // { value: 3, done: false }
xIterator.next(); // { value: 4, done: false }
xIterator.next(); // { value: undefined, done: true }
xIterator.next(); // { value: undefined, done: true }
// for..of loops automatically iterate values
for (const value of x) {
console.log(value); // 1 2 3 4
}
// Sets are also iterable:
[Symbol.iterator] in Set.prototype; // true
for (const value of new Set(['apple', 'orange'])) {
console.log(value); // "apple" "orange"
}
Нативные объекты
[ редактировать ]Язык JavaScript предоставляет несколько собственных объектов . Собственные объекты JavaScript считаются частью спецификации JavaScript. Несмотря на среду JavaScript, этот набор объектов всегда должен быть доступен.
Множество
[ редактировать ]Массив — это объект JavaScript, прототип которого взят из Array
конструктор, специально предназначенный для хранения значений данных, индексированных целочисленными ключами. Массивы, в отличие от базового типа Object, имеют методы и свойства, помогающие программисту выполнять рутинные задачи (например, join
, slice
, и push
).
Как и в семействе C , в массивах используется схема индексации с отсчетом от нуля: значение, которое вставляется в пустой массив с помощью push
метод занимает 0-й индекс массива.
const myArray = []; // Point the variable myArray to a newly ...
// ... created, empty Array
myArray.push("hello World"); // Fill the next empty index, in this case 0
console.log(myArray[0]); // Equivalent to console.log("hello World");
Массивы имеют length
свойство, которое гарантированно всегда будет больше, чем наибольший целочисленный индекс, используемый в массиве. Он автоматически обновляется, если создать свойство с еще большим индексом. Записывая меньшее число в length
свойство удалит более крупные индексы.
Элементы Array
Доступ к s можно получить, используя обычную нотацию доступа к свойствам объекта:
myArray[1]; // the 2nd item in myArray
myArray["1"];
Вышеуказанные два эквивалентны. Невозможно использовать «точечную» запись или строки с альтернативными представлениями числа:
myArray.1; // syntax error
myArray["01"]; // not the same as myArray[1]
В объявлении массива можно использовать либо Array
буквально или Array
конструктор:
let myArray;
// Array literals
myArray = [1, 2]; // length of 2
myArray = [1, 2,]; // same array - You can also have an extra comma at the end
// It's also possible to not fill in parts of the array
myArray = [0, 1, /* hole */, /* hole */, 4, 5]; // length of 6
myArray = [0, 1, /* hole */, /* hole */, 4, 5,]; // same array
myArray = [0, 1, /* hole */, /* hole */, 4, 5, /* hole */,]; // length of 7
// With the constructor
myArray = new Array(0, 1, 2, 3, 4, 5); // length of 6
myArray = new Array(365); // an empty array with length 365
Массивы реализованы таким образом, что только определенные элементы используют память; они представляют собой « разреженные массивы ». Параметр myArray[10] = 'someThing'
и myArray[57] = 'somethingOther'
использует пространство только для этих двух элементов, как и любой другой объект. length
часть массива по-прежнему будет равна 58. Максимальная длина массива равна 4 294 967 295, что соответствует 32-битному двоичному числу (111111111111111111111111111111111) 2 .
Литерал объявления объекта можно использовать для создания объектов, которые ведут себя во многом подобно ассоциативным массивам в других языках:
const dog = {color: "brown", size: "large"};
dog["color"]; // results in "brown"
dog.color; // also results in "brown"
Литералы объявления объектов и массивов можно использовать для быстрого создания ассоциативных, многомерных или того и другого массивов. (Технически JavaScript не поддерживает многомерные массивы, но их можно имитировать с помощью массивов массивов.)
const cats = [{color: "brown", size: "large"},
{color: "black", size: "small"}];
cats[0]["size"]; // results in "large"
const dogs = {rover: {color: "brown", size: "large"},
spot: {color: "black", size: "small"}};
dogs["spot"]["size"]; // results in "small"
dogs.rover.color; // results in "brown"
Дата
[ редактировать ]А Date
объект хранит число миллисекунд со знаком, где ноль представляет 1970-01-01 00:00:00 UT и диапазон ±10. 8 дни. Существует несколько способов аргументации Date
конструктор. Обратите внимание, что месяцы отсчитываются от нуля.
new Date(); // create a new Date instance representing the current time/date.
new Date(2010, 2, 1); // create a new Date instance representing 2010-Mar-01 00:00:00
new Date(2010, 2, 1, 14, 25, 30); // create a new Date instance representing 2010-Mar-01 14:25:30
new Date("2010-3-1 14:25:30"); // create a new Date instance from a String.
Предоставляются методы для извлечения полей, а также полезная toString
:
const d = new Date(2010, 2, 1, 14, 25, 30); // 2010-Mar-01 14:25:30;
// Displays '2010-3-1 14:25:30':
console.log(d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' '
+ d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds());
// Built-in toString returns something like 'Mon Mar 01 2010 14:25:30 GMT-0500 (EST)':
console.log(d);
Ошибка
[ редактировать ]Пользовательские сообщения об ошибках могут быть созданы с помощью Error
сорт:
throw new Error("Something went wrong.");
Их можно перехватить с помощью блоков try...catch...finally, как описано в разделе об обработке исключений .
Математика
[ редактировать ]The Объект Math содержит различные константы, связанные с математикой (например, π ) и функции (например, косинус). (Обратите внимание, что Math объект не имеет конструктора, в отличие от Массив или Дата . Все его методы являются «статическими», то есть методами «класса». Все тригонометрические функции используют углы, выраженные в радианах , а не в градусах или градусах .
Свойство | Возвращаемое значение округлено до 5 цифр |
Описание |
---|---|---|
Математика.Э | 2.7183 | e : основание натурального логарифма. |
Тип.LN2 | 0.69315 | Натуральный логарифм 2 |
Хорошо.LN10 | 2.3026 | Натуральный логарифм 10 |
Math.LOG2E | 1.4427 | Логарифм по основанию 2 от e |
Мат.LOG10E | 0.43429 | Логарифм по основанию 10 от e |
Матем.ПИ | 3.14159 | π : длина окружности/диаметр круга. |
Матем.SQRT1_2 | 0.70711 | Квадратный корень из ½ |
Математика.SQRT2 | 1.4142 | Квадратный корень из 2 |
Пример | Возвращаемое значение округлено до 5 цифр |
Описание |
---|---|---|
Мат.abs(-2.3) | 2.3 | Абсолютное значение |
Math.acos(Math.SQRT1_2) | 0,78540 рад = 45° | Арккосинус |
Math.asin(Math.SQRT1_2) | 0,78540 рад = 45° | Арксинус |
Мат.атан(1) | 0,78540 рад = 45° | полукруга Арктангенс ( от до ) |
Мат.атан2(-3,7, -3,7) | -2,3562 рад = -135° | Арктангенс целого круга ( от до ) |
Мат.cel(1.1) | 2 | Потолок: округлить до наименьшего целого числа ≥ аргумента. |
Math.cos(Math.PI/4) | 0.70711 | Косинус |
Мат.эксп(1) | 2.7183 | Показательная функция : e, возведенная в эту степень |
Мат.пол(1.9) | 1 | Этаж: округление до наибольшего целого числа ≤ аргумента |
Math.log(Math.E) | 1 | Натуральный логарифм по основанию e |
Мат.макс(1, -2) | 1 | Максимум: (х > у) ? х: у |
Мат.мин(1, -2) | −2 | Минимум: (х <у)? х: у |
Math.pow(-3, 2) | 9 | Возведение в степень (возведенное в степень): Math.pow(x, y) дает x и |
Мат.случайный() | например 0,17068 | Псевдослучайное число от 0 (включительно) до 1 (исключительно). |
Мат.раунд(1.5) | 2 | Округлить до ближайшего целого числа; половинные дроби округляются в большую сторону (например, 1,5 округляются до 2) |
Math.sin(Math.PI/4) | 0.70711 | Его |
Мат.кв.(49) | 7 | Квадратный корень |
Math.tan(Math.PI/4) | 1 | Касательная |
Регулярное выражение
[ редактировать ]/expression/.test(string); // returns Boolean
"string".search(/expression/); // returns position Number
"string".replace(/expression/, replacement);
// Here are some examples
if (/Tom/.test("My name is Tom")) console.log("Hello Tom!");
console.log("My name is Tom".search(/Tom/)); // == 11 (letters before Tom)
console.log("My name is Tom".replace(/Tom/, "John")); // == "My name is John"
Классы персонажей
[ редактировать ]// \d - digit
// \D - non digit
// \s - space
// \S - non space
// \w - word char
// \W - non word
// [ ] - one of
// [^] - one not of
// - - range
if (/\d/.test('0')) console.log('Digit');
if (/[0-9]/.test('6')) console.log('Digit');
if (/[13579]/.test('1')) console.log('Odd number');
if (/\S\S\s\S\S\S\S/.test('My name')) console.log('Format OK');
if (/\w\w\w/.test('Tom')) console.log('Hello Tom');
if (/[a-zA-Z]/.test('B')) console.log('Letter');
Соответствие символов
[ редактировать ]// A...Z a...z 0...9 - alphanumeric
// \u0000...\uFFFF - Unicode hexadecimal
// \x00...\xFF - ASCII hexadecimal
// \t - tab
// \n - new line
// \r - CR
// . - any character
// | - OR
if (/T.m/.test('Tom')) console.log ('Hi Tom, Tam or Tim');
if (/A|B/.test("A")) console.log ('A or B');
Ретрансляторы
[ редактировать ]// ? - 0 or 1 match
// * - 0 or more
// + - 1 or more
// {n} - exactly n
// {n,} - n or more
// {0,n} - n or less
// {n,m} - range n to m
if (/ab?c/.test("ac")) console.log("OK"); // match: "ac", "abc"
if (/ab*c/.test("ac")) console.log("OK"); // match: "ac", "abc", "abbc", "abbbc" etc.
if (/ab+c/.test("abc")) console.log("OK"); // match: "abc", "abbc", "abbbc" etc.
if (/ab{3}c/.test("abbbc")) console.log("OK"); // match: "abbbc"
if (/ab{3,}c/.test("abbbc")) console.log("OK"); // match: "abbbc", "abbbbc", "abbbbbc" etc.
if (/ab{1,3}c/.test("abc")) console.log("OK"); // match: "abc", "abbc", "abbbc"
Якоря
[ редактировать ]// ^ - string starts with
// $ - string ends with
if (/^My/.test("My name is Tom")) console.log ("Hi!");
if (/Tom$/.test("My name is Tom")) console.log ("Hi Tom!");
Подвыражение
[ редактировать ]// ( ) - groups characters
if (/water(mark)?/.test("watermark")) console.log("Here is water!"); // match: "water", "watermark",
if (/(Tom)|(John)/.test("John")) console.log("Hi Tom or John!");
Флаги
[ редактировать ]// /g - global
// /i - ignore upper/lower case
// /m - allow matches to span multiple lines
console.log("hi tom!".replace(/Tom/i, "John")); // == "hi John!"
console.log("ratatam".replace(/ta/, "tu")); // == "ratutam"
console.log("ratatam".replace(/ta/g, "tu")); // == "ratutum"
Расширенные методы
[ редактировать ]my_array = my_string.split(my_delimiter);
// example
my_array = "dog,cat,cow".split(","); // my_array==["dog","cat","cow"];
my_array = my_string.match(my_expression);
// example
my_array = "We start at 11:30, 12:15 and 16:45".match(/\d\d:\d\d/g); // my_array==["11:30","12:15","16:45"];
Группы захвата
[ редактировать ]const myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/;
const results = myRe.exec("The date and time are 2009-09-08 09:37:08.");
if (results) {
console.log("Matched: " + results[0]); // Entire match
const my_date = results[1]; // First group == "2009-09-08"
const my_time = results[2]; // Second group == "09:37:08"
console.log(`It is ${my_time} on ${my_date}`);
} else console.log("Did not find a valid date!");
Функция
[ редактировать ]Каждая функция в JavaScript является экземпляром Function
конструктор:
// x, y is the argument. 'return x + y' is the function body, which is the last in the argument list.
const add = new Function('x', 'y', 'return x + y');
add(1, 2); // => 3
Приведенную выше функцию добавления также можно определить с помощью функционального выражения:
const add = function(x, y) {
return x + y;
};
add(1, 2); // => 3
В ES6 был добавлен синтаксис стрелочных функций, что позволяет функциям, возвращающим значение, быть более краткими. Они также сохраняют this
глобального объекта вместо того, чтобы наследовать его от того, откуда он был вызван/как он был вызван, в отличие от function() {}
выражение.
const add = (x, y) => {return x + y;};
// values can also be implicitly returned (i.e. no return statement is needed)
const addImplicit = (x, y) => x + y;
add(1, 2); // => 3
addImplicit(1, 2) // => 3
Для функций, которые необходимо поднять, есть отдельное выражение:
function add(x, y) {
return x + y;
}
add(1, 2); // => 3
Подъем позволяет использовать функцию до ее «объявления»:
add(1, 2); // => 3, not a ReferenceError
function add(x, y) {
return x + y;
}
Экземпляр функции имеет свойства и методы.
function subtract(x, y) {
return x - y;
}
console.log(subtract.length); // => 2, arity of the function (number of arguments)
console.log(subtract.toString());
/*
"function subtract(x, y) {
return x - y;
}"
*/
Операторы
[ редактировать ]Оператор «+» перегружен : он используется для объединения строк и арифметического сложения. Это может вызвать проблемы при случайном смешивании строк и чисел. Как унарный оператор, он может преобразовать числовую строку в число.
// Concatenate 2 strings
console.log('He' + 'llo'); // displays Hello
// Add two numbers
console.log(2 + 6); // displays 8
// Adding a number and a string results in concatenation (from left to right)
console.log(2 + '2'); // displays 22
console.log('$' + 3 + 4); // displays $34, but $7 may have been expected
console.log('$' + (3 + 4)); // displays $7
console.log(3 + 4 + '7'); // displays 77, numbers stay numbers until a string is added
// Convert a string to a number using the unary plus
console.log(+'2' === 2); // displays true
console.log(+'Hello'); // displays NaN
Аналогичным образом перегружен оператор «*»: он может преобразовать строку в число.
console.log(2 + '6'*1); // displays 8
console.log(3*'7'); // 21
console.log('3'*'7'); // 21
console.log('hello'*'world'); // displays NaN
Арифметика
[ редактировать ]JavaScript поддерживает следующие операторы двоичной арифметики :
+ |
добавление |
- |
вычитание |
* |
умножение |
/ |
деление (возвращает значение с плавающей запятой) |
% |
по модулю (возвращает остаток) |
** |
возведение в степень |
JavaScript поддерживает следующие унарные арифметические операторы :
+ |
унарное преобразование строки в число |
- |
унарное отрицание (меняет знак) |
++ |
приращение (может быть префиксным или постфиксным) |
-- |
декремент (может быть префиксным или постфиксным) |
let x = 1;
console.log(++x); // x becomes 2; displays 2
console.log(x++); // displays 2; x becomes 3
console.log(x); // x is 3; displays 3
console.log(x--); // displays 3; x becomes 2
console.log(x); // displays 2; x is 2
console.log(--x); // x becomes 1; displays 1
Оператор modulo отображает остаток от деления на модуль. Если используются отрицательные числа, возвращаемое значение зависит от операнда.
const x = 17;
console.log(x%5); // displays 2
console.log(x%6); // displays 5
console.log(-x%5); // displays -2
console.log(-x%-5); // displays -2
console.log(x%-5); // displays 2
Чтобы всегда возвращать неотрицательное число, повторно добавьте модуль и снова примените оператор модуля:
const x = 17;
console.log((-x%5+5)%5); // displays 3
Вы также можете сделать:
const x = 17;
console.log(Math.abs(-x%5)); // also 3
Назначение
[ редактировать ]= |
назначать |
+= |
добавить и назначить |
-= |
вычесть и присвоить |
*= |
умножить и присвоить |
/= |
раздели и назначь |
%= |
по модулю и присвоить |
**= |
возведение в степень и присвоение |
Присвоение примитивных типов
let x = 9;
x += 1;
console.log(x); // displays: 10
x *= 30;
console.log(x); // displays: 300
x /= 6;
console.log(x); // displays: 50
x -= 3;
console.log(x); // displays: 47
x %= 7;
console.log(x); // displays: 5
Назначение типов объектов
/**
* To learn JavaScript objects...
*/
const object_1 = {a: 1}; // assign reference of newly created object to object_1
let object_2 = {a: 0};
let object_3 = object_2; // object_3 references the same object as object_2 does
object_3.a = 2;
message(); // displays 1 2 2
object_2 = object_1; // object_2 now references the same object as object_1
// object_3 still references what object_2 referenced before
message(); // displays 1 1 2
object_2.a = 7; // modifies object_1
message(); // displays 7 7 2
object_3.a = 5; // object_3 doesn't change object_2
message(); // displays 7 7 5
object_3 = object_2;
object_3.a=4; // object_3 changes object_1 and object_2
message(); // displays 4 4 4
/**
* Prints the console.log message
*/
function message() {
console.log(object_1.a + " " + object_2.a + " " + object_3.a);
}
Деструктуризация задания
[ редактировать ]В JavaScript Mozilla, начиная с версии 1.7, деструктурирующее присваивание позволяет присваивать части структур данных нескольким переменным одновременно. Левая часть присваивания представляет собой шаблон, напоминающий произвольно вложенный литерал объекта/массива, содержащий значения l-l в своих листьях, которые должны получить подструктуры присвоенного значения.
let a, b, c, d, e;
[a, b, c] = [3, 4, 5];
console.log(`${a},${b},${c}`); // displays: 3,4,5
e = {foo: 5, bar: 6, baz: ['Baz', 'Content']};
const arr = [];
({baz: [arr[0], arr[3]], foo: a, bar: b} = e);
console.log(`${a},${b},${arr}`); // displays: 5,6,Baz,,,Content
[a, b] = [b, a]; // swap contents of a and b
console.log(a + ',' + b); // displays: 6,5
[a, b, c] = [3, 4, 5]; // permutations
[a, b, c] = [b, c, a];
console.log(`${a},${b},${c}`); // displays: 4,5,3
Оператор распространения/остановки
[ редактировать ]Стандарт ECMAScript 2015 представил « ...
" оператор массива для связанных понятий "расширенного синтаксиса" [12] и «параметры покоя». [13] Распространение объектов было добавлено в ECMAScript 2018.
Синтаксис расширения предоставляет еще один способ деструктуризации массивов и объектов. Для массивов это означает, что элементы следует использовать в качестве параметров при вызове функции или элементов в литерале массива. Для объектов его можно использовать для объединения объектов или переопределения свойств.
Другими словами, " ...
"превращает" [...foo]
" в " [foo[0], foo[1], foo[2]]
", и " this.bar(...foo);
" в " this.bar(foo[0], foo[1], foo[2]);
", и " { ...bar }
" в { prop: bar.prop, prop2: bar.prop2 }
.
const a = [1, 2, 3, 4];
// It can be used multiple times in the same expression
const b = [...a, ...a]; // b = [1, 2, 3, 4, 1, 2, 3, 4];
// It can be combined with non-spread items.
const c = [5, 6, ...a, 7, 9]; // c = [5, 6, 1, 2, 3, 4, 7, 9];
// For comparison, doing this without the spread operator
// creates a nested array.
const d = [a, a]; // d = [[1, 2, 3, 4], [1, 2, 3, 4]]
// It works the same with function calls
function foo(arg1, arg2, arg3) {
console.log(`${arg1}:${arg2}:${arg3}`);
}
// You can use it even if it passes more parameters than the function will use
foo(...a); // "1:2:3" → foo(a[0], a[1], a[2], a[3]);
// You can mix it with non-spread parameters
foo(5, ...a, 6); // "5:1:2" → foo(5, a[0], a[1], a[2], a[3], 6);
// For comparison, doing this without the spread operator
// assigns the array to arg1, and nothing to the other parameters.
foo(a); // "1,2,3,4:undefined:undefined"
const bar = { a: 1, b: 2, c: 3 };
// This would copy the object
const copy = { ...bar }; // copy = { a: 1, b: 2, c: 3 };
// "b" would be overridden here
const override = { ...bar, b: 4 }; // override = { a: 1, c: 3, b: 4 }
Когда ...
используется в объявлении функции и указывает на оставшийся параметр . Оставшийся параметр должен быть последним именованным параметром в списке параметров функции. Ему будет присвоен Array
содержащий любые аргументы, переданные функции, сверх других именованных параметров. Другими словами, он получает «остальные» аргументы, переданные функции (отсюда и название).
function foo(a, b, ...c) {
console.log(c.length);
}
foo(1, 2, 3, 4, 5); // "3" → c = [3, 4, 5]
foo('a', 'b'); // "0" → c = []
Остальные параметры аналогичны параметрам Javascript arguments
объект, который представляет собой объект, подобный массиву, который содержит все параметры (именованные и безымянные) в текущем вызове функции. В отличие от arguments
, однако остальные параметры верны Array
объекты, поэтому такие методы, как .slice()
и .sort()
можно использовать непосредственно на них.
Сравнение
[ редактировать ]== |
равный |
!= |
не равный |
> |
больше, чем |
>= |
больше или равно |
< |
меньше, чем |
<= |
меньше или равно |
=== |
идентичный (равный и одного типа) |
!== |
не идентичны |
Переменные, ссылающиеся на объекты, равны или идентичны, только если они ссылаются на один и тот же объект:
const obj1 = {a: 1};
const obj2 = {a: 1};
const obj3 = obj1;
console.log(obj1 == obj2); //false
console.log(obj3 == obj1); //true
console.log(obj3 === obj1); //true
См. также Строка .
Логический
[ редактировать ]JavaScript предоставляет четыре логических оператора:
- унарное отрицание (
NOT = !a
) - бинарная дизъюнкция (
OR = a || b
) и союз (AND = a && b
) - троичный условный (
c ? t : f
)
В контексте логической операции любое выражение имеет значение true, за исключением следующих :
- Струны:
""
,''
, - Числа:
0
,-0
,NaN
, - Особенный:
null
,undefined
, - Логическое значение:
false
.
Логическую функцию можно использовать для явного преобразования в примитив типа Boolean
:
// Only empty strings return false
console.log(Boolean("") === false);
console.log(Boolean("false") === true);
console.log(Boolean("0") === true);
// Only zero and NaN return false
console.log(Boolean(NaN) === false);
console.log(Boolean(0) === false);
console.log(Boolean(-0) === false); // equivalent to -1*0
console.log(Boolean(-2) === true);
// All objects return true
console.log(Boolean(this) === true);
console.log(Boolean({}) === true);
console.log(Boolean([]) === true);
// These types return false
console.log(Boolean(null) === false);
console.log(Boolean(undefined) === false); // equivalent to Boolean()
Оператор NOT оценивает свой операнд как логическое значение и возвращает отрицание. Использование оператора дважды подряд, например двойного отрицания , явно преобразует выражение в примитив логического типа:
console.log( !0 === Boolean(!0));
console.log(Boolean(!0) === !!1);
console.log(!!1 === Boolean(1));
console.log(!!0 === Boolean(0));
console.log(Boolean(0) === !1);
console.log(!1 === Boolean(!1));
console.log(!"" === Boolean(!""));
console.log(Boolean(!"") === !!"s");
console.log(!!"s" === Boolean("s"));
console.log(!!"" === Boolean(""));
console.log(Boolean("") === !"s");
console.log(!"s" === Boolean(!"s"));
Тернарный оператор также можно использовать для явного преобразования:
console.log([] == false); console.log([] ? true : false); // “truthy”, but the comparison uses [].toString()
console.log([0] == false); console.log([0]? true : false); // [0].toString() == "0"
console.log("0" == false); console.log("0"? true : false); // "0" → 0 ... (0 == 0) ... 0 ← false
console.log([1] == true); console.log([1]? true : false); // [1].toString() == "1"
console.log("1" == true); console.log("1"? true : false); // "1" → 1 ... (1 == 1) ... 1 ← true
console.log([2] != true); console.log([2]? true : false); // [2].toString() == "2"
console.log("2" != true); console.log("2"? true : false); // "2" → 2 ... (2 != 1) ... 1 ← true
Выражения, использующие такие функции, как постинкрементирование ( i++
) имеют ожидаемый побочный эффект . JavaScript обеспечивает сокращенную оценку выражений; правый операнд выполняется только в том случае, если левого операнда недостаточно для определения значения выражения.
console.log(a || b); // When a is true, there is no reason to evaluate b.
console.log(a && b); // When a is false, there is no reason to evaluate b.
console.log(c ? t : f); // When c is true, there is no reason to evaluate f.
В ранних версиях JavaScript и JScript бинарные логические операторы возвращали логическое значение (как и в большинстве языков программирования, производных от C). Однако все современные реализации вместо этого возвращают один из своих операндов:
console.log(a || b); // if a is true, return a, otherwise return b
console.log(a && b); // if a is false, return a, otherwise return b
Программистам, более знакомым с поведением C, эта функция может показаться удивительной, но она позволяет более кратко выражать такие шаблоны, как объединение значений null :
const s = t || "(default)"; // assigns t, or the default value, if t is null, empty, etc.
Логическое задание
[ редактировать ]??=
|
Нулевое присвоение |
||=
|
Логическое ИЛИ присваивание |
&&=
|
Логическое И присваивание |
Побитовый
[ редактировать ]JavaScript поддерживает следующие двоичные побитовые операторы :
& |
И |
| |
ИЛИ |
^ |
БЕСПЛАТНО |
! |
НЕТ |
<< |
сдвиг влево (заполнение нулями справа) |
>> |
сдвиг вправо (с распространением знака); копии Крайний левый бит (знаковый бит) сдвигается слева |
>>> |
сдвиг вправо (заполнение нулями слева). Для положительных чисел >> и >>> дать тот же результат.
|
Примеры:
const x = 11 & 6;
console.log(x); // 2
JavaScript поддерживает следующий унарный побитовый оператор :
~ |
НЕ (инвертирует биты) |
Побитовое присваивание
[ редактировать ]JavaScript поддерживает следующие операторы двоичного присваивания:
&= |
и |
|= |
или |
^= |
бесплатно |
<<= |
сдвиг влево (заполнение нулями справа) |
>>= |
сдвиг вправо (с распространением знака); копии Крайний левый бит (знаковый бит) сдвигается слева |
>>>= |
сдвиг вправо (заполнение нулями слева). Для положительных чисел >>= и >>>= дать тот же результат.
|
Примеры:
let x=7;
console.log(x); // 7
x<<=3;
console.log(x); // 7->14->28->56
Нить
[ редактировать ]= |
назначение |
+ |
конкатенация |
+= |
объединить и назначить |
Примеры:
let str = "ab" + "cd"; // "abcd"
str += "e"; // "abcde"
const str2 = "2" + 2; // "22", not "4" or 4.
??
[ редактировать ] JavaScript : Ближайший оператор ??
, «нулевой оператор объединения», который был добавлен в стандарт в ECMAScript . 11-м издании [14] В более ранних версиях его можно было использовать через плагин Babel и в TypeScript . Он оценивает свой левый операнд и, если значение результата не является «нулевым» ( null
или undefined
), принимает это значение как результат; в противном случае он оценивает правый операнд и принимает полученное значение в качестве результата.
В следующем примере a
будет присвоено значение b
если значение b
не null
или undefined
, в противном случае ему будет присвоено 3.
const a = b ?? 3;
Перед нулевым оператором объединения программисты использовали бы логический оператор ИЛИ ( ||
). Но где ??
ищет специально для null
или undefined
, ||
оператор ищет любое ложное значение: null
, undefined
, ""
, 0
, NaN
, и, конечно, false
.
В следующем примере a
будет присвоено значение b
если значение b
является правдивым , в противном случае ему будет присвоено 3.
const a = b || 3;
Структуры управления
[ редактировать ]Сложные утверждения
[ редактировать ]Пара фигурных скобок { }
а вложенная последовательность операторов представляет собой составной оператор, который можно использовать везде, где можно использовать оператор.
Если... еще
[ редактировать ]if (expr) {
//statements;
} else if (expr2) {
//statements;
} else {
//statements;
}
Условный (тройной) оператор
[ редактировать ]Условный оператор создает выражение, которое оценивается как одно из двух выражений в зависимости от условия. Это похоже на оператор if , который выбирает один из двух операторов для выполнения в зависимости от условия. Т. е. условный оператор относится к выражениям, а что если — к операторам.
const result = condition ? expression : alternative;
то же самое, что:
if (condition) {
const result = expression;
} else {
const result = alternative;
}
В отличие от оператора if , условный оператор не может опустить свою «другую ветвь».
Оператор переключения
[ редактировать ]Синтаксис оператора переключателя JavaScript следующий:
switch (expr) {
case SOMEVALUE:
// statements;
break;
case ANOTHERVALUE:
// statements for when ANOTHERVALUE || ORNAOTHERONE
// no break statement, falling through to the following case
case ORANOTHERONE:
// statements specific to ORANOTHERONE (i.e. !ANOTHERVALUE && ORANOTHER);
break; //The buck stops here.
case YETANOTHER:
// statements;
break;
default:
// statements;
break;
}
break;
является необязательным; однако обычно это необходимо, поскольку в противном случае выполнение кода продолжится до тела следующего блока case. Такое провальное поведение можно использовать, когда один и тот же набор утверждений применяется в нескольких случаях, эффективно создавая различие между этими случаями.- Добавьте оператор прерывания в конец последнего случая в качестве меры предосторожности на случай, если позже будут добавлены дополнительные случаи.
- Строковые литералы также могут использоваться для значений регистра.
- Вместо значений можно использовать выражения.
- Случай по умолчанию (необязательный) выполняется, когда выражение не соответствует ни одному другому указанному случаю.
- Брекеты обязательны.
Для цикла
[ редактировать ]Синтаксис цикла for в JavaScript следующий:
for (initial; condition; loop statement) {
/*
statements will be executed every time
the for{} loop cycles, while the
condition is satisfied
*/
}
или
for (initial; condition; loop statement(iteration)) // one statement
Для... в цикле
[ редактировать ]Синтаксис JavaScript for ... in loop
заключается в следующем:
for (var property_name in some_object) {
// statements using some_object[property_name];
}
- Перебирает все перечислимые свойства объекта.
- Перебирает все используемые индексы массива, включая все определяемые пользователем свойства объекта массива, если таковые имеются. Таким образом, возможно, лучше использовать традиционный цикл for с числовым индексом при переборе массивов.
- Между различными веб-браузерами существуют различия в отношении того, какие свойства будут отражены в операторе цикла for...in. Теоретически это контролируется внутренним свойством состояния, определенным стандартом ECMAscript и называемым DontEnum, но на практике каждый браузер во время самоанализа возвращает немного отличающийся набор свойств. Полезно проверить заданное свойство, используя
if (some_object.hasOwnProperty(property_name)) { ...
}. Таким образом, добавив метод к прототипу массива с помощьюArray.prototype.newMethod = function() {...
} может вызватьfor ... in
циклы для перебора имени метода.
Пока цикл
[ редактировать ]Синтаксис цикла while в JavaScript следующий:
while (condition) {
statement1;
statement2;
statement3;
...
}
Сделайте... цикл while
[ редактировать ]Синтаксис JavaScript do ... while loop
заключается в следующем:
do {
statement1;
statement2;
statement3;
...
} while (condition);
С
[ редактировать ]Оператор with добавляет все свойства и методы данного объекта в область действия следующего блока, позволяя ссылаться на них, как если бы они были локальными переменными.
with (document) {
const a = getElementById('a');
const b = getElementById('b');
const c = getElementById('c');
};
- Обратите внимание на отсутствие документ. перед каждым Вызов getElementById() .
Семантика аналогична оператору with Паскаля .
Поскольку наличие операторов with снижает производительность программы и, как полагают, снижает ясность кода (поскольку любая данная переменная на самом деле может быть свойством включающей с ), этот оператор не разрешен в строгом режиме .
Этикетки
[ редактировать ]JavaScript поддерживает вложенные метки в большинстве реализаций. Циклы или блоки могут быть помечены для оператора Break, а циклы для continue
. Хотя goto
это зарезервированное слово, [15] goto
не реализован в JavaScript.
loop1: for (let a = 0; a < 10; ++a) {
if (a === 4) break loop1; // Stops after the 4th attempt
console.log('a = ' + a);
loop2: for (let b = 0; b < 10; ++b) {
if (b === 3) continue loop2; // Number 3 is skipped
if (b === 6) continue loop1; // Continues the first loop, 'finished' is not shown
console.log('b = ' + b);
} //end of loop2
console.log('finished');
} //end of loop1
block1: {
console.log('Hello'); // Displays 'Hello'
break block1;
console.log('World'); // Will never get here
}
goto block1; // Parse error.
Функции
[ редактировать ]Функция — это блок со списком параметров (возможно, пустым), которому обычно присваивается имя. Функция может использовать локальные переменные. Если вы выйдете из функции без оператора return, значение неопределенное значение возвращается .
function gcd(number1, number2) {
if (isNaN(number1*number2)) throw TypeError("Non-Numeric arguments not allowed.");
number1 = Math.round(number1);
number2 = Math.round(number2);
let difference = number1 - number2;
if (difference === 0) return number1;
return difference > 0 ? gcd(number2, difference) : gcd(number1, -difference);
}
console.log(gcd(60, 40)); // 20
//In the absence of parentheses following the identifier 'gcd' on the RHS of the assignment below,
//'gcd' returns a reference to the function itself without invoking it.
let mygcd = gcd; // mygcd and gcd reference the same function.
console.log(mygcd(60, 40)); // 20
Функции являются объектами первого класса и могут быть присвоены другим переменным.
Количество аргументов, передаваемых при вызове функции, может не обязательно соответствовать количеству аргументов в определении функции; именованный аргумент в определении, который не имеет соответствующего аргумента в вызове, будет иметь значение undefined (которому можно неявно привести к false). Внутри функции доступ к аргументам также можно получить через объект аргументов ; это обеспечивает доступ ко всем аргументам с использованием индексов (например, arguments[0], arguments[1], ... arguments[n]
), включая те, которые выходят за рамки количества именованных аргументов. (Хотя в списке аргументов есть .length
свойство, оно не является примером Множество ; у него нет таких методов, как .slice() , .sort() и т. д.)
function add7(x, y) {
if (!y) {
y = 7;
}
console.log(x + y + arguments.length);
};
add7(3); // 11
add7(3, 4); // 9
Примитивные значения (число, логическое значение, строка) передаются по значению. Для объектов это ссылка на передаваемый объект.
const obj1 = {a : 1};
const obj2 = {b : 2};
function foo(p) {
p = obj2; // Ignores actual parameter
p.b = arguments[1];
}
foo(obj1, 3); // Does not affect obj1 at all. 3 is additional parameter
console.log(`${obj1.a} ${obj2.b}`); // writes 1 3
Функции могут быть объявлены внутри других функций и иметь доступ к локальным переменным внешней функции. Более того, они реализуют полное замыкание , запоминая локальные переменные внешней функции даже после ее завершения.
let t = "Top";
let bar, baz;
function foo() {
let f = "foo var";
bar = function() { console.log(f) };
baz = function(x) { f = x; };
}
foo();
baz("baz arg");
bar(); // "baz arg" (not "foo var") even though foo() has exited.
console.log(t); // Top
Асинхронный/ожидание
[ редактировать ]Оператор await в JavaScript можно использовать только внутри асинхронной функции или на верхнем уровне модуля . Если параметром является промис , выполнение асинхронной функции возобновится, когда промис будет разрешен (если промис не будет отклонен, в этом случае будет выдана ошибка, которую можно обработать с помощью обычной обработки исключений JavaScript ). Если параметр не является обещанием, сам параметр будет возвращен немедленно. [16]
Многие библиотеки предоставляют объекты-промисы, которые также можно использовать с await, если они соответствуют спецификации собственных промисов JavaScript. Однако промисы из библиотеки jQuery не были совместимы с Promises/A+ до версии jQuery 3.0. [17]
Вот пример (измененный из этого [18] статья):
async function createNewDoc() {
let response = await db.post({}); // post a new doc
return db.get(response.id); // find by id
}
async function main() {
try {
let doc = await createNewDoc();
console.log(doc);
} catch (err) {
console.log(err);
}
}
main();
Объекты
[ редактировать ]Для удобства типы обычно подразделяются на примитивы и объекты . Объекты — это сущности, которые имеют идентичность (они равны только самим себе) и которые сопоставляют имена свойств значениям («слоты» в терминологии программирования на основе прототипов ). Объекты можно рассматривать как ассоциативные массивы или хэши, и они часто реализуются с использованием этих структур данных. Однако у объектов есть дополнительные возможности, такие как цепочка прототипов , которых нет у обычных ассоциативных массивов.
В JavaScript есть несколько типов встроенных объектов, а именно: Array
, Boolean
, Date
, Function
, Math
, Number
, Object
, RegExp
и String
. Другие объекты являются «хост-объектами», определяемыми не языком, а средой выполнения. Например, в браузере типичные хост-объекты принадлежат DOM (окно, форма, ссылки и т. д.).
Создание объектов
[ редактировать ]Объекты можно создавать с помощью конструктора или литерала объекта. Конструктор может использовать либо встроенную функцию объекта, либо пользовательскую функцию. По соглашению функциям-конструкторам присваиваются имена, начинающиеся с заглавной буквы:
// Constructor
const anObject = new Object();
// Object literal
const objectA = {};
const objectA2 = {}; // A != A2, {}s create new objects as copies.
const objectB = {index1: 'value 1', index2: 'value 2'};
// Custom constructor (see below)
Литералы объектов и литералы массивов позволяют легко создавать гибкие структуры данных:
const myStructure = {
name: {
first: "Mel",
last: "Smith"
},
age: 33,
hobbies: ["chess", "jogging"]
};
Это основа JSON — простой нотации, использующей для обмена данными синтаксис, подобный JavaScript.
Методы
[ редактировать ]Метод — это просто функция , присвоенная имени свойства объекта. В отличие от многих объектно-ориентированных языков, в объектно-ориентированном JavaScript нет различия между определением функции и определением метода. Скорее, различие возникает во время вызова функции; функцию можно вызвать как метод.
При вызове как метод стандартная локальная переменная это просто автоматически устанавливается на экземпляр объекта слева от " . ". (Есть также позвони и применять методы, которые могут установить это явно — некоторые пакеты, такие как jQuery, делают необычные вещи с этот .)
В приведенном ниже примере Foo используется в качестве конструктора. В конструкторе нет ничего особенного — это просто функция, инициализирующая объект. При использовании с новое ключевое слово, как обычно, это значение устанавливается для вновь созданного пустого объекта.
Обратите внимание, что в приведенном ниже примере Foo просто присваивает значения слотам, некоторые из которых являются функциями. Таким образом, он может назначать разные функции разным экземплярам. В этом примере нет прототипирования.
function px() { return this.prefix + "X"; }
function Foo(yz) {
this.prefix = "a-";
if (yz > 0) {
this.pyz = function() { return this.prefix + "Y"; };
} else {
this.pyz = function() { return this.prefix + "Z"; };
}
this.m1 = px;
return this;
}
const foo1 = new Foo(1);
const foo2 = new Foo(0);
foo2.prefix = "b-";
console.log("foo1/2 " + foo1.pyz() + foo2.pyz());
// foo1/2 a-Y b-Z
foo1.m3 = px; // Assigns the function itself, not its evaluated result, i.e. not px()
const baz = {"prefix": "c-"};
baz.m4 = px; // No need for a constructor to make an object.
console.log("m1/m3/m4 " + foo1.m1() + foo1.m3() + baz.m4());
// m1/m3/m4 a-X a-X c-X
foo1.m2(); // Throws an exception, because foo1.m2 doesn't exist.
Конструкторы
[ редактировать ]Функции конструктора просто присваивают значения слотам вновь созданного объекта. Значения могут быть данными или другими функциями.
Пример: Манипулирование объектом:
function MyObject(attributeA, attributeB) {
this.attributeA = attributeA;
this.attributeB = attributeB;
}
MyObject.staticC = "blue"; // On MyObject Function, not object
console.log(MyObject.staticC); // blue
const object = new MyObject('red', 1000);
console.log(object.attributeA); // red
console.log(object.attributeB); // 1000
console.log(object.staticC); // undefined
object.attributeC = new Date(); // add a new property
delete object.attributeB; // remove a property of object
console.log(object.attributeB); // undefined
прототипа объекта Ссылка на сам конструктор находится в слоте конструктора . Так,
function Foo() {}
// Use of 'new' sets prototype slots (for example,
// x = new Foo() would set x's prototype to Foo.prototype,
// and Foo.prototype has a constructor slot pointing back to Foo).
const x = new Foo();
// The above is almost equivalent to
const y = {};
y.constructor = Foo;
y.constructor();
// Except
x.constructor == y.constructor; // true
x instanceof Foo; // true
y instanceof Foo; // false
// y's prototype is Object.prototype, not
// Foo.prototype, since it was initialised with
// {} instead of new Foo.
// Even though Foo is set to y's constructor slot,
// this is ignored by instanceof - only y's prototype's
// constructor slot is considered.
Функции сами по себе являются объектами, которые можно использовать для создания эффекта, подобного «статическим свойствам» (используя терминологию C++/Java), как показано ниже. (Объект функции также имеет специальный prototype
свойство, как описано в разделе «Наследование» ниже.)
Удаление объектов используется редко, поскольку механизм сценариев будет собирать мусор для объектов, на которые больше нет ссылок.
Наследование
[ редактировать ]JavaScript поддерживает иерархию наследования посредством прототипирования наподобие Self .
В следующем примере Производный класс наследуется от Базовый класс. Когда d создается как Derived , ссылка на базовый экземпляр База копируется в д.база .
Производное не содержит значения для aBaseFunction , поэтому она извлекается из aBaseFunction, когда aBaseFunction Доступ к . Это становится очевидным, если изменить значение base.aBaseFunction , что отражается в значении d.aBaseFunction .
Некоторые реализации позволяют получить доступ к прототипу или установить его явно с помощью Слот __proto__, как показано ниже.
function Base() {
this.anOverride = function() { console.log("Base::anOverride()"); };
this.aBaseFunction = function() { console.log("Base::aBaseFunction()"); };
}
function Derived() {
this.anOverride = function() { console.log("Derived::anOverride()"); };
}
const base = new Base();
Derived.prototype = base; // Must be before new Derived()
Derived.prototype.constructor = Derived; // Required to make `instanceof` work
const d = new Derived(); // Copies Derived.prototype to d instance's hidden prototype slot.
d instanceof Derived; // true
d instanceof Base; // true
base.aBaseFunction = function() { console.log("Base::aNEWBaseFunction()"); };
d.anOverride(); // Derived::anOverride()
d.aBaseFunction(); // Base::aNEWBaseFunction()
console.log(d.aBaseFunction == Derived.prototype.aBaseFunction); // true
console.log(d.__proto__ == base); // true in Mozilla-based implementations and false in many others.
Ниже ясно показано, как ссылки на прототипы копируются при создании экземпляра, но изменения прототипа могут повлиять на все экземпляры, которые на него ссылаются.
function m1() { return "One"; }
function m2() { return "Two"; }
function m3() { return "Three"; }
function Base() {}
Base.prototype.m = m2;
const bar = new Base();
console.log("bar.m " + bar.m()); // bar.m Two
function Top() { this.m = m3; }
const t = new Top();
const foo = new Base();
Base.prototype = t;
// No effect on foo, the *reference* to t is copied.
console.log("foo.m " + foo.m()); // foo.m Two
const baz = new Base();
console.log("baz.m " + baz.m()); // baz.m Three
t.m = m1; // Does affect baz, and any other derived classes.
console.log("baz.m1 " + baz.m()); // baz.m1 One
На практике используется множество вариаций этих тем, и они могут быть как мощными, так и запутанными.
Обработка исключений
[ редактировать ]JavaScript включает в себя try ... catch ... finally
оператор обработки исключений для обработки ошибок во время выполнения.
The try ... catch ... finally
Оператор перехватывает исключения, возникающие в результате ошибки или оператора throw. Его синтаксис следующий:
try {
// Statements in which exceptions might be thrown
} catch(errorValue) {
// Statements that execute in the event of an exception
} finally {
// Statements that execute afterward either way
}
Первоначально выполняются инструкции внутри блока try. Если генерируется исключение, поток управления сценарием немедленно переходит к операторам в блоке catch, при этом исключение доступно в качестве аргумента ошибки. В противном случае блок catch пропускается. Блок улова может throw(errorValue) , если он не хочет обрабатывать конкретную ошибку.
В любом случае операторы в блокеfinally выполняются всегда. Это можно использовать для освобождения ресурсов, хотя память автоматически очищается от мусора.
Предложение catch или предложениеfinally можно опустить. Аргумент catch является обязательным.
Реализация Mozilla позволяет использовать несколько операторов catch в качестве расширения стандарта ECMAScript. Они следуют синтаксису, аналогичному используемому в Java :
try { statement; }
catch (e if e == "InvalidNameException") { statement; }
catch (e if e == "InvalidIdException") { statement; }
catch (e if e == "InvalidEmailException") { statement; }
catch (e) { statement; }
В браузере функция Событие onerror чаще используется для перехвата исключений.
onerror = function (errorValue, url, lineNr) {...; return true;};
Собственные функции и методы
[ редактировать ]
оценка (выражение)
[ редактировать ]Оценивает первый параметр как выражение, которое может включать операторы присваивания. Выражение может ссылаться на переменные, локальные для функций. Однако, eval
представляет серьезную угрозу безопасности, поскольку позволяет злоумышленнику выполнять произвольный код, поэтому его использование не рекомендуется. [20]
> (function foo() {
... var x = 7;
... console.log("val " + eval("x + 2"));
... })();
val 9
undefined
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Спецификация JavaScript 1.1
- ^ «Глава 1. Базовый JavaScript» . говорящий js.com . Проверено 22 сентября 2020 г.
- ^ Фланаган, Дэвид (2006). JavaScript: полное руководство . п. 16 . ISBN 978-0-596-10199-2 .
Пропуск точек с запятой не является хорошей практикой программирования; вам следует выработать привычку вставлять их.
- ^ «Хранение необходимой информации — Переменные — Изучение веб-разработки | MDN» . http://developer.mozilla.org . 9 мая 2023 г. Проверено 23 июня 2023 г.
- ^ «Значения, переменные и литералы — MDC» . Сеть разработчиков Mozilla. 16 сентября 2010 года. Архивировано из оригинала 29 июня 2011 года . Проверено 1 февраля 2020 г.
- ^ «Подъем JavaScript» . W3Школы .
В JavaScript переменную можно объявить после ее использования. Другими словами; переменную можно использовать до ее объявления.
- ^ « Обзор и подъем JavaScript », Бен Черри , Адекватно хорошо , 8 февраля 2010 г.
- ^ ECMA-262 5e edition разъяснил это поведение с помощью декларативной записи среды и записи среды объекта . При таком формализме глобальный объект — это запись объектной среды глобальной лексической среды ( глобальная область видимости ).
- ^ «Шаблонные литералы» . Веб-документы MDN . Проверено 4 ноября 2023 г.
- ^ «Операторы сравнения — Док-центр MDC» . Мозилла. 5 августа 2010 г. Проверено 5 марта 2011 г.
- ^ «Элементы стиля JavaScript» . Дуглас Крокфорд . Проверено 5 марта 2011 г.
- ^ «Синтаксис распространения (...) — JavaScript | MDN» . http://developer.mozilla.org . 25 сентября 2023 г.
- ^ «параметры покоя» .
- ^ «Спецификация языка ECMAScript 2020» . Экма Интернешнл . Июнь 2020.
- ^ ECMA-262, издание 3, 7.5.3 Будущие зарезервированные слова
- ^ «ожидание — JavaScript (MDN)» . Проверено 2 мая 2017 г.
- ^ «Руководство по обновлению jQuery Core 3.0» . Проверено 2 мая 2017 г.
- ^ «Укрощение асинхронного зверя с помощью ES7» . Проверено 12 ноября 2015 г.
- ^ Foundation, Node.js (30 мая 2017 г.). «Узел v8.0.0 (текущий) — Node.js» . Нод.js.
- ^ "оценка()" . Веб-документы MDN . Проверено 29 января 2020 г.
Дальнейшее чтение
[ редактировать ]- Дэнни Гудман: Библия JavaScript , Wiley, John & Sons, ISBN 0-7645-3342-8 .
- Дэвид Флэнаган, Паула Фергюсон: JavaScript: полное руководство , O'Reilly & Associates, ISBN 0-596-10199-6 .
- Томас А. Пауэлл, Фриц Шнайдер: JavaScript: полный справочник , Компании McGraw-Hill, ISBN 0-07-219127-9 .
- Аксель Раушмайер: «Разговор на JavaScript: подробное руководство для программистов» , 460 страниц, O'Reilly Media, 25 февраля 2014 г., ISBN 978-1449365035 . ( бесплатное онлайн-издание )
- Эмили Вандер Вир: JavaScript для чайников, 4-е издание , Wiley, ISBN 0-7645-7659-3 .
Внешние ссылки
[ редактировать ]- Повторное знакомство с JavaScript - Центр разработчиков Mozilla
- Циклы JavaScript
- Ссылки на стандарты ECMAScript: ECMA-262.
- Интерактивные уроки JavaScript – на основе примеров
- JavaScript на сайте About.com: уроки и объяснения. Архивировано 25 февраля 2017 г. на Wayback Machine.
- Обучение JavaScript
- Основные ссылки Центра разработчиков Mozilla для версий JavaScript 1.5 , 1.4 , 1.3 и 1.2.
- Документация по языку Mozilla JavaScript