stringtranslate.com

JavaScript

JavaScript ( / ˈ ɑː v ə s k r ɪ p t / ), часто сокращенно JS , является языком программирования и базовой технологией Интернета , наряду с HTML и CSS . 99% веб-сайтов используют JavaScript на стороне клиента для поведения веб-страницы . [10]

Веб-браузеры имеют выделенный движок JavaScript , который выполняет клиентский код . Эти движки также используются на некоторых серверах и в различных приложениях . Самая популярная система выполнения для использования вне браузера — Node.js.

JavaScript — это высокоуровневый , часто компилируемый язык just-in-time , который соответствует стандарту ECMAScript . [11] Он имеет динамическую типизацию , прототипную объектную ориентацию и первоклассные функции . Он является многопарадигмальным , поддерживает событийно-управляемый , функциональный и императивный стили программирования . Он имеет интерфейсы прикладного программирования (API) для работы с текстом, датами, регулярными выражениями , стандартными структурами данных и объектной моделью документа (DOM).

Стандарт ECMAScript не включает в себя никаких входов/выходов (I/O), таких как сетевые , хранилища или графические возможности. На практике веб-браузер или другая система выполнения предоставляет API JavaScript для ввода/вывода.

Хотя Java и JavaScript похожи по названию, синтаксису и соответствующим стандартным библиотекам , эти два языка различны и существенно различаются по своей структуре.

История

Создание в Netscape

Первый популярный веб-браузер с графическим пользовательским интерфейсом , Mosaic , был выпущен в 1993 году. Доступный для нетехнических людей, он сыграл важную роль в быстром росте ранней Всемирной паутины . [12] Затем ведущие разработчики Mosaic основали корпорацию Netscape , которая выпустила более совершенный браузер, Netscape Navigator , в 1994 году. Он быстро стал наиболее используемым. [13]

В эти годы становления Интернета веб-страницы могли быть только статичными, не имея возможности динамического поведения после загрузки страницы в браузере. На процветающей сцене веб-разработки было желание устранить это ограничение, поэтому в 1995 году Netscape решила добавить язык программирования в Navigator. Они преследовали два пути достижения этого: сотрудничество с Sun Microsystems для внедрения языка Java , а также найм Брендана Эйха для внедрения языка Scheme . [6]

Целью был «язык для масс», [14] «чтобы помочь непрограммистам создавать динамичные, интерактивные веб-сайты ». [15] Руководство Netscape вскоре решило, что лучшим вариантом для Эйха будет разработка нового языка с синтаксисом, похожим на Java и менее похожим на Scheme или другие существующие языки сценариев . [5] [6] Хотя новый язык и его реализация интерпретатора назывались LiveScript, когда впервые были отправлены как часть бета-версии Navigator в сентябре 1995 года, название было изменено на JavaScript для официального релиза в декабре. [6] [1] [16] [17]

Выбор имени JavaScript вызвал путаницу, подразумевая, что оно напрямую связано с Java. В то время начался бум доткомов , и Java был популярным новым языком, поэтому Эйх посчитал имя JavaScript маркетинговым ходом Netscape. [14]

Принятие Microsoft

Microsoft дебютировала с Internet Explorer в 1995 году, что привело к войне браузеров с Netscape. На фронте JavaScript Microsoft создала свой собственный интерпретатор под названием JScript . [18]

Microsoft впервые выпустила JScript в 1996 году, вместе с первоначальной поддержкой CSS и расширений HTML . Каждая из этих реализаций заметно отличалась от своих аналогов в Netscape Navigator . [19] [20] Эти различия затрудняли разработчикам работу их веб-сайтов в обоих браузерах, что привело к широкому использованию логотипов «лучше всего просматривать в Netscape» и «лучше всего просматривать в Internet Explorer» в течение нескольких лет. [19] [21]

Рост популярности JScript

Брендан Эйх позже сказал об этом периоде: «Это все еще своего рода язык- помощник . Он считается медленным или раздражающим. Люди делают всплывающие окна или прокручивают сообщения в старой строке состояния внизу вашего старого браузера ». [14]

В ноябре 1996 года Netscape представила JavaScript в Ecma International в качестве отправной точки для стандартной спецификации, которой могли бы соответствовать все поставщики браузеров. Это привело к официальному выпуску первой спецификации языка ECMAScript в июне 1997 года.

Процесс стандартизации продолжался несколько лет, с выпуском ECMAScript 2 в июне 1998 года и ECMAScript 3 в декабре 1999 года. Работа над ECMAScript 4 началась в 2000 году. [18]

Однако усилия по полной стандартизации языка были подорваны тем, что Microsoft заняла все более доминирующее положение на рынке браузеров. К началу 2000-х годов доля рынка Internet Explorer достигла 95%. [22] Это означало, что JScript стал фактическим стандартом для клиентских скриптов в Интернете.

Microsoft изначально участвовала в процессе стандартизации и реализовала некоторые предложения в своем языке JScript, но в конечном итоге прекратила сотрудничество в работе над ECMA. Таким образом, ECMAScript 4 был законсервирован.

Рост и стандартизация

В период доминирования Internet Explorer в начале 2000-х годов клиентские скрипты находились в состоянии застоя. Это начало меняться в 2004 году, когда преемник Netscape, Mozilla , выпустил браузер Firefox . Firefox был хорошо принят многими, отобрав значительную долю рынка у Internet Explorer. [23]

В 2005 году Mozilla присоединилась к ECMA International, и началась работа над стандартом ECMAScript для XML (E4X). Это привело к тому, что Mozilla начала работать совместно с Macromedia (позже приобретенным Adobe Systems ), которые реализовывали E4X в своем языке ActionScript 3, который был основан на проекте ECMAScript 4. Целью стала стандартизация ActionScript 3 как нового ECMAScript 4. С этой целью Adobe Systems выпустила реализацию Tamarin как проект с открытым исходным кодом . Однако Tamarin и ActionScript 3 слишком отличались от устоявшихся клиентских сценариев, и без сотрудничества с Microsoft ECMAScript 4 так и не был реализован.

Тем временем, очень важные события происходили в сообществах с открытым исходным кодом, не связанных с работой ECMA. В 2005 году Джесси Джеймс Гарретт выпустил white paper, в котором он ввел термин Ajax и описал набор технологий, основой которых был JavaScript, для создания веб-приложений , в которых данные могут загружаться в фоновом режиме, избегая необходимости полной перезагрузки страницы. Это вызвало период возрождения JavaScript, возглавляемый библиотеками с открытым исходным кодом и сообществами, которые сформировались вокруг них. Было создано много новых библиотек, включая jQuery , Prototype , Dojo Toolkit и MooTools .

Google дебютировал со своим браузером Chrome в 2008 году с движком JavaScript V8 , который был быстрее, чем у конкурентов. [24] [25] Ключевым нововведением была компиляция «на лету» (JIT), [26] поэтому другим поставщикам браузеров пришлось переделать свои движки для JIT. [27]

В июле 2008 года эти разрозненные стороны собрались на конференции в Осло . Это привело к окончательному соглашению в начале 2009 года объединить всю соответствующую работу и продвигать язык вперед. Результатом стал стандарт ECMAScript 5, выпущенный в декабре 2009 года.

Достижение зрелости

Амбициозная работа над языком продолжалась несколько лет, завершившись обширным набором дополнений и улучшений, которые были формализованы с публикацией ECMAScript 6 в 2015 году. [28]

Создание Node.js в 2009 году Райаном Далем вызвало значительный рост использования JavaScript за пределами веб-браузеров. Node объединяет движок V8 , цикл событий и API ввода-вывода , тем самым предоставляя автономную систему выполнения JavaScript. [29] [30] По состоянию на 2018 год Node использовали миллионы разработчиков, [31] а npm имел наибольшее количество модулей среди всех менеджеров пакетов в мире. [32]

В настоящее время проект спецификации ECMAScript открыто поддерживается на GitHub , [33] а редакции выпускаются посредством регулярных ежегодных снимков. [33] Потенциальные изменения языка проверяются посредством комплексного процесса предложений. [34] [35] Теперь вместо номеров редакций разработчики проверяют статус будущих функций по отдельности. [33]

Текущая экосистема JavaScript имеет множество библиотек и фреймворков , устоявшиеся практики программирования и значительное использование JavaScript за пределами веб-браузеров. [17] Кроме того, с ростом одностраничных приложений и других веб-сайтов, использующих JavaScript, было создано несколько транспиляторов для облегчения процесса разработки. [36]

Торговая марка

«JavaScript» является торговой маркой Oracle Corporation в США. [37] [38] Торговая марка была первоначально выдана Sun Microsystems 6 мая 1997 года и была передана Oracle, когда они приобрели Sun в 2009 году. [39]

Использование веб-сайта на стороне клиента

JavaScript является доминирующим клиентским языком сценариев в Интернете, и 99% всех веб-сайтов используют его для этой цели. [10] Скрипты встраиваются или включаются в HTML- документы и взаимодействуют с DOM .

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

Примеры поведения по сценарию

Библиотеки и фреймворки

Более 80% веб-сайтов используют сторонние библиотеки JavaScript или веб-фреймворки как часть своих клиентских скриптов. [40]

jQuery на сегодняшний день является наиболее используемым. [40] Другие известные из них включают Angular , Bootstrap , Lodash , Modernizr , React , Underscore и Vue . [40] Несколько вариантов могут использоваться совместно, например jQuery и Bootstrap. [41]

Однако термин «Vanilla JS» был придуман для веб-сайтов, которые вообще не используют никаких библиотек или фреймворков, а вместо этого полностью полагаются на стандартную функциональность JavaScript. [42]

Другое использование

Использование JavaScript вышло за рамки его веб-браузерных корней. Движки JavaScript теперь встроены в ряд других программных систем, как для серверных веб-развертываний, так и для небраузерных приложений .

Первоначальные попытки продвижения использования JavaScript на стороне сервера были предприняты Netscape Enterprise Server и Microsoft Internet Information Services , [ 43] [44], но они были небольшими нишами. [45] Использование на стороне сервера в конечном итоге начало расти в конце 2000-х годов с созданием Node.js и других подходов . [45]

Electron , Cordova , React Native и другие фреймворки приложений использовались для создания множества приложений с поведением, реализованным в JavaScript. Другие небраузерные приложения включают поддержку Adobe Acrobat для создания сценариев PDF- документов [46] и расширения GNOME Shell, написанные на JavaScript. [47]

JavaScript использовался в некоторых встроенных системах , обычно с использованием Node.js. [48] [49] [50]

Исполнение

JavaScript-движок

Движок JavaScript — это программный компонент , который выполняет код JavaScript . Первые движки JavaScript были просто интерпретаторами , но все соответствующие современные движки используют компиляцию «на лету» для повышения производительности. [51]

JavaScript-движки обычно разрабатываются поставщиками веб-браузеров , и у каждого крупного браузера есть один. В браузере JavaScript-движок работает совместно с рендеринг-движком через Document Object Model и привязки Web IDL . [52] Однако использование JavaScript-движков не ограничивается браузерами; например, V8-движок является основным компонентом системы выполнения Node.js. [53 ]

Поскольку ECMAScript является стандартизированной спецификацией JavaScript, движок ECMAScript — это еще одно название для этих реализаций . С появлением WebAssembly некоторые движки также могут выполнять этот код в той же песочнице , что и обычный код JavaScript. [54] [53]

Система выполнения

Механизм JavaScript должен быть встроен в систему выполнения (например, веб-браузер или автономную систему), чтобы скрипты могли взаимодействовать с более широкой средой. Система выполнения включает необходимые API для операций ввода/вывода , таких как сетевые операции , хранение и графика , а также обеспечивает возможность импорта скриптов.

JavaScript — однопоточный язык . Среда выполнения обрабатывает сообщения из очереди по одному и вызывает функцию, связанную с каждым новым сообщением, создавая кадр стека вызовов с аргументами функции и локальными переменными . Стек вызовов уменьшается и увеличивается в зависимости от потребностей функции. Когда стек вызовов пуст после завершения функции, JavaScript переходит к следующему сообщению в очереди. Это называется циклом событий , описываемым как «выполнение до завершения», поскольку каждое сообщение полностью обрабатывается до того, как будет рассмотрено следующее сообщение. Однако модель параллелизма языка описывает цикл событий как неблокирующий : программный ввод-вывод выполняется с использованием событий и функций обратного вызова . Это означает, например, что JavaScript может обрабатывать щелчок мыши, ожидая, пока запрос к базе данных вернет информацию. [55]

Наиболее известными автономными средами выполнения являются Node.js , Deno и Bun .

Функции

Следующие функции являются общими для всех соответствующих реализаций ECMAScript, если явно не указано иное.

Императивный и структурированный

JavaScript поддерживает большую часть структурированного синтаксиса программирования из C (например, ifоператоры, whileциклы, switchоператоры, do whileциклы и т. д.). Одним частичным исключением является область действия : изначально в JavaScript была только область действия функций с var; область действия блоков была добавлена ​​в ECMAScript 2015 с ключевыми словами letи const. Как и в C, JavaScript делает различие между выражениями и операторами . Одним синтаксическим отличием от C является автоматическая вставка точки с запятой , которая позволяет опускать точки с запятой (которые завершают операторы). [56]

Слабо типизированный

JavaScript слабо типизирован , что означает, что определенные типы неявно приводятся в зависимости от используемой операции. [57]

Значения преобразуются в строки следующим образом: [57]

Значения преобразуются в числа путем преобразования в строки, а затем преобразования строк в числа. Эти процессы можно модифицировать, определив функции toStringи valueOfв прототипе для преобразования строк и чисел соответственно.

JavaScript подвергся критике за способ реализации этих преобразований, поскольку сложность правил можно ошибочно принять за непоследовательность. [58] [57] Например, при добавлении числа к строке число будет преобразовано в строку перед выполнением конкатенации, но при вычитании числа из строки строка преобразуется в число перед выполнением вычитания.

Часто также упоминается, что {} + []результатом является 0(число). Это вводит в заблуждение: {}интерпретируется как пустой блок кода вместо пустого объекта, а пустой массив преобразуется в число оставшимся унарным +оператором. Если выражение заключено в скобки - ({} + [])- фигурные скобки интерпретируются как пустой объект, и результат выражения такой, "[object Object]"как и ожидалось. [57]

Динамичный

Печатание

JavaScript динамически типизирован, как и большинство других языков сценариев . Тип связан со значением, а не с выражением. Например, переменная , изначально связанная с числом, может быть переназначена в строку . [59] JavaScript поддерживает различные способы проверки типа объектов, включая утиную типизацию . [60]

Оценка во время выполнения

JavaScript включает evalфункцию, которая может выполнять операторы, представленные в виде строк, во время выполнения.

Объектно-ориентированный (на основе прототипов)

Прототипное наследование в JavaScript описано Дугласом Крокфордом следующим образом:

Вы создаете прототипы объектов, а затем... создаете новые экземпляры. Объекты изменяемы в JavaScript, поэтому мы можем дополнять новые экземпляры, давая им новые поля и методы. Затем они могут выступать в качестве прототипов для еще более новых объектов. Нам не нужны классы, чтобы создавать множество похожих объектов... Объекты наследуются от объектов. Что может быть более объектно-ориентированным, чем это? [61]

В JavaScript объект — это ассоциативный массив , дополненный прототипом (см. ниже); каждый ключ предоставляет имя для свойства объекта , и существует два синтаксических способа указать такое имя: точечная нотация ( obj.x = 10) и скобочная нотация ( obj['x'] = 10). Свойство может быть добавлено, перепривязано или удалено во время выполнения. Большинство свойств объекта (и любое свойство, принадлежащее цепочке наследования прототипа объекта) можно перечислить с помощью for...inцикла.

Прототипы

JavaScript использует прототипы там, где многие другие объектно-ориентированные языки используют классы для наследования . [62] В JavaScript можно имитировать многие функции, основанные на классах, с помощью прототипов. [63]

Функции как конструкторы объектов

Функции также являются конструкторами объектов, наряду со своей типичной ролью. Префикс вызова функции new создаст экземпляр прототипа, наследуя свойства и методы от конструктора (включая свойства от Objectпрототипа). [64] ECMAScript 5 предлагает Object.createметод, позволяющий явно создавать экземпляр без автоматического наследования от Objectпрототипа (старые среды могут назначать прототип null). [65] Свойство конструктора prototypeопределяет объект, используемый для внутреннего прототипа нового объекта. Новые методы можно добавлять, изменяя прототип функции, используемой в качестве конструктора. Встроенные конструкторы JavaScript, такие как Arrayили Object, также имеют прототипы, которые можно изменять. Хотя можно изменять прототип Object, это обычно считается плохой практикой, поскольку большинство объектов в JavaScript наследуют методы и свойства от Objectпрототипа, и они могут не ожидать, что прототип будет изменен. [66]

Функции как методы

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

Функциональный

Функции JavaScript являются первоклассными ; функция считается объектом. [67] Таким образом, функция может иметь свойства и методы, такие как .call()и .bind(). [68]

Лексическое закрытие

Вложенная функция — это функция, определенная внутри другой функции. Она создается каждый раз при вызове внешней функции.

Кроме того, каждая вложенная функция образует лексическое замыкание : лексическая область действия внешней функции (включая любую константу, локальную переменную или значение аргумента) становится частью внутреннего состояния каждого объекта внутренней функции, даже после завершения выполнения внешней функции. [69]

Анонимная функция

JavaScript также поддерживает анонимные функции .

Делегативный

JavaScript поддерживает неявное и явное делегирование .

Функции как роли (черты и миксины)

JavaScript изначально поддерживает различные реализации шаблонов ролей [70] на основе функций , такие как Traits [71] [72] и Mixins . [73] Такая функция определяет дополнительное поведение по крайней мере одним методом, привязанным к thisключевому слову в ее functionтеле. Затем роль должна быть делегирована явно через callили applyобъектам, которым необходимо предоставить дополнительное поведение, которое не разделяется через цепочку прототипов.

Композиция и наследование объектов

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

Разнообразный

Нумерация с нуля

JavaScript — язык с нулевым индексом .

Вариативные функции

В функцию можно передать неограниченное количество параметров. Функция может получить к ним доступ через формальные параметры , а также через локальный argumentsобъект. С помощью метода можно также создавать функции с переменным числом аргументовbind .

Массивы и литералы объектов

Как и во многих скриптовых языках, массивы и объекты ( ассоциативные массивы в других языках) могут быть созданы с помощью краткого сокращенного синтаксиса. Фактически, эти литералы формируют основу формата данных JSON .

Регулярные выражения

Подобно Perl , JavaScript также поддерживает регулярные выражения , которые обеспечивают краткий и мощный синтаксис для обработки текста, который является более сложным, чем встроенные строковые функции. [74]

Обещания и асинхронность/ожидание

JavaScript поддерживает обещания и Async/await для обработки асинхронных операций. [ необходима цитата ]

Обещания

Встроенный объект Promise предоставляет функциональность для обработки обещаний и связывания обработчиков с конечным результатом асинхронного действия. Недавно в спецификации JavaScript были представлены методы комбинаторов, которые позволяют разработчикам объединять несколько обещаний JavaScript и выполнять операции на основе различных сценариев. Представлены следующие методы: Promise.race, Promise.all, Promise.allSettled и Promise.any.

Асинхронный/ожидание

Async/await позволяет структурировать асинхронную, неблокирующую функцию способом, аналогичным обычной синхронной функции. Асинхронный, неблокирующий код может быть написан с минимальными накладными расходами, структурированным аналогично традиционному синхронному, блокирующему коду.

Расширения, специфичные для поставщика

Исторически некоторые движки JavaScript поддерживали следующие нестандартные функции:

Синтаксис

Простые примеры

Переменные в JavaScript могут быть определены с использованием ключевых слов var, [76] let[77] или const[78] . Переменные, определенные без ключевых слов, будут определены в глобальной области видимости.

// Объявляет переменную функциональной области действия с именем `x` и неявно присваивает ей // специальное значение `undefined`. Переменные без значения автоматически // устанавливаются в undefined. // var обычно считается плохой практикой, и let и const обычно предпочтительнее. var x ; // Переменные можно вручную установить в `undefined`, например, так: let x2 = undefined ;   // Объявляет переменную с областью действия блока с именем `y` и неявно устанавливает ее в // `undefined`. Ключевое слово `let` было введено в ECMAScript 2015. let y ; // Объявляет блочную, непереназначаемую переменную с именем `z` и устанавливает ее в // строковый литерал. Ключевое слово `const` также было введено в ECMAScript 2015, // и должно быть явно назначено.// Ключевое слово `const` означает константу, поэтому переменную нельзя переназначить , // так как ее значение `constant`. const z = "это значение нельзя переназначить!" ;   // Объявляет глобальную переменную и присваивает ей значение 3. Обычно это считается // плохой практикой и не будет работать, если включен строгий режим. t = 3 ;  // Объявляет переменную с именем `myNumber` и присваивает ей числовой литерал (значение // `2`). let myNumber = 2 ;   // Переназначает `myNumber`, устанавливая его в строковый литерал (значение `"foo"`). // JavaScript — язык с динамической типизацией, поэтому это допустимо. myNumber = "foo" ;  

Обратите внимание на комментарии в приведенных выше примерах, все из которых предваряются двумя косыми чертами .

В JavaScript нет встроенной функциональности ввода/вывода , вместо этого она предоставляется средой выполнения. Спецификация ECMAScript в редакции 5.1 упоминает, что «в этой спецификации нет положений для ввода внешних данных или вывода вычисленных результатов». [79] Однако большинство сред выполнения имеют consoleобъект, который можно использовать для печати вывода. [80] Вот минималистская программа «Hello, World!» на JavaScript в среде выполнения с объектом console:

console.log ( "Привет, мир! " ) ;

В HTML-документах для вывода требуется такая программа:

// Текстовые узлы можно создавать с помощью метода "write". // Это не приветствуется, так как может привести к перезаписи документа, если он полностью загружен. document . write ( 'foo' );// Элементы тоже можно создавать. Сначала их нужно создать в DOM. const myElem = document . createElement ( 'span' );   // Также можно задать такие атрибуты, как классы и идентификатор myElem . classList . add ( 'foo' ); myElem . id = 'bar' ;  // После установки этого тег будет выглядеть так: `<span class="foo" id="bar" data-attr="baz"></span>` myElem . setAttribute ( 'data-attr' , 'baz' ); // Что также можно записать как `myElem.dataset.attr = 'baz'`  // Наконец, добавляем его как дочерний элемент к <body> в HTML- документе . body . appendChild ( myElem );// Элементы могут быть императивно захвачены с помощью querySelector для одного элемента или querySelectorAll для нескольких элементов, которые могут быть зациклены с помощью forEach document . querySelector ( '.class' ); // Выбирает первый элемент с классом "class" document . querySelector ( '#id' ); // Выбирает первый элемент с `id` из "id" document . querySelector ( '[data-other]' ); // Выбирает первый элемент с атрибутом "data-other" document . querySelectorAll ( '.multiple' ); // Возвращает похожий на массив NodeList всех элементов с классом "multiple"    

Простая рекурсивная функция для вычисления факториала натурального числа :

function factorial ( n ) { // Проверка аргумента на легитимность. Факториал определен для положительных целых чисел. if ( isNaN ( n )) { console . error ( "Нечисловой аргумент не допускается." ); return NaN ; // Специальное значение: не число } if ( n === 0 ) return 1 ; // 0! = 1 if ( n < 0 ) return undefined ; // Факториал отрицательных чисел не определен. if ( n % 1 ) { console . warn ( ` ${ n } будет округлен до ближайшего целого числа. Для нецелых чисел рассмотрите возможность использования гамма-функции.` ); n = Math . round ( n ); } // Вышеуказанные проверки не нужно повторять в рекурсии, поэтому фактическая рекурсивная часть определяется отдельно ниже.                                     // Следующая строка — это выражение функции для рекурсивного вычисления факториала. Оно использует синтаксис стрелок, введенный в ES6. const recursivelyCompute = a => a > 1 ? a * recursivelyCompute ( a - 1 ) : 1 ; // Обратите внимание на использование тернарного оператора `?`. return recursivelyCompute ( n ); }                   факториал ( 3 ); // Возвращает 6 

Анонимная функция ( или лямбда):

константный счетчик = функция () { пусть счетчик = 0 ; возврат функции () { возврат ++ счетчик ; } };              const x = counter (); x (); // Возвращает 1 x (); // Возвращает 2 x (); // Возвращает 3      

Этот пример показывает, что в JavaScript замыкания функций захватывают свои нелокальные переменные по ссылке.

Стрелочные функции впервые были введены в 6-м издании - ECMAScript 2015. Они сокращают синтаксис для написания функций в JavaScript. Стрелочные функции анонимны, поэтому для ссылки на них, чтобы вызвать их после создания, необходима переменная, если только они не заключены в скобки и не выполняются немедленно.

Пример стрелочной функции:

// Стрелочные функции позволяют нам опустить ключевое слово `function`. // Здесь `long_example` указывает на анонимное значение функции. const long_example = ( input1 , input2 ) => { console . log ( "Hello, World!" ); const output = input1 + input2 ;              возврат вывода ; }; // Если скобок нет, стрелочная функция просто возвращает выражение // Вот оно (input1 + input2) const short_example = ( input1 , input2 ) => input1 + input2 ;        long_example ( 2 , 3 ); // Печатает "Hello, World!" и возвращает 5 short_example ( 2 , 5 ); // Возвращает 7    // Если стрелочная функция имеет только один параметр, скобки можно убрать. const no_parentheses = input => input + 2 ;       без_скоб ( 3 ); // Возвращает 5 // Стрелочная функция, как и определения других функций, может быть выполнена в том же операторе, в котором она была создана. // Это полезно при написании библиотек, чтобы избежать заполнения глобальной области видимости, а также для замыканий. let three = (( a , b ) => a + b ) ( 1 , 2 );          const generate_multiplier_function = a => ( b => isNaN ( b ) || ! b ? a : a *= b ); const five_multiples = generate_multiplier_function ( 5 ); // Предоставленный аргумент «задает» выражение и сохраняется в a. five_multiples ( 1 ); // Возвращает 5 five_multiples ( 3 ); // Возвращает 15 five_multiples ( 4 ); // Возвращает 60                    

В JavaScript объекты могут быть созданы как экземпляры класса .

Пример класса объекта:

класс Мяч {   конструктор ( радиус ) { этот . радиус = радиус ; этот . площадь = Математика . ПИ * ( радиус ** 2 ); }               // Классы (и, следовательно , объекты) могут содержать функции, известные как методы show ( ) { console.log ( this.radius ) ; } };    const myBall = new Ball ( 5 ); // Создает новый экземпляр объекта-мяча с радиусом 5 myBall . radius ++ ; // Свойства объекта обычно можно изменять извне myBall . show (); // Использование унаследованной функции "show" регистрирует "6"       

В JavaScript объекты можно создавать непосредственно из функции.

Пример функционирования объекта:

функция Шар ( радиус ) {   const площадь = Математика . ПИ * ( радиус ** 2 ); const obj = { радиус , площадь };                 // Объекты изменяемы, и функции могут быть добавлены как свойства. obj . show = () => console . log ( obj . radius ); return obj ; };       const myBall = Ball ( 5 ); // Создает новый объект мяча с радиусом 5. Ключевое слово "new" не требуется. myBall . radius ++ ; // Свойство экземпляра можно изменить. myBall . show (); // Использование функции "show" регистрирует "6" - новое значение экземпляра.      

Демонстрация вариативной функцииarguments ( является специальной переменной ): [81]

функция сумма () { пусть x = 0 ;       для ( пусть i = 0 ; i < аргументы . длина ; ++ i ) x += аргументы [ i ];            вернуть х ; } сумма ( 1 , 2 ); // Возвращает 3 сумма ( 1 , 2 , 3 ); // Возвращает 6     // Начиная с ES6, используется оператор rest. function sum (... args ) { return args . reduce (( a , b ) => a + b ); }         сумма ( 1 , 2 ); // Возвращает 3 сумма ( 1 , 2 , 3 ); // Возвращает 6     

Немедленно вызываемые выражения функций часто используются для создания замыканий. Замыкания позволяют собирать свойства и методы в пространстве имен и делать некоторые из них закрытыми:

пусть счетчик = ( функция () { пусть i = 0 ; // Частная собственность          return { // Публичные методы get : function () { alert ( i ); }, set : function ( value ) { i = value ; }, increment : function () { alert ( ++ i ); } }; })(); // Модуль                     counter.get ( ); // Возвращает 0 counter.set ( 6 ) ; counter.increment ( ) ; // Возвращает 7 counter.increment ( ); // Возвращает 8   

Объекты -генераторы (в форме функций-генераторов) предоставляют функцию, которую можно вызывать, выходить из нее и повторно входить в нее, сохраняя при этом внутренний контекст (сохранение состояния). [82]

функция * rawCounter () { выход 1 ; выход 2 ; }      function * dynamicCounter () { let count = 0 ; while ( true ) { // В большинстве случаев не рекомендуется использовать циклы while true. yield ++ count ; } }             // Экземпляры const counter1 = rawCounter (); const counter2 = dynamicCounter ();      // Реализация counter1.next (); // {значение: 1 , выполнено: false} counter1.next ( ); // { значение : 2, выполнено: false} counter1.next ( ); // {значение: undefined , выполнено: true}   counter2.next (); // {значение: 1, выполнено: false} counter2.next ( ); // {значение : 2, выполнено : false} counter2.next (); // {значение: 3, выполнено : false} // ... бесконечно   

JavaScript может экспортировать и импортировать из модулей: [83]

Пример экспорта:

/* mymodule.js */ // Эта функция остается закрытой, так как она не экспортируется let sum = ( a , b ) => { return a + b ; }          // Экспорт переменных export let name = 'Alice' ; export let age = 23 ;        // Экспорт именованных функций export function add ( num1 , num2 ) { return num1 + num2 ; }        // Экспорт класса экспорт класса Умножение { конструктор ( num1 , num2 ) { this . num1 = num1 ; this . num2 = num2 ; }              добавить () { вернуть сумму ( this . num1 , this . num2 ); } }     

Пример импорта:

// Импорт одного свойства import { add } from './mymodule.js' ; console . log ( add ( 1 , 2 )); //> 3      // Импорт нескольких свойств import { name , age } from './mymodule.js' ; console . log ( name , age ); //> "Alice", 23       // Импорт всех свойств из модуля import * from './module.js' console.log ( name , age ); // > "Алиса", 23 console.log ( add ( 1 , 2 ) ) ; //> 3    

Более продвинутый пример

В этом примере кода показаны различные функции JavaScript.

/* Находит наименьшее общее кратное (НОК) двух чисел */ function LCMCalculator ( x , y ) { // функция-конструктор if ( isNaN ( x * y )) throw new TypeError ( "Нечисловые аргументы не допускаются." ); const checkInt = function ( x ) { // внутренняя функция if ( x % 1 !== 0 ) throw new TypeError ( x + "не является целым числом" );                           вернуть х ; };   this.a = checkInt ( x ) // точки с запятой ^^^^ необязательны, достаточно новой строки this.b = checkInt ( y ) ; } // Прототипом экземпляров объектов, созданных конструктором, является // свойство "prototype" этого конструктора. LCMCalculator.prototype = { // конструктор литерала объекта : LCMCalculator , // при переназначении прототипа установите свойство конструктора соответствующим образом gcd : function ( ) { // метод , вычисляющий наибольший общий делитель // Алгоритм Евклида : let a = Math.abs ( this.a ) , b = Math.abs ( this.b ) , t ;                          if ( a < b ) { // поменять местами переменные // t = b; b = a; a = t; [ a , b ] = [ b , a ]; // поменять местами с помощью деструктурирующего присваивания (ES6) }              пока ( б !== 0 ) { т = б ; б = а % б ; а = т ; }                 // Нужно вычислить НОД только один раз, поэтому «переопределим» этот метод. // (На самом деле это не переопределение — оно определено в самом экземпляре, // так что this.gcd ссылается на это «переопределение» вместо LCMCalculator.prototype.gcd. // Обратите внимание, что это приводит к неправильному результату, если члены объекта LCMCalculator «a» или «b» впоследствии изменяются.) // Кроме того, 'gcd' === «gcd», this['gcd'] === this.gcd this [ 'gcd' ] = function () { return a ; };            вернуть ; } ,   // Имена свойств объектов могут быть указаны строками, разделенными двойными (") или одинарными (') кавычками. "lcm" : function () { // Имена переменных не конфликтуют со свойствами объектов, например, |lcm| не является |this.lcm|. // не используем |this.a*this.b|, чтобы избежать проблем с точностью FP let lcm = this . a / this . gcd () * this . b ;              // Нужно вычислить lcm только один раз, поэтому «переопределим» этот метод. this . lcm = function () { return lcm ; };        вернуть lcm ; },   // Методы также можно объявлять с использованием синтаксиса ES6 toString () { // Использование как шаблонных литералов ES6, так и оператора (+) для объединения значений return `LCMCalculator: a = ${ this . a } , b = ` + this . b ; } };        // Определяем универсальную функцию вывода ; эта реализация работает только для веб - браузеров function output ( x ) { document.body.appendChild ( document.createTextNode ( x ) ) ; document.body.appendChild ( document.createElement ( ' br ' ) ) ; }    // Примечание: map() и forEach() массива определены в JavaScript 1.6. // Они используются здесь для демонстрации функциональной природы JavaScript. [ [ 25 , 55 ], [ 21 , 56 ], [ 22 , 58 ], [ 28 , 56 ] ]. map ( function ( pair ) { // литерал массива + функция сопоставления return new LCMCalculator ( pair [ 0 ], pair [ 1 ]); }). sort (( a , b ) => a . lcm () - b . lcm ()) // сортировка с помощью этой сравнительной функции; => — сокращенная форма функции, называемая «стрелочной функцией» . forEach ( printResult );                     функция printResult ( obj ) { вывод ( obj + ", gcd = " + obj . gcd () + ", lcm = " + obj . lcm ()); }           

В окне браузера должен отобразиться следующий вывод.

НОККалькулятор: a = 28, b = 56, НОД = 28, НОК = 56 НОККалькулятор: a = 21, b = 56, НОД = 7, НОК = 168 НОККалькулятор: a = 25, b = 55, НОД = 5, НОК = 275 НОККалькулятор: a = 22, b = 58, НОД = 2, НОК = 638

Безопасность

JavaScript и DOM предоставляют авторам-злоумышленникам возможность доставлять скрипты для запуска на клиентском компьютере через Интернет. Авторы браузеров минимизируют этот риск, используя два ограничения. Во-первых, скрипты запускаются в песочнице , в которой они могут выполнять только действия, связанные с Интернетом, а не задачи программирования общего назначения, такие как создание файлов. Во-вторых, скрипты ограничены политикой одного источника : скрипты с одного веб-сайта не имеют доступа к информации, такой как имена пользователей, пароли или файлы cookie, отправленные на другой сайт. Большинство ошибок безопасности, связанных с JavaScript, являются нарушениями либо политики одного источника, либо песочницы.

Существуют подмножества общего JavaScript — ADsafe, Secure ECMAScript (SES) — которые обеспечивают более высокий уровень безопасности, особенно в коде, созданном третьими лицами (например, рекламе). [84] [85] Closure Toolkit — еще один проект для безопасного внедрения и изоляции стороннего JavaScript и HTML. [86]

Политика безопасности контента — это основной метод обеспечения того, чтобы на веб-странице выполнялся только доверенный код.

Межсайтовый скриптинг

Распространенной проблемой безопасности, связанной с JavaScript, является межсайтовый скриптинг (XSS), нарушение политики одного источника . Уязвимости XSS возникают, когда злоумышленник может заставить целевой веб-сайт, например веб-сайт онлайн-банкинга, включить вредоносный скрипт в веб-страницу, представленную жертве. Скрипт в этом примере затем может получить доступ к банковскому приложению с привилегиями жертвы, потенциально раскрывая секретную информацию или переводя деньги без разрешения жертвы. Одним из важных решений уязвимостей XSS является очистка HTML .

Некоторые браузеры включают частичную защиту от отраженных атак XSS, в которых злоумышленник предоставляет URL, включающий вредоносный скрипт. Однако даже пользователи этих браузеров уязвимы для других атак XSS, например, тех, где вредоносный код хранится в базе данных. Только правильная разработка веб-приложений на стороне сервера может полностью предотвратить XSS.

Уязвимости XSS также могут возникать из-за ошибок реализации авторами браузеров. [87]

Подделка межсайтовых запросов

Другая уязвимость кросс-сайта — это подделка кросс-сайтовых запросов (CSRF). При CSRF код на сайте злоумышленника обманывает браузер жертвы, заставляя его выполнять действия, которые пользователь не планировал на целевом сайте (например, перевод денег в банке). Когда целевые сайты полагаются исключительно на файлы cookie для аутентификации запросов, запросы, исходящие из кода на сайте злоумышленника, могут содержать те же действительные учетные данные для входа инициирующего пользователя. В общем, решение CSRF заключается в требовании значения аутентификации в скрытом поле формы, а не только в файлах cookie, для аутентификации любого запроса, который может иметь долгосрочные последствия. Проверка заголовка HTTP Referrer также может помочь.

«JavaScript hijacking» — это тип CSRF-атаки, при которой <script>тег на сайте злоумышленника использует страницу на сайте жертвы, которая возвращает конфиденциальную информацию, такую ​​как JSON или JavaScript. Возможные решения включают:

Неоправданное доверие к клиенту

Разработчики клиент-серверных приложений должны осознавать, что ненадежные клиенты могут находиться под контролем злоумышленников. Автор приложения не может предполагать, что его код JavaScript будет работать так, как задумано (или вообще), поскольку любой секрет, встроенный в код, может быть извлечен определенным противником. Вот некоторые выводы:

Неоправданное доверие к разработчикам

Системы управления пакетами, такие как npm и Bower, популярны среди разработчиков JavaScript. Такие системы позволяют разработчику легко управлять зависимостями своей программы от программных библиотек других разработчиков. Разработчики верят, что сопровождающие библиотеки будут поддерживать их в безопасности и актуальности, но это не всегда так. Из-за этого слепого доверия возникла уязвимость. У используемых библиотек могут быть новые выпуски, которые приводят к появлению ошибок или уязвимостей во всех программах, которые полагаются на библиотеки. И наоборот, библиотека может оставаться неисправленной с известными уязвимостями в свободном доступе. В исследовании, проведенном с использованием выборки из 133 000 веб-сайтов, исследователи обнаружили, что 37% веб-сайтов включали библиотеку по крайней мере с одной известной уязвимостью. [90] «Средняя задержка между самой старой версией библиотеки, используемой на каждом веб-сайте, и самой новой доступной версией этой библиотеки составляет 1177 дней в ALEXA, а разработка некоторых библиотек, которые все еще активно используются, прекратилась много лет назад». [90] Другая возможность заключается в том, что разработчик библиотеки может полностью удалить библиотеку. Это произошло в марте 2016 года, когда Азер Кочулу удалил свой репозиторий из npm. Это привело к поломке десятков тысяч программ и веб-сайтов, зависящих от его библиотек. [91] [92]

Ошибки кодирования браузера и плагина

JavaScript предоставляет интерфейс для широкого спектра возможностей браузера, некоторые из которых могут иметь недостатки, такие как переполнение буфера . Эти недостатки могут позволить злоумышленникам писать скрипты, которые будут запускать любой код, который они пожелают, в системе пользователя. Этот код никоим образом не ограничивается другим приложением JavaScript. Например, эксплойт переполнения буфера может позволить злоумышленнику получить доступ к API операционной системы с привилегиями суперпользователя.

Эти уязвимости затронули основные браузеры, включая Firefox, [93] Internet Explorer, [94] и Safari. [95]

Плагины, такие как видеоплееры, Adobe Flash и широкий спектр элементов управления ActiveX , включенных по умолчанию в Microsoft Internet Explorer, также могут иметь уязвимости, которые можно эксплуатировать через JavaScript (такие уязвимости эксплуатировались в прошлом). [96] [97]

В Windows Vista компания Microsoft попыталась ограничить риски ошибок, таких как переполнение буфера, запустив процесс Internet Explorer с ограниченными привилегиями. [98] Google Chrome аналогичным образом ограничивает свои средства визуализации страниц их собственной « песочницей ».

Ошибки реализации песочницы

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

Неправильное предоставление привилегий JavaScript из Интернета сыграло свою роль в уязвимостях как в Internet Explorer [99], так и в Firefox. [100] В Windows XP Service Pack 2 компания Microsoft понизила привилегии JScript в Internet Explorer. [101]

Microsoft Windows позволяет запускать исходные файлы JavaScript на жестком диске компьютера как программы общего назначения, не изолированные (см.: Windows Script Host ). Это делает JavaScript (как и VBScript ) теоретически жизнеспособным вектором для троянского коня , хотя троянские кони JavaScript на практике встречаются редко. [102] [ неудавшаяся проверка ]

Уязвимости оборудования

В 2015 году в статье исследователей безопасности была описана реализация концепции атаки Rowhammer на основе JavaScript. [103] [104] [105] [106]

В 2017 году была продемонстрирована атака на основе JavaScript через браузер, которая могла обойти ASLR . Она называется «ASLR⊕Cache» или AnC. [107] [108]

В 2018 году в статье, в которой было объявлено об атаках Spectre против спекулятивного выполнения в процессорах Intel и других, была представлена ​​реализация JavaScript. [109]

Инструменты разработки

Важные инструменты развивались вместе с языком.

Связанные технологии

Ява

Распространенное заблуждение заключается в том, что JavaScript напрямую связан с Java . Оба языка действительно имеют синтаксис, подобный C (язык C является их самым непосредственным общим языком-предком). Они также обычно изолированы , и JavaScript был разработан с учетом синтаксиса и стандартной библиотеки Java. В частности, все ключевые слова Java были зарезервированы в оригинальном JavaScript, стандартная библиотека JavaScript следует соглашениям об именовании Java, а JavaScript Mathи Dateобъекты основаны на классах из Java 1.0. [112]

Оба языка впервые появились в 1995 году, но Java был разработан Джеймсом Гослингом из Sun Microsystems, а JavaScript — Бренданом Эйхом из Netscape Communications.

Различия между этими двумя языками более заметны, чем их сходства. Java имеет статическую типизацию , в то время как типизация JavaScript является динамической . Java загружается из скомпилированного байт-кода, тогда как JavaScript загружается как исходный код, понятный человеку. Объекты Java основаны на классах , в то время как JavaScript основаны на прототипах . Наконец, Java не поддерживал функциональное программирование до Java 8, тогда как JavaScript поддерживал его с самого начала, находясь под влиянием Scheme .

JSON

JSON — это формат данных, полученный из JavaScript; отсюда и название JavaScript Object Notation. Это широко используемый формат, поддерживаемый многими другими языками программирования.

Транспилеры

Многие веб-сайты используют много JavaScript, поэтому были созданы транспиляторы для преобразования кода, написанного на других языках, что может помочь в процессе разработки. [36]

TypeScript и CoffeeScript — два известных языка, которые транслируются в JavaScript.

Веб-сборка

WebAssembly — это новый язык с форматом байт-кода, разработанный для дополнения JavaScript, особенно критических для производительности частей скриптов веб-страниц . Все основные движки JavaScript поддерживают WebAssembly, [113] который работает в той же песочнице, что и обычный код JavaScript.

asm.js — это подмножество JavaScript, которое послужило предшественником WebAssembly. [114]

Ссылки

  1. ^ ab "Netscape и Sun анонсируют JavaScript, открытый кроссплатформенный язык сценариев объектов для корпоративных сетей и Интернета" (пресс-релиз). 4 декабря 1995 г. Архивировано из оригинала 16 сентября 2007 г.
  2. ^ "Спецификация языка ECMAScript® 2024". Июнь 2024 г. Получено 30 августа 2024 г.
  3. ^ "Спецификация языка ECMAScript® 2025". 27 марта 2024 г. Получено 17 апреля 2024 г.
  4. ^ "nodejs/node-eps". GitHub . Архивировано из оригинала 29 августа 2020 . Получено 5 июля 2018 .
  5. ^ ab Seibel, Peter (16 сентября 2009 г.). Кодеры на работе: размышления о ремесле программирования. Apress. ISBN 9781430219484. Архивировано из оригинала 24 декабря 2020 г. . Получено 25 декабря 2018 г. . Айх: Первоочередной заботой Netscape было то, чтобы он выглядел как Java.
  6. ^ abcde "Глава 4. Как был создан JavaScript". speakingjs.com . Архивировано из оригинала 27 февраля 2020 г. . Получено 21 ноября 2017 г. .
  7. ^ «Популярность - Брендан Эйх».
  8. ^ "Brendan Eich: An Introduction to JavaScript, JSConf 2010". YouTube . 20 января 2013 г. стр. 22m. Архивировано из оригинала 29 августа 2020 г. Получено 25 ноября 2019 г. Eich: "function", восемь букв, на меня повлиял AWK.
  9. ^ Эйх, Брендан (1998). «Предисловие». В Goodman, Danny (ред.). JavaScript Bible (3-е изд.). John Wiley & Sons . ISBN 0-7645-3188-3. LCCN  97078208. OCLC  38888873. OL  712205M.
  10. ^ ab "Статистика использования JavaScript как клиентского языка программирования на веб-сайтах". W3Techs . Получено 27 февраля 2024 г.
  11. ^ "ECMAScript 2020 Language Specification". Архивировано из оригинала 8 мая 2020 г. Получено 8 мая 2020 г.
  12. ^ "Bloomberg Game Changers: Marc Andreessen". Bloomberg . Bloomberg. 17 марта 2011 г. Архивировано из оригинала 16 мая 2012 г. Получено 7 декабря 2011 г.
  13. ^ Энзер, Ларри (31 августа 2018 г.). «Эволюция веб-браузеров». Monmouth Web Developers . Архивировано из оригинала 31 августа 2018 г. Получено 31 августа 2018 г.
  14. ^ abc Fin JS (17 июня 2016 г.), «Брендан Эйх – генеральный директор Brave», YouTube , получено 7 февраля 2018 г.
  15. ^ "Netscape Communications Corp.", Улучшения браузера. Encyclopaedia Britannica 2006 Ultimate Reference Suite DVD
  16. ^ "TechVision: Innovators of the Net: Brendan Eich and JavaScript". Архивировано из оригинала 8 февраля 2008 г.
  17. ^ ab Han, Sheon (4 марта 2024 г.). «JavaScript управляет миром — возможно, даже буквально». Wired . Получено 21 августа 2024 г. .
  18. ^ ab "Глава 5. Стандартизация: ECMAScript". speakingjs.com . Архивировано из оригинала 1 ноября 2021 г. . Получено 1 ноября 2021 г. .
  19. ^ ab Champeon, Steve (6 апреля 2001 г.). "JavaScript, как мы сюда попали?". oreilly.com . Архивировано из оригинала 19 июля 2016 г. . Получено 16 июля 2016 г. .
  20. ^ "Microsoft Internet Explorer 3.0 Beta Now Available". microsoft.com . Microsoft. 29 мая 1996 г. Архивировано из оригинала 24 ноября 2020 г. Получено 16 июля 2016 г.
  21. ^ Маккракен, Гарри (16 сентября 2010 г.). «Нежелательное возвращение «Лучшего просмотра с помощью Internet Explorer»». technologizer.com . Архивировано из оригинала 23 июня 2018 г. . Получено 16 июля 2016 г. .
  22. ^ Бейкер, Лорен (24 ноября 2004 г.). «Рыночная доля интернет-браузера Mozilla Firefox увеличилась до 7,4%». Search Engine Journal . Архивировано из оригинала 7 мая 2021 г. . Получено 8 мая 2021 г. .
  23. Вебер, Тим (9 мая 2005 г.). «Нападение на софтверного гиганта Microsoft». BBC News . Архивировано из оригинала 25 сентября 2017 г.
  24. ^ "Большой сравнительный тест браузеров: Internet Explorer против Firefox, Opera, Safari и Chrome". PC Games Hardware . Computec Media AG. 3 июля 2009 г. Архивировано из оригинала 2 мая 2012 г. Получено 28 июня 2010 г.
  25. ^ Purdy, Kevin (11 июня 2009 г.). "Lifehacker Speed ​​Tests: Safari 4, Chrome 2". Lifehacker . Архивировано из оригинала 14 апреля 2021 г. . Получено 8 мая 2021 г. .
  26. ^ "TraceMonkey: JavaScript Lightspeed, блог Брендана Эйха". Архивировано из оригинала 4 декабря 2015 г. Получено 22 июля 2020 г.
  27. ^ "Mozilla спрашивает: „Мы уже быстры?“". Wired . Архивировано из оригинала 22 июня 2018 года . Получено 18 января 2019 года .
  28. ^ "ECMAScript 6: Новые возможности: Обзор и сравнение". es6-features.org . Архивировано из оригинала 18 марта 2018 г. Получено 19 марта 2018 г.
  29. ^ Professional Node.js: Создание масштабируемого программного обеспечения на основе JavaScript Архивировано 24.03.2017 в Wayback Machine , John Wiley & Sons, 01.10.2012
  30. ^ Sams Teach Yourself Node.js за 24 часа Архивировано 23.03.2017 в Wayback Machine , Sams Publishing, 05.09.2012
  31. ^ Лоутон, Джордж (19 июля 2018 г.). «Секретная история успеха npm и Node». TheServerSide . Архивировано из оригинала 2 августа 2021 г. . Получено 2 августа 2021 г. .
  32. ^ Браун, Пол (13 января 2017 г.). «State of the Union: npm». Linux.com . Архивировано из оригинала 2 августа 2021 г. . Получено 2 августа 2021 г. .
  33. ^ abc Branscombe, Mary (4 мая 2016 г.). "JavaScript Standard Moves to Annual Release Schedule; Here is What's New for ES16". The New Stack . Архивировано из оригинала 16 января 2021 г. . Получено 15 января 2021 г. .
  34. ^ "The TC39 Process". tc39.es . Ecma International. Архивировано из оригинала 7 февраля 2021 г. Получено 15 января 2021 г.
  35. ^ "Предложения ECMAScript". TC39. Архивировано из оригинала 4 декабря 2020 г. Получено 15 января 2021 г.
  36. ^ ab Ashkenas, Jeremy . "Список языков, компилируемых в JS". GitHub . Архивировано из оригинала 31 января 2020 г. Получено 6 февраля 2020 г.
  37. ^ "US Trademark Serial No. 75026640". uspto.gov . United States Patent and Trademark Office . 6 мая 1997 г. Архивировано из оригинала 13 июля 2021 г. Получено 8 мая 2021 г.
  38. ^ "Юридические уведомления". oracle.com . Корпорация Oracle . Архивировано из оригинала 5 июня 2021 г. . Получено 8 мая 2021 г. .
  39. ^ "Oracle купит Sun за 7,4 млрд долларов". The Economic Times . 21 апреля 2009 г.
  40. ^ abc "Статистика использования библиотек JavaScript для веб-сайтов". W3Techs . Получено 9 апреля 2021 г.
  41. ^ «Использование jQuery с Bootstrap». clouddevs.com . 10 июня 2019 г. . Получено 17 марта 2024 г. .
  42. ^ "Vanilla JS". vanilla-js.com . 16 июня 2020 г. Архивировано из оригинала 16 июня 2020 г. Получено 17 июня 2020 г.
  43. ^ "Server-Side JavaScript Guide". oracle.com . Oracle Corporation . 11 декабря 1998 г. Архивировано из оригинала 11 марта 2021 г. Получено 8 мая 2021 г.
  44. ^ Clinick, Andrew (14 июля 2000 г.). «Введение в JScript .NET». Microsoft Developer Network . Microsoft. Архивировано из оригинала 10 ноября 2017 г. . Получено 10 апреля 2018 г. . [С] момента появления в 1996 г. версии JScript 1.0... мы наблюдаем устойчивый рост использования JScript на сервере, особенно в Active Server Pages (ASP)
  45. ^ ab Mahemoff, Michael (17 декабря 2009 г.). «Server-Side JavaScript, Back with a Vengeance». readwrite.com . Архивировано из оригинала 17 июня 2016 г. . Получено 16 июля 2016 г. .
  46. ^ "JavaScript для Acrobat". adobe.com . 7 августа 2009 г. Архивировано из оригинала 7 августа 2009 г. Получено 18 августа 2009 г.
  47. ^ treitter (2 февраля 2013 г.). «Ответ на вопрос: «Как разработать приложение для GNOME?»». livejournal.com . Архивировано из оригинала 11 февраля 2013 г. . Получено 7 февраля 2013 г. .
  48. ^ "Tessel 2... Используйте все библиотеки Node.JS для создания полезных устройств за считанные минуты с Tessel". tessel.io . Архивировано из оригинала 26 мая 2021 г. . Получено 8 мая 2021 г. .
  49. ^ "Node.js Raspberry Pi GPIO Introduction". w3schools.com . Архивировано из оригинала 13 августа 2021 г. . Получено 3 мая 2020 г. .
  50. ^ "Espruino – JavaScript для микроконтроллеров". espruino.com . Архивировано из оригинала 1 мая 2020 г. . Получено 3 мая 2020 г. .
  51. ^ Looper, Jen (21 сентября 2015 г.). «Руководство по движкам JavaScript для идиотов». Telerik Developer Network. Архивировано из оригинала 8 декабря 2018 г. Получено 8 декабря 2018 г.
  52. ^ "Как работает Blink". Google . Получено 12 марта 2024 г. .
  53. ^ ab "Документация · V8". Google . Получено 3 марта 2024 г. .
  54. ^ Нелатуру, Кирти. «WebAssembly: в чем проблема?». medium.com . Получено 3 марта 2024 г.
  55. ^ "Concurrency model and Event Loop". Mozilla Developer Network . Архивировано из оригинала 5 сентября 2015 г. Получено 28 августа 2015 г.
  56. ^ Фланаган, Дэвид (17 августа 2006 г.). JavaScript: Полное руководство: Полное руководство. "O'Reilly Media, Inc.". стр. 16. ISBN 978-0-596-55447-7. Архивировано из оригинала 1 августа 2020 . Получено 29 марта 2019 .
  57. ^ abcd Королев, Михаил (1 марта 2019 г.). "JavaScript quirks in one image from the Internet". Сообщество DEV . Архивировано из оригинала 28 октября 2019 г. Получено 28 октября 2019 г.
  58. ^ Бернхардт, Гэри (2012). "Wat". Destroy All Software . Архивировано из оригинала 28 октября 2019 года . Получено 28 октября 2019 года .
  59. ^ "Типы и структуры данных JavaScript". MDN . 16 февраля 2017 г. Архивировано из оригинала 14 марта 2017 г. Получено 24 февраля 2017 г.
  60. Фланаган 2006, стр. 176–178.
  61. ^ Крокфорд, Дуглас. "Прототипное наследование в JavaScript". Архивировано из оригинала 13 августа 2013 г. Получено 20 августа 2013 г.
  62. ^ "Наследование и цепочка прототипов". Mozilla Developer Network . Архивировано из оригинала 25 апреля 2013 г. Получено 6 апреля 2013 г.
  63. ^ Герман, Дэвид (2013). Эффективный JavaScript. Addison-Wesley. стр. 83. ISBN 978-0-321-81218-6.
  64. ^ Хавербеке, Марин (2011). Красноречивый JavaScript. Нет крахмального пресса. стр. 95–97. ISBN 978-1-59327-282-1.
  65. ^ Кац, Йехуда (12 августа 2011 г.). «Понимание «прототипов» в JavaScript». Архивировано из оригинала 5 апреля 2013 г. Получено 6 апреля 2013 г.
  66. ^ Герман, Дэвид (2013). Эффективный JavaScript. Addison-Wesley. С. 125–127. ISBN 978-0-321-81218-6.
  67. ^ "Функция – JavaScript". MDN Web Docs . Получено 30 октября 2021 г.
  68. ^ "Свойства объекта функции". Es5.github.com. Архивировано из оригинала 28 января 2013 года . Получено 26 мая 2013 года .
  69. ^ Фланаган 2006, стр. 141.
  70. ^ Многочисленные таланты JavaScript для обобщения подходов ролевого программирования, таких как черты и миксины. Архивировано 05.10.2017 на Wayback Machine , Peterseliger.blogpsot.de, 11 апреля 2014 г.
  71. ^ Черты для JavaScript. Архивировано 24 июля 2014 г. на Wayback Machine , 2010 г.
  72. ^ "Главная | CocktailJS". Cocktailjs.github.io . Архивировано из оригинала 4 февраля 2017 . Получено 24 февраля 2017 .
  73. ^ Кролл, Ангус (31 мая 2011 г.). "Свежий взгляд на JavaScript Mixins". JavaScript, JavaScript… . Архивировано из оригинала 15 апреля 2020 г.
  74. ^ Хавербеке, Марин (2011). Красноречивый JavaScript. Нет крахмального пресса. стр. 139–149. ISBN 978-1-59327-282-1.
  75. ^ "E4X – Архив устаревшего контента". Mozilla Developer Network . Mozilla Foundation. 14 февраля 2014 г. Архивировано из оригинала 24 июля 2014 г. Получено 13 июля 2014 г.
  76. ^ "var – JavaScript". Mozilla Developer Network . Архивировано из оригинала 23 декабря 2012 г. Получено 22 декабря 2012 г.
  77. ^ "let". MDN web docs . Mozilla. Архивировано из оригинала 28 мая 2019 г. Получено 27 июня 2018 г.
  78. ^ "const". MDN web docs . Mozilla. Архивировано из оригинала 28 июня 2018 г. Получено 27 июня 2018 г.
  79. ^ "ECMAScript Language Specification – ECMA-262 Edition 5.1". Ecma International . Архивировано из оригинала 26 ноября 2012 г. Получено 22 декабря 2012 г.
  80. ^ "console". Mozilla Developer Network . Mozilla . Архивировано из оригинала 28 февраля 2013 . Получено 6 апреля 2013 .
  81. ^ "аргументы". Mozilla Developer Network . Mozilla . Архивировано из оригинала 13 апреля 2013 г. . Получено 6 апреля 2013 г. .
  82. ^ "function* - JavaScript | MDN". developer.mozilla.org . Получено 27 сентября 2022 г. .
  83. ^ "Модули JavaScript". MDN Web Docs . Mozilla. Архивировано из оригинала 17 июля 2022 г. Получено 28 июля 2022 г.
  84. ^ "Making JavaScript Safe for Advertising". ADsafe. Архивировано из оригинала 6 июля 2021 г. Получено 8 мая 2021 г.
  85. ^ "Secure ECMA Script (SES)". Архивировано из оригинала 15 мая 2013 года . Получено 26 мая 2013 года .
  86. ^ "Google Caja Project". Google . Архивировано из оригинала 22 января 2021 г. . Получено 9 июля 2021 г. .
  87. ^ "Уязвимость межсайтового скриптинга Mozilla обнаружена и исправлена ​​– MozillaZine Talkback". Mozillazine.org . Архивировано из оригинала 21 июля 2011 г. Получено 24 февраля 2017 г.
  88. ^ Коттелин, Тор (17 июня 2008 г.). «Щелкните правой кнопкой мыши «защиту»? Забудьте об этом». blog.anta.net . Архивировано из оригинала 9 августа 2011 г. . Получено 28 июля 2022 г. .
  89. ^ Rehorik, Jan (29 ноября 2016 г.). «Почему вы никогда не должны помещать конфиденциальные данные в свой JavaScript». Блог ServiceObjects . ServiceObjects. Архивировано из оригинала 3 июня 2019 г. . Получено 3 июня 2019 г. .
  90. ^ ab Lauinger, Tobias; Chaabane, Abdelberi; Arshad, Sajjad; Robertson, William; Wilson, Christo; Kirda, Engin (21 декабря 2016 г.), «Thou Shalt Not Depend on Me: Analysing the Use of Outdated JavaScript Libraries on the Web» (PDF) , Северо-Восточный университет , arXiv : 1811.00918 , doi : 10.14722/ndss.2017.23414, ISBN 978-1-891562-46-4, S2CID  17885720, заархивировано из оригинала (PDF) 29 марта 2017 г. , извлечено 28 июля 2022 г.
  91. ^ Коллинз, Кит (27 марта 2016 г.). «Как один программист сломал интернет, удалив крошечный фрагмент кода». Quartz . Архивировано из оригинала 22 февраля 2017 г. Получено 22 февраля 2017 г.
  92. ^ SC Magazine UK, 11 строк удаленного кода разработчика «ломают интернет». Архивировано 23 февраля 2017 г. на Wayback Machine.
  93. ^ Mozilla Corporation, Переполнение буфера в crypto.signText() Архивировано 04.06.2014 на Wayback Machine
  94. ^ Феста, Пол (19 августа 1998 г.). "Ошибка переполнения буфера в IE". CNET . Архивировано из оригинала 25 декабря 2002 г.
  95. ^ SecurityTracker.com, Переполнение буфера JavaScript в Apple Safari позволяет удаленным пользователям выполнять произвольный код, а ошибка перенаправления HTTP позволяет удаленным пользователям получать доступ к файлам. Архивировано 18 февраля 2010 г. на Wayback Machine.
  96. ^ SecurityFocus, Уязвимость переполнения буфера элемента управления ActiveX Microsoft WebViewFolderIcon. Архивировано 11 октября 2011 г. на Wayback Machine.
  97. Fusion Authority, Macromedia Flash ActiveX Buffer Overflow. Архивировано 13 августа 2011 г. на Wayback Machine.
  98. ^ "Защищенный режим в Vista IE7 – IEBlog". Blogs.msdn.com . 9 февраля 2006 г. Архивировано из оригинала 23 января 2010 г. Получено 24 февраля 2017 г.
  99. ^ US CERT, Заметка об уязвимости VU#713878: Microsoft Internet Explorer некорректно проверяет источник перенаправленного кадра. Архивировано 30 октября 2009 г. на Wayback Machine.
  100. ^ Mozilla Foundation, Mozilla Foundation Security Advisory 2005–41: Повышение привилегий с помощью переопределения свойств DOM. Архивировано 04.06.2014 на Wayback Machine.
  101. ^ Андерсен, Старр (9 августа 2004 г.). «Часть 5: Улучшенная безопасность просмотра». TechNet . Microsoft Docs . Изменения функциональности в Windows XP с пакетом обновления 2 . Получено 20 октября 2021 г. .
  102. ^ Один из примеров редкого троянского коня JavaScript см. в Symantec Corporation, JS.Seeker.K. Архивировано 13 сентября 2011 г. на Wayback Machine.
  103. ^ Грасс, Даниэль; Морис, Клементин; Мангард, Стефан (24 июля 2015 г.). «Rowhammer.js: Удаленная программно-индуцированная атака на сбои в JavaScript». arXiv : 1507.06955 [cs.CR].
  104. ^ Жан-Фарунс, Аликс (30 июля 2015 г.). «Rowhammer.js — самый гениальный хак, который я когда-либо видел». Motherboard . Vice . Архивировано из оригинала 27 января 2018 г. . Получено 26 января 2018 г. .
  105. ^ Гудин, Дэн (4 августа 2015 г.). «Эксплойт DRAM „Bitflipping“ для атаки на ПК: просто добавьте JavaScript». Ars Technica . Архивировано из оригинала 27 января 2018 г. Получено 26 января 2018 г.
  106. ^ Ауэрбах, Дэвид (28 июля 2015 г.). «Уязвимость безопасности Rowhammer: почему новая атака безопасности действительно ужасает». slate.com . Архивировано из оригинала 30 июля 2015 г. Получено 29 июля 2015 г.
  107. ^ AnC Архивировано 16.03.2017 на Wayback Machine VUSec, 2017
  108. ^ Новый JavaScript, разрушающий ASLR, собирается сделать эксплойты drive-by гораздо более опасными. Архивировано 16.03.2017 на Wayback Machine Ars Technica, 2017
  109. ^ Атака Спектра Архивировано 2018-01-03 на Wayback Machine Атака Спектра
  110. ^ "Benchmark.js". benchmarkjs.com . Архивировано из оригинала 19 декабря 2016 . Получено 6 ноября 2016 .
  111. ^ JSBEN.CH. "JSBEN.CH Performance Benchmarking Playground for JavaScript". jsben.ch . Архивировано из оригинала 27 февраля 2021 г. . Получено 13 августа 2021 г. .
  112. ^ Эйх, Брендан (3 апреля 2008 г.). "Популярность". Архивировано из оригинала 3 июля 2011 г. Получено 19 января 2012 г.
  113. ^ "Edge Browser Switches WebAssembly to 'On' -- Visual Studio Magazine". Visual Studio Magazine . Архивировано из оригинала 10 февраля 2018 года . Получено 9 февраля 2018 года .
  114. ^ "часто задаваемые вопросы". asm.js. Архивировано из оригинала 4 июня 2014 года . Получено 13 апреля 2014 года .

Источники

Дальнейшее чтение

Внешние ссылки

Послушайте эту статью ( 48 минут )
Разговорный значок Википедии
Этот аудиофайл был создан на основе редакции этой статьи от 20 августа 2013 года и не отражает последующие правки. (2013-08-20)