Javascript — HELP с JS, PHP, доработка и БАГ


Содержание

Debugging PHP and JavaScript code at the same time

Web applications typically consist of both PHP and JavaScript code: PHP code runs on the server side, while JavaScript runs in the browser. With PhpStorm, you can easily debug the PHP code to inspect what is happening on the server, modify variables and so on. We can also debug the JavaScript running in the browser by starting a JavaScript debugging session from the IDE.

This tutorial provides an overview of how you can debug PHP and JavaScript code simultaneously from within PhpStorm.

Before you start

Before you start debugging, make sure that you have a debugging engine installed and configured properly. PhpStorm supports debugging with two most popular tools: Xdebug and Zend Debugger. These tools cannot be used simultaneously because they block each other. To avo >php.ini file as described in Configuring Xdebug and Configuring Zend Debugger.

To open the active php.ini file in the editor:

In the Settings/Preferences dialog ( Ctrl+Alt+S ), click PHP under Languages & Frameworks .

On the PHP page that opens, click next to the CLI Interpreter field.

In the CLI Interpreters dialog that opens, the Configuration File read-only field shows the path to the active php.ini file. Click Open in Editor .

Next, install PhpStorm debugging bookmarklets or one of the Browser Debugging Extensions, and the JetBrains Chrome extension extension as described in Live Edit in HTML, CSS, and JavaScript.

Listening for incoming debugger connections

In PhpStorm, enable listening to incoming debug connections by either clicking on the toolbar or selecting Run | Start Listening for PHP Debug Connections in the main menu. This will ensure PhpStorm reacts when a debugging session is started and opens the Debug tool window automatically. Before launching the script, make sure that either a breakpoint is set or the Break at first line in PHP scripts option is enabled on the Debug page of the Settings/Preferences dialog Ctrl+Alt+S .

Starting the JavaScript debugger

Depending on your preference or application requirements, you can use the PhpStorm’s built-in webserver to run our application locally, or make use of any other web server running either locally or on a remote machine.

Using the built-in web server

The JavaScript debugger in PhpStorm can be started from the editor or from the Project Tool Window by means of the Debug | context menu command. If the selected file is a PHP file, two entries will be available. It is important to select the first one marked with , which will start the JavaScript debugger.

Once started, we can place breakpoints in JavaScript code and use the JavaScript debugger.

Using an external web server

When using a local web server, such as Apache or Nginx, or when developing on a remote web server, a Vagrant or a Docker machine, we can start the JavaScript debugger using a run/debug configuration.

To create a Run/Debug configuration

Do any of the following:

Select Edit configurations. on the PhpStorm toolbar

Select Run | Edit Configurations. from the main menu.

In the Run/Debug Configurations Dialog dialog that opens, click on the toolbar and add a new JavaScript Debug configuration.

Enter the full URL to the page we want to debug on the web server. Optionally, provide some mappings so PhpStorm can determine where to find local files relative to the remote URL. This is only required when we have a different project structure locally and on the remote server. Note that if you are deploying PHP applications with PhpStorm, mappings will be reused from the deployment configuration.

Once the configuration is created, you can start the JavaScript debugging session from the PhpStorm toolbar:

Starting a PHP debugging session from the browser

We’ll follow the Zero-Configuration Debugging approach. In the browser, we can use PhpStorm debugging bookmarklets or one of the Browser Debugging Extensions to start a PHP debugging session. This will instruct the PHP server to make a connection to PhpStorm and open the debugger. Note that the IDE may initially ask you to provide the necessary path mappings. Once the debugger is attached, we will be able to debug both JavaScript and PHP at the same time. PhpStorm will switch between the debuggers as necessary.

Launching the JavaScript and PHP debugger at the same time

In the previous steps, we started the JavaScript and PHP debugger separately. When using Xdebug, we can pass a XDEBUG_SESSION_START URL parameter to our server to start PHP debugging simultaneously with JavaScript debugging. We can do this using a customized run/debug configuration. Create the run/debug configuration as you’ve done earlier, and make sure to append the XDEBUG_SESSION_START=some-session-name URL parameter, for example, ?XDEBUG_SESSION_START=phpstorm :

Troubleshooting

I cannot place breakpoints in the JavaScript parts of a php file

Currently, setting both PHP and JavaScript breakpoints in one file is not supported. For example, no JavaScript breakpoints can be set in the following code:

Google PageSpeed Insights: «Удалите код JavaScript и CSS, блокирующий отображение верхней части страницы»

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

Это одна из наиболее распространенных проблем, которую я встречаю, анализируя веб-сайты. Решение данной задачи — один из самых сложных моментов при оптимизации скорости загрузки страницы, поскольку требует глубоких технических знаний.

Хочу обратить внимание – каждый сайт индивидуален. И если для одного сайта некоторые решения будут полезны, то для другого могут оказать негативное влияние.

Суть проблемы

Данное предупреждение срабатывает, когда в коде документа между тегами … обнаружены ссылки на внешние файлы javascript и css. И пока они не будут загружены, дальнейший рендеринг страницы не будет выполняться. Таким образом они блокируют вывод контента на странице.

Как удалить JavaScript, препятствующий отображению верхней части страницы

Большинство рекомендаций в Интернете сводятся к тому, чтобы перенести все скрипты в подвал сайта. Однако не стоит слепо выполнять эту рекомендацию — есть большая вероятность того, что функционал сайта будет нарушен:

    Для начала мы должны убедиться, что JavaScript не участвует в процессе отображения страницы. Скрипты небольшого размера размещаем в самом содержимом HTML страницы. Например: Проверяем скрипты на зависимости и очередность загрузки. Если ни того, ни другого не имеется, то добавляем к ним атрибут «async»:
  • Благодаря этому атрибуту такие скрипты будут загружаться асинхронно.

Данную инструкцию нельзя применять к библиотеке JQuery, которая используется в подавляющем большинстве сайтов. Далее рассмотрим правильное решение для JQuery.

Запуск скрипта JS в условии PHP

Добрый день. У меня есть условие на PHP. И нужно если это условие срабатывало то активировалась функция JS

Сама функция JS

Я пытался поместить JS в условие но он все равно не срабатывал.

2 ответа 2

PHP работает на стороне сервера, JS на стороне посетителя и между ними нет ни какой прямой связи. PHP лишь генерирует страницу. все. Единственная примерная возможность решить вашу задачу (не глядя, что сама по себе она неправильная). Гененрировать страницу в соответствии с условием

Т.е. скрипт выводится на страницу, тольков случае выполнения условия.

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

например вот так

Всё ещё ищете ответ? Посмотрите другие вопросы с метками php javascript ajax или задайте свой вопрос.

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2020 Stack Exchange Inc; пользовательское содержимое попадает под действие лицензии cc by-sa 4.0 с указанием ссылки на источник. rev 2020.11.14.35433

Отладка JavaScript в настоящем встроенном отладчике, о котором вы не знали

Дата публикации: 2020-02-19

От автора: console.log может много сказать о приложении, но с его помощью нельзя по-настоящему заниматься отладкой кода. Новый JS дебагер в Firefox поможет вам писать код быстрее и без багов. Статья про принцип работы этого отладчика.

В этом примере мы откроем очень простое приложение, с помощью которого легко делается отладка JavaScript. Само приложение работает на базовых open source JS фреймворках. Откройте его в последней версии Firefox Developer Edition и запустите debugger.html с помощью комбинации клавиш Option + Cmd + S на Mac или Shift + Ctrl + S на Windows. Отладчик разделен на 3 панели: панель со списком файлов, панель кода и панель инструментов.


Панель инструментов разделена на тулбар, выражения для отслеживания, точки останова, стек вызовов и области.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Прекратите использовать console.log

Нам хочется использовать console.log для отладки кода. Просто добавляем вызов в код, чтобы узнать значение переменной, и все, так ведь? Такой подход будет работать, но он громоздкий и долгий. В этом пример мы будем пошагово выполнять приложение с помощью debugger.html для поиска значения переменной.

С помощью debugger.html можно погружаться вглубь код, просто добавив точку останова на строке. Точки останова ставят отладчик на паузу, чтобы вы могли посмотреть код. В этом примере мы добавим точку останова на строку 13 файла app.js.

Теперь добавьте задачу в список. Код остановится на функции addTodo, и мы сможем посмотреть в коде значение поля. Наведите курсор на переменную, чтобы увидеть ее значение и т.д. Так можно посмотреть якоря, апплеты, дочерние элементы и т.д.:

Эту же информацию можно найти на панели Области.

Когда скрипт на паузе, можно пошагово выполнять его строки с помощью тулбара. Кнопки Возобновить/Пауза делают именно то, что написано. Кнопка Перешагнуть выполняет текущую строку кода, Зайти – заходит внутрь функции, Выйти – выполняет текущую функцию до выхода из ее вызова.

Следить за значением переменной моно также с помощью выражений для отслеживания. Просто введите выражение в поле Выражения для отслеживания, и отладчик будет следить за ним во время выполнения кода. В примере выше можно добавить выражения title и to-do, и отладчик разобьет значения, когда они будут доступны. Особенно полезно, когда:

Вы пошагово выполняете код и следите за изменением значения;

Вы отлаживаете один и тот же код много раз и хотите увидеть общие значения;

Вы пытаетесь понять, почему эта чертова кнопка не работает.

С помощью debugger.html также можно проводить отладку приложений React/Redux. Как это работает:

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Перейдите к компоненту, который хотите отладить.

Смотрите схему компонента слева (функции в классе).

Добавьте точки останова в подходящие функции.

Нажмите паузу и следите за свойствами и состояниями компонента.

Стек вызова упрощен, поэтому вы видите код приложения в перемешку с фреймворком.

debugger.html позволяет смотреть запутанный или минифицированый код, который может вызывать ошибки. Особенно полезно при работе с общими фреймворками типа React/Redux. Дебагер знает о компоненте, на котором вы нажали паузу, и покажет упрощенный стек вызова, схему компонента и свойства. Ниже разработчик, Amit Zur объясняет, как он использует отладчик кода в Firefox на JS Kongress:

Если хотите подробно изучить новый debugger.html, зайдите на Mozilla Developer Playground. Мы создали серию уроков, чтобы помочь разработчикам научиться эффективно использовать инструмент для отладки кода.

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

Проект debugger.html был запущен примерно 2 года назад вместе с полным пересмотром Firefox DevTools. Мы хотели перевести DevTools на современные технологии, открыть их разработчикам по всему миру. А так как технология открыта, она может свободно вырасти в то, что маленькая группа в Mozilla и не могла себе представить.

JS – основа любого продвинутого веб-приложения, поэтому мощный отладчик был основной частью набора инструментов. Мы хотели создать что-то быстрое, легкое в использовании, адаптирующееся – способное отлаживать любой новый JS фреймворк. Мы решили использовать популярные веб-технологии, так как хотели работать ближе к сообществу. Этот подход улучшил бы сам отладчик – если бы мы приняли Webpack и начали внутренне использовать билд инструмент и карты исходников, мы бы захотели улучшить сопоставление исходников и горячую перезагрузку.

debugger.html написан на React, Redux и Babel. Компоненты React легкие, тестируемые и легко проектируемые. Для быстрого прототипирования UI и документации общих компонентов мы используем React Storybook. Это упрощает работу с разными JS фреймворкам (типа React). Babel front-end позволяет делать такие вещи, как показывать класс Component и его функции в левом сайдбаре. Мы также можем устанавливать точки останова на функции, и они не сдвинутся, если вы измените код.

Действия Redux – это чистый API для UI. Однако их также можно использовать для создания независимого CLI JS Debugger. В хранилище Redux есть селекторы для запроса текущего состояния отладки. Наши юнит тесты запускают действия Redux и имитируют ответы браузера. Интеграционные тесты приводят браузер в действие с Redux действиями отладчика. Сама функциональная архитектура спроектирована для тестирования.

Мы полагались на сообщество разработчиков Mozilla на каждом шаге. Проект был выложен на GitHub, и наша команда достучалась до разработчиков по всему миру, и они откликнулись. В самом начале для сообщества были критичны автоматические тесты. Тесты проводили регресс и документировали поведение, которое легко можно не доглядеть. Именно поэтому один из первых шагов был – написание юнит тестов для действий Redux и типов Flow для хранилища Redux. Фактически, сообщество обеспечило, что покрытие Flow и Jest помогло убедиться в том, что каждый файл был написан и протестирован.

Как разработчики, мы считаем, что инструменты тем сильнее, чем больше вовлечено разработчиков. Наша основная команда всегда была маленькая (2 человека), но в среднем за неделю было 15 помощников. Сообщество дало нам разные точки зрения, что помогло нам предвидеть сложности и написать функции, о которых мы и не могли мечтать. Сейчас мы форматируем стеки вызовов под 24 библиотеки. О многих мы даже не знали. Мы также показываем карты Webpack и Angular в дереве исходников.

Мы планируем перенести все Firefox DevTools на GitHub, чтобы их могли использовать и улучшать больше людей. Мы с радостью примем вашу помощь. Можете перейти на страницу нашего проекта debugger.html на GitHub. Мы написали целый список инструкций по запуску отладчика на своей машине, где вы можете менять все, что хотите. Используйте его для отладки JS кода для чего угодно – браузеров, терминалов, серверов, телефонов, роботов. Если видите, что можно улучшить, пишите нам на GitHub.

Автор: Dustin Driver

Редакция: Команда webformyself.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Как правильно подключить JS- и PHP-скрипты к вашему сайту?

Сегодня я расскажу вам, как осуществляется подключение разных типов скриптов к вашему сайту. Это своего рода основа основ, и написать эту статью я должен был одной из первых. Потому – начнем.

Подключение JS-скриптов (файлы с расширением *.js) к сайту

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

Подключение JavaScript’а осуществляется двумя способами:

Цукерберг рекомендует:  Обучение - javascript settimer

1. Первый – это непосредственно вставка кода в ваш сайт с помощью тегов:

2. Второй – с помощью файла:

Где «https://www.pandoge.com/main.js» – путь до файла скрипта. Такой вариант рекомендуется писать для файлов на удаленном (внешнем) сервере. Если же файл находится на вашем сайте, то можно просто указать относительный путь:

Это удобно, если вы вдруг захотите сменить домен или перевести сайт на другой протокол.

Что касается места подключения, то все скрипты рекомендуется подключать в секции HEAD, перед закрывающим ее тегом. Например:

Их также можно подключить в секции BODY. Например, все библиотеки рекомендуется подключать в секции HEAD, тогда как все счетчики, слайдеры, галереи и прочие скрипты – в секции BODY, также перед закрывающим тегом.

Подключение PHP-скриптов (файлы с расширением *.php) к сайту

Подключение PHP-скриптов осуществляется уже тремя способами:

1. Первый – это та же вставка кода в саму страницу сайта (обратите внимание, что если вы имеете страницу с расширением *.html – вам необходимо сменить расширение на *.php) с помощью тегов:

2. С помощью файла (в таком случае подключение можно осуществлять и на странице с *.html расширением):

Но для работы этого способа в файл .htaccess, который находится в корне вашего сайта, в самый верх, необходимо добавить эти строки:

Если такого файла нет на хостинге — создайте его через любой текстовый редактор.

3. Третье – с помощью JS-скрипта. В этом случае вы также можете получить результат выполненного PHP-скрипта на сервере.

Реализация будет следующая:

Где «.result» – это класс, куда будут грузиться данные, а «/main.php», соответственно, адрес до PHP-скрипта.

Если вы грузите данные с другого сервера, то поддержка PHP на вашем сервере не обязательна. Не забывайте подключить к вашему сайту библиотеку jQuery.

Здесь правила абсолютно те же: полный адрес к файлу, если он находится на внешнем сервере, относительный – если на вашем.

Обратите внимание! Если вы хотите подключить PHP-скрипт к вашему сайту, то на сервере должна быть поддержка PHP. О том, есть ли у вас такая возможность – узнайте у своего хостинг-провайдера.

Если вы осуществляете подключение скриптов первый раз – попробуйте подключить скрипты из архива, который прикреплен в конце статьи. Если в обоих случаях вы получили сообщение «Hello World!» – значит, вы все сделали правильно.

codedokode / js-task-1.md

Простые задачи на яваскрипт

Сразу расскажу про несколько особенностей яваскрипта, о которых может быть не написано (или мало написано) в учебниках, но которые стоит понимать:


На 2020 год есть 3 версии: ES3, ES5 (он же ES Harmony), ES6 (aka ES Next или ES 2015). ES значит «ECMAScript», а название «JavaScript» это защищенная торговая марка и ее нельзя так просто использовать. ES3 это версия которая работает во всех браузерах с 2000 года, включая древний IE6. ES5, ES6 (подробнее на learn.JS) — новые, их уровень поддержки браузерами описан тут:

На 2020 год писать на ES5, а тем более на ES6 рановато, делать это можно, только если ты пишешь какой-то внутренний проект, например, который будет использоваться только внутри компании и у всех пользователей есть современная версия браузера. Некоторые решают эту проблему транспайлером — компилятором, преобразующим ES5/6 код в ES3.

И еще: язык Ява (Java) не имеет никакого отношения к яваскрипту, похожи в них только название и часть синтаксиса.

В новом Javascript есть строгий режим:

В нем некоторые ошибки, которые ранее прощались, становятся фатальными. Обязательно используй этот режим при решении задач.

Функции и замыкания

Функции — это объекты. У них есть свойства (например length ) и методы (например toSource , apply и call ). Функции можно хранить в переменных, передавать и возвращать из других функций:

Функция при создании привязывается к набору переменных родительской функции и потому видит ее переменные:

  • Код 1 видит переменные a, b и функцию f2 (и f1 тоже)
  • Код 2 видит свои переменные d, e, а также родительские a, b, и f2 (и f1 тоже)
  • Код 3 видит переменную f, а также d, e, a, b, f2 (и f1 тоже)

То есть внутренняя функции видит переменные внешней функции, которые были в момент ее создания. Это называется замыкание.

Внешняя функция не видит переменных внутренней. Код, находящийся вне функций, в глобальном контексте, не видит внутренние (локальные) переменные.

Порядок создания переменных

Локальные переменные (объявленные через var) создаются при входе в функцию, до выполнения ее кода. При этом им изначально присваивается undefined:

Этот код выполняется так:

  • создать переменную a и присвоить ей undefined
  • выполнить первый console.log
  • присвоить a значение 2
  • выполнить второй console.log

Копирование по значению и по ссылке

Примитивные значения дублируются при копировании, копирование объектов просто копирует ссылку на один и тот же объект. Примитивные значения — это не-объекты, то есть null , undefined , числа, true / false , строки. Если ты их присваиваешь переменной, передаешь или возвращаешь из функции, создается новая независимая копия значения:

Объекты (а это в том числе массивы (Array), функции (Function), регулярки (RegExp), даты (Date)) копируются и передаются в/из функции по ссылке:

Объекты (а значит и массивы, и функции, так как они тоже ими являются) сравниваются по идентичности, то есть тому, что это ссылки на один и тот же объект:

Во втором случае у нас 2 разных объекта и получается false . <> всегда создает новый объект. По этой причине <> === <> , [] === [] , function()<> === function()<> всегда дают false . И вообще, любое сравнение объекта с [] или <> даст false .

Ложные и правдивые значения

Falsy (ложных? лживеньких?) значений ровно 7, их надо знать наизусть: 0 , -0 (да, в программировании есть отрицательный ноль), NaN , null , undefined , » (пустая строка), false . Все остальные значения truthy, в том числе ‘0’ (строка из символа 0). При преобразовании в логический (булев) тип falsy значения преовращаются в false , а все остальные — в true :

У примитивных значений (примитивные = не-объекты, то есть числа, строки, true / false / null / undefined ) нет свойств и методов (они есть только у объектов). При попытке обратиться к свойствам/методам примитивов происходит боксинг: яваскрипт создает временный объект из примитива и обращается к нему (сам примитив остается неизменным). Для чисел создается объект «класса» Number, для true / false Boolean, для строк — String (вот мы и узнали, зачем были нужны эти встроенные классы). Для null и undefined выдается ошибка. То есть код

Превращается внутри в:

Потому присвоить свойство примитиву можно, но оно не сохранится — ведь оно создалось на временном объекте.

Это легко объяснить, если записать что происходит с учетом боксинга:

Боксинг сделан для того, чтобы с примитивами можно было работать как с объектами, например, вызывая у них методы. Само разделение на примитивы и объекты сделано из-за соображений производительности: если бы числа и строки были настоящими объектами, все работало бы медленнее. Если тебе понадобится (100% что не понадобится), ты можешь сделать боксинг и анбоксинг вручную:

Проверялка для первых 10 задачек от @dkab: http://dkab.github.io/jasmine-tests/ (робот не совершенен и может ошибаться. Если ты думаешь, что он не прав, напиши на codedokode@gmail.com и не забудь приложить свою программу — мы разберемся и вправим ему мозги).

Напиши функцию создания генератора sequence(start, step) . Она при вызове возвращает другую функцию-генератор, которая при каждом вызове дает число на 1 больше, и так до бесконечности. Начальное число, с которого начинать отсчет, и шаг, задается при создании генератора. Шаг можно не указывать, тогда он будет равен одному. Начальное значение по умолчанию равно 0. Генераторов можно создать сколько угодно.

Также, нужна функция take(gen, x) которая вызвает функцию gen заданное число ( x ) раз и возвращает массив с результатами вызовов. Она нам пригодится для отладки:

Напиши функцию map(fn, array) , которая принимает на вход функцию и массив, и обрабатывает каждый элемент массива этой функцией, возвращая новый массив. Пример:

Обрати внимание: функция не должна изменять переданный ей массив:

Это аналог array_map из PHP.

Напиши функцию fmap(a, gen) , которая принимает на вход 2 функции, a и gen , где gen — функция-генератор вроде той, что была в первом задании. fmap возвращает новую функцию-генератор, которая при каждом вызове берет следующее значение из gen и пропускает его через функцию a . Пример:

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

Эти аргументы бы передавались функции gen . Аргументов может быть любое количество.

Подсказка: если непонятно, как сделать функцию, принимающую произвольное число аргументов, то стоит погуглить про псевдопеременную arguments (псевдопеременная значит, что она выглядит как переменная, но формально ей не является). Чтобы понять, как вызвать функцию с заранее неизвестным числом аргументов, можно погуглить Function.prototype.call и Function.prototype.apply . В JS функции — это объекты, и у них есть полезные методы и свойства.

Частичное применение (partial application)

Напиши функцию partial(fn, a1, a2, . ) , которая позволяет зафиксировать один или несколько аргументов функции. Пример:

Есть функция с аргументами:

Мы можем с помощью partial сделать из нее функцию с меньшим числом аргументов, заранее задав значения для нескольких из них, например:

будет равносилен вызову:

Кстати, имеющийся в новых версиях JS метод bind() тоже может делать частичное применение: http://frontender.info/partial-application-in-javascript-using-bind/ Но ты должен обойтись без его использования, и написать свой велосипед.

Наша функция partial позволяет фиксировать только первые аргументы. Усовершенствуй ее, чтобы зафиксировать можно было любые аргументы, пропущенные аргументы обозначаются с помощью undefined. Обрати внимание, что теперь мы переименовали ее в partialAny , чтобы не путать с предыдущей:

напиши функцию bind , которая позволяет привязать контекст (значение this ) к функции:

В библиотеках тоже есть такой метод: http://lodash.com/docs#bind

напиши функцию pluck , которая берет массив объектов и возвращает массив значений определенного поля:

Такая функция была в lodash: http://lodash.com/docs#pluck но теперь вместо нее советуют использовать map: https://lodash.com/docs/4.15.0#map

Функция не должна изменять исходный массив.

напиши функцию filter , которая принимает функцию-предикат и массив. Возвращает она массив значений, для которых предикат вернет true.

Функция не должна изменять исходный массив:

Аналог из lodash: http://lodash.com/docs#filter В новых браузерах у массивов есть метод filter .

Напиши функцию, считающую число свойств в объекте:

Кстати, в новых браузерах с поддержкой Javascript ES5 есть метод Object.keys(x) , возвращающий массив ключей у объекта.

Можешь взять оттуда первые 5-10 городов и перенести в код. Города в списке могут идти в произвольном порядке. Напиши программу, которая отберет и выведет N самых населенных городов по убыванию числа жителей.

Некая сеть фастфудов предлагает несколько видов гамбургеров:

  • маленький (50 тугриков, 20 калорий)
  • большой (100 тугриков, 40 калорий)


Гамбургер может быть с одним из нескольких видов начинок (обязательно):

  • сыром (+ 10 тугриков, + 20 калорий)
  • салатом (+ 20 тугриков, + 5 калорий)
  • картофелем (+ 15 тугриков, + 10 калорий)

Дополнительно, гамбургер можно посыпать приправой (+ 15 тугриков, 0 калорий) и полить майонезом (+ 20 тугриков, + 5 калорий). Напиши программу, расчиытвающую стоимость и калорийность гамбургера. Используй ООП подход (подсказка: нужен класс Гамбургер, константы, методы для выбора опций и рассчета нужных величин).

Код должен быть защищен от ошибок. Представь, что твоим классом будет пользоваться другой программист. Если он передает неправильный тип гамбургера, например, или неправильный вид добавки, должно выбрасываться исключение (ошибка не должна молча игнорироваться).

Написанный класс должен соответствовать следующему jsDoc описанию (то есть содержать указанные методы, которые принимают и возвращают данные указанного типа и выбрасывают исключения указанного типа. Комментарии ниже можно скопировать в свой код):

Комментарии. Эта задача вызывает много непонимания, потому внимательно прочти эти комментарии перед решением.

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

Почему? Потому что каждый должен заниматься своим делом, класс должен только обсчитывать гамбургер, а вводом-выводом пусть занимаются другие. Иначе мы получим кашу, где разные функции смешаны вместе.

Типы начинок, размеры надо сделать константами. Никаких магических строк не должно быть.

Переданную информацию о параметрах гамбургера класс хранит внутри в своих полях. Вот как может выглядеть использование этого класса:

При неправильном использовании класс сообщает об этом с помощью выброса исключения: (урок на примере PHP: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a , учебник: https://learn.javascript.ru/exception )

Обрати внимание в коде выше на такие моменты:

  • класс не взаимодействует с внешним миром. Это не его дело, этим занимается другой код, а класс живет в изоляции от мира
  • обязательные параметры (размер и начинка) мы передаем через конструктор, чтобы нельзя было создать объект, не указав их
  • необязательные (добавка) добавляем через методы
  • имена методов начинаются с глагола и имеют вид «сделайЧтоТо»: calculateCalories() , addTopping()
  • типы начинок обозначены «константами» с понятными именами (на самом деле просто свойствами, написанным заглавными буквами, которые мы договорились считать «константами»)
  • об исключительных ситуациях сообщаем с помощью исключений
  • объект создается через конструктор — функцию, которая задает начальные значения полей. Имя конструктора пишется с большой буквы и обычно является существительным: new Hamburger(. )
  • «константы» вроде могут иметь значение, являющееся строкой или числом. От смены значения константы ничего не должно меняться (то есть эти значения не должны где-то еще быть записаны). К сожалению, в отличие от других языков (Java, PHP, C#) при опечатке в имени такой «константы» интепретатор JS не укажет на ошибку
  • в свойствах объекта гамбургера логично хранить исходные данные (размер, тип начинки), а не вычисленные из них (цена, число калорий и т.д.). Рассчитывать цену и калории логично в тот момент, когда это потребуется, а не заранее.
  • в JS нет синтаксиса, чтобы пометить свойство или метод приватным (доступным для использования только внутри класса), потому некоторые разработчики начинают их имена с подчеркивания и договариваются, что извне класса к ним никто не обращается. Вообще, в JS нет нормальных классов, потому многое основано на таких договоренностях.

В дополнение, вот еще инструкция, как решать задачи на ООП. Когда ты решаешь задачу на ООП, ты должен ответить на вопросы:

  • какие есть сущности, для которых мы сделаем классы? (Гамбургер).
  • какие у них есть свойства (размер, начинка, добавки). Цена или калории не являются свойствами так как они вычисляются из других свойств и хранить их не надо.
  • что мы хотим от них получить (какие у них должны быть методы). Например, сколько стоит гамбургер?
  • как сущности связаны? У нас одна сущность «Гамбургер» и она ни с чем не связана.

Заметь также, что в моем примере класс не взаимодействует с внешним миром. За это отвечает внешний относительно него код. Потому наш класс унивесален: ты можешь использовать его в консоли, выводя данные через console.log , а можешь приделать навороченный HTML-интерфейс с кнопками для запуска на планшете с тачскрином. Именно в таком стиле ты должен писать ООП код.

Послесловие. Если ты внимательно читал учебник по JS, то наверно знаешь, что в JS нет классов, а до версии ES5 нет и констант ( а как же решать задачу? ). Классы в JS имитируются разными споcобами, всякими костылями самый общеупотребимый — через добавление методов в прототипы объекта:

Если ты знаешь ООП в каком-то другом языке (например PHP, Java, Python), вот список соответствий между другими языками и JS:

  • класс = функция-конструктор + прототип
  • конструктор = функция с именем с большой буквы
  • поле объекта = создается в конструкторе через this.x = 1;
  • метод = функция на прототипе
  • константа класса = свойство, добавленное к функции-конструктору и написанное большими буквами: Hamburger.SOMETHING = ‘something’;
  • статические поля и методы = свойства добавленные к функции: Hamburger.somStaticMethod = function () < .. >;
  • private/public = нету, приватные свойства и методы можно обозначать подчеркиванием в начале
  • интерфейсы, абстрактные классы и методы = нету
  • наследование = в ES5 делается через Object.create , в ES3 через хак с прототипами (описан в learn.javascript.ru)

В ES5 константы можно реализовывать через свойства только для чтения. В ES6 добавлен синтаксис для классов (с константами), но для начала научись делать все по старинке, на ES3, так как такой код встретится в 99% библиотек. Вот новый синтаксис: http://frontender.info/es6-classes-final/

Обрати внимание, что в ES6 добавлен лишь синтаксис, и в итоге создается та же самая имитация класса через прототипы. Потому сначала ты должен научиться создавать их вручную, а потом только переходить на удобный синтаксис.

ES3, ES5, ES6 — это версии JS. ES3 это версия которая работает во всех браузерах с 2000 года. ES5, 6 — новые, их уровень поддержки описан тут:

13. В одном городе есть электрическая сеть. К ней могут быть подключены:

  • электростанции, вырабатывают мощность от 1 до 100 мегаватт
  • солнечные панели, генерируют от 1 до 5 мегаватт днем (в зависимости от вида панели, то есть некоторые панели генерируют 1 мегаватт, некоторые 2 и так далее) и 0 ночью
  • жилые дома, в них от 1 до 400 квартир, потребляют 4 кВт на квартиру днем и 1 кВт ночью.
  • линии электропередач, ведущие в другие города, по ним может подаваться недостающая или отдаваться лишняя энергия. У линий есть свойство «мощность», которая определяет, сколько мегаватт можно передать по ней, а также «цена мегаватта», которое показывает сколько можно получить или придется заплатить за переданный/полученный мегаватт. На разных линиях может быть разная цена.
Цукерберг рекомендует:  Javascript - Нужна помощь

Дан список всех элементов электросети. Напиши программу, рассчитывющую, сколько электричества необходимо закупить (или можно продать) днем и ночью для обеспечения баланса и сколько это будет стоить (или принесет прибыли). Используй продвинутый ООП подход для решения задачи.

14. напиши функцию, определяющую тип переменной. Результат должен быть одной из строк: ‘undefined’, ‘boolean’ (для true/false), ‘null’, ‘number’, ‘string’, ‘function’, ‘array’, ‘array-like’, ‘object’

array-like — это псевдомассив, то есть объект, у которого есть неотрицательное свойство length и элементы с 0 до length — 1 . Примеры псевдомассивов:

  • псевдопеременная arguments
  • коллекции, которые возвращают функции работы с DOM, вроде document.images , document.getElementsByTagName(..) , document.body.children

В JS есть оператор typeof , но у него есть подвохи:

  • typeof null дает ‘object’
  • typeof [] дает ‘object’

Определение массива через [] instanceof Array не сработает, если массив был создан в друго вкладке или фрейме браузера, так как в каждой вкладке свой объект window и свой window.Array .

Обычно для решения этой задачи используется хак с Object.prototype.toString.call(. ) : https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/toString#Example:_Using_toString_to_detect_object_type (обрати внимание: JS позволяет с помощью call() и apply() вызвать метод на произольном объекте, передав в качестве this что угодно).

15. Напиши функцию неглубокого копирования объектов и массивов.

По умолчанию, как ты наверно, знаешь, при копировании объектов или массивов (которые являются объекты) мы копируем лишь ссылку на тот же самый объект:

Функция неглубокого копирования должна создавать новый массив/объект, и копировать в него элементы из старого. При этом сами элементы копируются по ссылке:

Если в функцию копирования передан объект Date , надо создавать копию того же типа.

В библиотеке lodash для неглубокого копирования есть функция clone: http://lodash.com/docs#clone

16. Напиши функцию глубокого копирования объектов и массивов. Она должна делать не только копию переданного объекта/массива, но и копии вложенных них объектов/массивов. Также, копироваться должны объекты встроенного в JS конструктора Date

Решать можешь потом, так как сейчас не факт что ты сможешь их решить. Правильные ответы можно увидеть например в коде библиотеки lodash:

DOM, который построил Джек

Дальше идут задания на работу с DOM и событиями. DOM = Document Object Model — это набор объектов, которые соответствуют содержимому HTML-страницы, и позволяют взаимодействовать с и изменять содержимое страницы в браузере. Обычно каждому тегу на странице соответствует отдельный узел дерева DOM. Узлы образуют дерево, и для каждого узла можно получить родительский узел, список узлов-детей, соседние узлы.

CSSOM = CSS Object Model — это свойства и методы этих объектов, которые позволяют изменять CSS-стили элементов, а также получать информацию об их размерах и положении.

События в браузере — это события движения мыши, нажатия клавиш, прокрутки страницы. Ты можешь подписываться на эти события, и указанная тобой функция будет вызваться в случае их возникновения.

Теория для изучения (читать можно параллельно с решением задач):

14 подсказок для отладки JavaScript, о которых Вы могли не знать

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

Мы составили список из 14 подсказок для отладки, о которых Вы могли не знать, но которые могут помочь Вам отладить JavaScript код.

Большинство из этих подсказок для Chrome и Firefox, хотя, большинство из них работает и в средствах разработки для других браузеров.

1. ‘debugger;’

После console.log, ‘debugger;‘ мой любимый быстрый и «грязный» инструмент для отладки. Как только Вы добавляете его в свой код, Chrome автоматически останавливает выполнение кода в этой точке. Вы можете даже обернуть его в условие, чтобы он срабатывал только тогда, когда Вам это необходимо.

2. Отображение объектов в виде таблиц

Иногда у Вас есть сложный набор объектов, которые Вы хотите просмотреть. Вы можете использовать console.log для их отображения, а потом пролистывать огромный список, или использовать console.table. Так намного легче понять, с чем Вы имеете дело.

3. Попробуйте посмотреть на разных разрешениях

Было бы потрясающе, если бы на Вашем столе было любое мобильное устройство, однако в реальном мире это невозможно. Как изменить размер окна просмотра? Chrome предоставляет Вам все необходимое. Перейдите в инструменты разработчика, а затем нажмите кнопку «Режим переключения устройства». Посмотрите, как ваши медиа-выражения оживают!


4. Быстрый поиск DOM-элементов

Выберите DOM-элемент на панели элементов, а затем обращайтесь к нему в консоли. Инструменты разработчика в Chrome запоминают последние пять элементов: последний выбранный элемент $0, предпоследний выбранный элемент $1, и т.д.

Если Вы выбирали следующие элементы в порядке ‘item-4’, ‘item-3’, ‘item-2’, ‘item-1’, ‘item-0’, то Вы можете получить доступ к DOM-элементам, как показано в консоли:

5. Замер времени выполнения кода с помощью console.time() и console.timeEnd()

Может быть очень полезно узнать, за какое время выполняется фрагмент кода, особенно при отладке медленных циклов. Вы можете установить несколько именованных таймеров. Посмотрим пример:

Этот код выдаст следующий результат:

6. Получение стек-трейса для функции

Вероятно Вы знаете, что в JavaScript-фреймворках очень много кода.

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

Поскольку JavaScript не является сильно структурированным языком, иногда бывает полезно получить информацию о том, что и когда произошло. В этот момент на сцену выходит console.trace.

Представьте, что Вы хотите увидеть весь стек вызовов для функции funcZ в экземпляре car на 33 строке.

Теперь мы видим, что func1 вызывает func2, которая вызывает func4. Func4 создает экземпляр Car, а затем вызывает функцию car.funcX, и т.д.

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

7. Форматирование минифицированного кода

Иногда Вы можете столкнуться с проблемой прямо на продакшене, а ваших сурс-мапов нет на сервере. Ничего страшного. Chrome может отформатировать Ваши JavaScript-файлы, приведя их в более читаемый формат. Конечно, код будет не так информативен, как исходный код, но, по крайней мере, Вы можете понять что в нем происходит. Нажмите кнопку <> «Pretty Print«, расположенную под просмотрщиком кода в инспекторе.

8. Быстрая отладка функции

Предположим, Вы хотите добавить точку останова для функции.

Есть два самых распространенных способа это сделать:

  1. Найти нужную строку в инпекторе и добавить точку останова
  2. Добавить debugger в Ваш скрипт

Оба этих решения требуют поиска нужного файла и нужной строки, которую Вы хотите отладить.

Использование консоли для этой цели, вероятно, менее распространено. Используйте debug(funcName) в консоли, и скрипт приостановит свое выполнение, когда достигнет нужной функции.

Это очень быстрый способ, однако он не работает на закрытых и анонимных функциях. Но если у Вас другая ситуация, то это, вероятно, самый быстрый способ отладить функцию. (Прим. авт.: есть функция console.debug, которая нужна для другого.)

9. Скрипты, не требующие отладки

На современных проектах часто используются фреймворки и библиотеки. Большинство из них хорошо протестированы, и работают достаточно стабильно. Но отладчик все еще обходит файлы, которые не имеет смысла отлаживать. Решение заключается в складывании скриптов в «черный ящик», который не нужно отлаживать. В этот ящик могут входить и Ваши скрипты. Подробнее об этом читайте в этой статье.

10. Найдите важные вещи с помощью более сложных способов отладки

При более сложных сценариях отладки может потребоваться вывести много строк. Одним из способов структурирования выводимых данных является использования различных функций console. Например, console.log, console.debug, console.warn, console.info, console.error, и т.д. Затем Вы можете отфильтровать их в инспекторе. Но иногда это не совсем то, что Вам нужно при отладке. Теперь Вы можете проявить творческий подход, и создавать собственные форматы вывода данных в консоли с помощью CSS.

11. Отслеживайте вызовы функций и ее аргументы.

В консоли Chrome, Вы можете следить за определенными функциями. Каждый раз, когда функция вызывается, это будет залогировано вместе с параметрами, которые в нее переданы.

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

12. Быстрый доступ к элементам в консоли

Более быстрый способ использовать querySelector в консоли — это использовать $. $(‘css-селектор’) — вернет первый подходящий элемент, а $$(‘css-селектор’) — вернет все подходящие элементы. Если Вы используете элемент больше одного раза, можно сохранить его в переменную.

13. Postman великолепен (но Firefox быстрее)

Многие разработчики, используют Postman для тестирования AJAX-запросов.

Иногда, для этих целей проще использовать браузер.

Когда Вы больше не беспокоитесь о куках для авторизации, если работаете со страницей, защищенной паролем. Вот как Вы можете редактировать и повторно отправлять запросы в Firefox.

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

Ниже я привел пример запроса, который был отправлен несколько раз с разными параметрами:

14. Точка останова в момент изменения DOM-элемента

DOM может быть забавным. Иногда, элементы в нем меняются по непонятной для Вас причине. Однако, когда Вам нужно отлаживать JavaScript, Chrome позволяет Вам приостановить выполнение кода, при изменении DOM-элемента. Щелкните правой кнопкой мыши по интересующему элементу в инспекторе, и выберите условие остановки выполнения.

Взаимодействие PHP и JavaScript

Автор: Артемьев Сергей Игоревич
ICQ: 438856621
email: _spin_@bk.ru

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

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

Различаются языки и по уровню безопасности. При выполнении PHP-скрипта вы можете обращаться к файловой системе сервера, базам данных и другим внешним объектам, на которые вам предоставили права администраторы. А вот JavaScript ограничен только встроенными объектами браузера и с их помощью вы не сможете читать или писать непосредственно на диск. Сделано это в первую очередь для защиты от злоумышленников, т.к. если разрешить доступ скриптам к системной информации и файлам – обязательно найдётся умелец, который напишет код, скрытно отсылающий ваши файлы кошельков, логины, пароли и другую закрытую информацию на адрес умельца.

Помимо прочего, протокол HTTP, по которому передаются все веб-страницы, не поддерживает постоянных соединений, т.е. браузер подключается к серверу, запрашивает страницу, получает данные и немедленно отключается. Это означает, что все скрипты PHP завершаются ещё ДО того, как начнутся выполняться скрипты JavaScript.

Таким образом, сам собой напрашивается вывод: прямое взаимодействие скриптов на PHP и JavaScript попросту невозможно.

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

  1. Внесение изменений в текст страницы (в скрипт);
  2. Использование Cookies;
  3. Использование Ajax;

Первый способ пригоден только для передачи данных и параметров с сервера на клиент. Суть метода проста: при генерации страницы необходимые параметры зашиваются прямо в текст скрипта.

В этом примере мы на этапе формирования страницы вписываем в неё заданную переменную с нужным нам значением. Работает это так:

  1. От пользователя поступает запрос на получение страницы.
  2. Запускается PHP и начинает выполнять соответствующий скрипт.
  3. В процессе выполнения скрипт создаёт HTML-страницу, содержащую скрипт JavaScript. Как я уже упоминал раньше, создаваемая веб-страница с точки зрения сервера – обычный текст, который можно перед отправкой пользователю править как угодно.
  4. Готовая страница передаётся в браузер пользователя.
  5. По окончании загрузки страницы в браузер начнёт выполнение наш JavaScript. При этом скрипт не будет «знать», каким образом он составлен – вручную программистом или автоматически скриптом. Главное – скрипт должен быть синтаксически верен и работоспособен.

Второй способ несколько сложнее, но позволяет передавать параметры как со стороны сервера, так и со стороны клиента. Суть в том, что и PHP и JavaScript позволяют читать и сохранять cookies (подробнее про cookies рассказывалось в одном из предыдущих уроков). Например (условный):

Здесь мы на стороне сервера устанавливаем cookie с необходимыми нам параметрами. При этом клиенту посылается специальным образом сформированная команда и данные, т.е. все cookie передаются ДО передачи основной страницы. Это значит, что все установленные сервером cookie будут доступны после загрузки страницы, а значит и при выполнении скриптов JavaScript.

Аналогично и для обратной передачи: все cookies, установленные из JavaScript, будут переданы на сервер при первом же обновлении страницы.

Основной недостаток этого метода – ограничение на размер передаваемых данных. Максимальный размер одного cookie не может превышать 4Кб, а у некторых пользователей возможность установки cookies вообще отключена. Так же этот способ создаёт большой дополнительный трафик, т.к. все cookies автоматически отправляются на сервер при каждом обновлении страницы.

У обоих методов взаимодействия есть два общих недостатка:

  1. Все обновления и изменения происходят только при загрузке/обновлении страницы. Это очень неудобно, особенно когда приходится заполнять громоздкие и сложные формы с динамическим содержимым, когда состав и содержимое полей изменяется в зависимости от уже введённых данных.
  2. Программист должен достаточно хорошо разбираться как в PHP, так и в JavaScript, чтобы грамотно написать клиентские и серверные скрипты.

Последний способ взаимодействия – AJAX. Это наилучший, пусть и не самый простой способ. Ajax – это комбинированная технология, использующая все преимущества PHP и JavaScript, позволяя изменять и обновлять данные на страницах вашего сайта «на лету», т.е. без перезагрузки страницы.


Для использования Ajax обычно создаётся так называемые «frontend» и «backend». Backend – это PHP-скрипты, выполняющиеся на сервере. Обычно такие скрипты возвращают структурированные блоки данных (массивы), не содержащие никакого оформления.

Frontend – это скрипты JavaScript, выполняющиеся в браузере пользователя. Основное их назначение – вызвать требуемый скрипт backend`a, получить данные и правильно их вывести на странице, добавив при необходимости обрамление из тегов и стилей.

Подробнее об использовании Ajax вы можете прочитать в соответствующем уроке по JavaScript на этом сайте.

Таким образом, взаимодействие PHP и JavaScript наладить всё-таки можно, но для этого надо хорошо разбираться в обоих языках. Из собственного опыта могу сказать, что для домашних страничек и небольших сайтов проще всего применять первый способ (прямую запись текста скрипта). Для проектов покрупнее или динамичнее – Ajax. А вот от третьего способа я бы рекомендовал вам воздержаться, т.к там слишком много подводных камней и условностей, таких как размер cookie, их поддержка браузерами, формат данных, кодировка и т.п.

Javascript — HELP с JS, PHP, доработка и БАГ

Оставлять свои предложения по заказу могут только зарегистрированные пользователи с аккаунтом специалиста.

Редактирование

Удаление

Вы уверены, что хотите удалить отклик сообщение ?

Получить ссылку

Скопируйте ссылку в буфер обмена:

Выбор исполнителя

Вы собираетесь выбрать исполнителем своего заказа пользователя:

В целях вашей безопасности мы рекомендуем использовать «Безопасную сделку» для работы с исполнителем. В случае возникновения неприятностей в процессе исполнения заказа вы сможете подать жалобу на исполнителя и вернуть свои деньги. Средства выплачиваются исполнителю только после подтверждения выполненной работы со стороны заказчика.

После согласования безопасной сделки вы сможете связаться с исполнителем и приступить к работе.

codedokode / js-task-1.md

Простые задачи на яваскрипт

Сразу расскажу про несколько особенностей яваскрипта, о которых может быть не написано (или мало написано) в учебниках, но которые стоит понимать:

На 2020 год есть 3 версии: ES3, ES5 (он же ES Harmony), ES6 (aka ES Next или ES 2015). ES значит «ECMAScript», а название «JavaScript» это защищенная торговая марка и ее нельзя так просто использовать. ES3 это версия которая работает во всех браузерах с 2000 года, включая древний IE6. ES5, ES6 (подробнее на learn.JS) — новые, их уровень поддержки браузерами описан тут:

На 2020 год писать на ES5, а тем более на ES6 рановато, делать это можно, только если ты пишешь какой-то внутренний проект, например, который будет использоваться только внутри компании и у всех пользователей есть современная версия браузера. Некоторые решают эту проблему транспайлером — компилятором, преобразующим ES5/6 код в ES3.

Цукерберг рекомендует:  CSS для закладки с диагональной рамкой

И еще: язык Ява (Java) не имеет никакого отношения к яваскрипту, похожи в них только название и часть синтаксиса.

В новом Javascript есть строгий режим:

В нем некоторые ошибки, которые ранее прощались, становятся фатальными. Обязательно используй этот режим при решении задач.

Функции и замыкания

Функции — это объекты. У них есть свойства (например length ) и методы (например toSource , apply и call ). Функции можно хранить в переменных, передавать и возвращать из других функций:

Функция при создании привязывается к набору переменных родительской функции и потому видит ее переменные:

  • Код 1 видит переменные a, b и функцию f2 (и f1 тоже)
  • Код 2 видит свои переменные d, e, а также родительские a, b, и f2 (и f1 тоже)
  • Код 3 видит переменную f, а также d, e, a, b, f2 (и f1 тоже)

То есть внутренняя функции видит переменные внешней функции, которые были в момент ее создания. Это называется замыкание.

Внешняя функция не видит переменных внутренней. Код, находящийся вне функций, в глобальном контексте, не видит внутренние (локальные) переменные.

Порядок создания переменных

Локальные переменные (объявленные через var) создаются при входе в функцию, до выполнения ее кода. При этом им изначально присваивается undefined:

Этот код выполняется так:

  • создать переменную a и присвоить ей undefined
  • выполнить первый console.log
  • присвоить a значение 2
  • выполнить второй console.log

Копирование по значению и по ссылке

Примитивные значения дублируются при копировании, копирование объектов просто копирует ссылку на один и тот же объект. Примитивные значения — это не-объекты, то есть null , undefined , числа, true / false , строки. Если ты их присваиваешь переменной, передаешь или возвращаешь из функции, создается новая независимая копия значения:

Объекты (а это в том числе массивы (Array), функции (Function), регулярки (RegExp), даты (Date)) копируются и передаются в/из функции по ссылке:

Объекты (а значит и массивы, и функции, так как они тоже ими являются) сравниваются по идентичности, то есть тому, что это ссылки на один и тот же объект:

Во втором случае у нас 2 разных объекта и получается false . <> всегда создает новый объект. По этой причине <> === <> , [] === [] , function()<> === function()<> всегда дают false . И вообще, любое сравнение объекта с [] или <> даст false .

Ложные и правдивые значения

Falsy (ложных? лживеньких?) значений ровно 7, их надо знать наизусть: 0 , -0 (да, в программировании есть отрицательный ноль), NaN , null , undefined , » (пустая строка), false . Все остальные значения truthy, в том числе ‘0’ (строка из символа 0). При преобразовании в логический (булев) тип falsy значения преовращаются в false , а все остальные — в true :

У примитивных значений (примитивные = не-объекты, то есть числа, строки, true / false / null / undefined ) нет свойств и методов (они есть только у объектов). При попытке обратиться к свойствам/методам примитивов происходит боксинг: яваскрипт создает временный объект из примитива и обращается к нему (сам примитив остается неизменным). Для чисел создается объект «класса» Number, для true / false Boolean, для строк — String (вот мы и узнали, зачем были нужны эти встроенные классы). Для null и undefined выдается ошибка. То есть код

Превращается внутри в:

Потому присвоить свойство примитиву можно, но оно не сохранится — ведь оно создалось на временном объекте.

Это легко объяснить, если записать что происходит с учетом боксинга:

Боксинг сделан для того, чтобы с примитивами можно было работать как с объектами, например, вызывая у них методы. Само разделение на примитивы и объекты сделано из-за соображений производительности: если бы числа и строки были настоящими объектами, все работало бы медленнее. Если тебе понадобится (100% что не понадобится), ты можешь сделать боксинг и анбоксинг вручную:

Проверялка для первых 10 задачек от @dkab: http://dkab.github.io/jasmine-tests/ (робот не совершенен и может ошибаться. Если ты думаешь, что он не прав, напиши на codedokode@gmail.com и не забудь приложить свою программу — мы разберемся и вправим ему мозги).

Напиши функцию создания генератора sequence(start, step) . Она при вызове возвращает другую функцию-генератор, которая при каждом вызове дает число на 1 больше, и так до бесконечности. Начальное число, с которого начинать отсчет, и шаг, задается при создании генератора. Шаг можно не указывать, тогда он будет равен одному. Начальное значение по умолчанию равно 0. Генераторов можно создать сколько угодно.

Также, нужна функция take(gen, x) которая вызвает функцию gen заданное число ( x ) раз и возвращает массив с результатами вызовов. Она нам пригодится для отладки:

Напиши функцию map(fn, array) , которая принимает на вход функцию и массив, и обрабатывает каждый элемент массива этой функцией, возвращая новый массив. Пример:

Обрати внимание: функция не должна изменять переданный ей массив:

Это аналог array_map из PHP.

Напиши функцию fmap(a, gen) , которая принимает на вход 2 функции, a и gen , где gen — функция-генератор вроде той, что была в первом задании. fmap возвращает новую функцию-генератор, которая при каждом вызове берет следующее значение из gen и пропускает его через функцию a . Пример:

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

Эти аргументы бы передавались функции gen . Аргументов может быть любое количество.

Подсказка: если непонятно, как сделать функцию, принимающую произвольное число аргументов, то стоит погуглить про псевдопеременную arguments (псевдопеременная значит, что она выглядит как переменная, но формально ей не является). Чтобы понять, как вызвать функцию с заранее неизвестным числом аргументов, можно погуглить Function.prototype.call и Function.prototype.apply . В JS функции — это объекты, и у них есть полезные методы и свойства.

Частичное применение (partial application)

Напиши функцию partial(fn, a1, a2, . ) , которая позволяет зафиксировать один или несколько аргументов функции. Пример:


Есть функция с аргументами:

Мы можем с помощью partial сделать из нее функцию с меньшим числом аргументов, заранее задав значения для нескольких из них, например:

будет равносилен вызову:

Кстати, имеющийся в новых версиях JS метод bind() тоже может делать частичное применение: http://frontender.info/partial-application-in-javascript-using-bind/ Но ты должен обойтись без его использования, и написать свой велосипед.

Наша функция partial позволяет фиксировать только первые аргументы. Усовершенствуй ее, чтобы зафиксировать можно было любые аргументы, пропущенные аргументы обозначаются с помощью undefined. Обрати внимание, что теперь мы переименовали ее в partialAny , чтобы не путать с предыдущей:

напиши функцию bind , которая позволяет привязать контекст (значение this ) к функции:

В библиотеках тоже есть такой метод: http://lodash.com/docs#bind

напиши функцию pluck , которая берет массив объектов и возвращает массив значений определенного поля:

Такая функция была в lodash: http://lodash.com/docs#pluck но теперь вместо нее советуют использовать map: https://lodash.com/docs/4.15.0#map

Функция не должна изменять исходный массив.

напиши функцию filter , которая принимает функцию-предикат и массив. Возвращает она массив значений, для которых предикат вернет true.

Функция не должна изменять исходный массив:

Аналог из lodash: http://lodash.com/docs#filter В новых браузерах у массивов есть метод filter .

Напиши функцию, считающую число свойств в объекте:

Кстати, в новых браузерах с поддержкой Javascript ES5 есть метод Object.keys(x) , возвращающий массив ключей у объекта.

Можешь взять оттуда первые 5-10 городов и перенести в код. Города в списке могут идти в произвольном порядке. Напиши программу, которая отберет и выведет N самых населенных городов по убыванию числа жителей.

Некая сеть фастфудов предлагает несколько видов гамбургеров:

  • маленький (50 тугриков, 20 калорий)
  • большой (100 тугриков, 40 калорий)

Гамбургер может быть с одним из нескольких видов начинок (обязательно):

  • сыром (+ 10 тугриков, + 20 калорий)
  • салатом (+ 20 тугриков, + 5 калорий)
  • картофелем (+ 15 тугриков, + 10 калорий)

Дополнительно, гамбургер можно посыпать приправой (+ 15 тугриков, 0 калорий) и полить майонезом (+ 20 тугриков, + 5 калорий). Напиши программу, расчиытвающую стоимость и калорийность гамбургера. Используй ООП подход (подсказка: нужен класс Гамбургер, константы, методы для выбора опций и рассчета нужных величин).

Код должен быть защищен от ошибок. Представь, что твоим классом будет пользоваться другой программист. Если он передает неправильный тип гамбургера, например, или неправильный вид добавки, должно выбрасываться исключение (ошибка не должна молча игнорироваться).

Написанный класс должен соответствовать следующему jsDoc описанию (то есть содержать указанные методы, которые принимают и возвращают данные указанного типа и выбрасывают исключения указанного типа. Комментарии ниже можно скопировать в свой код):

Комментарии. Эта задача вызывает много непонимания, потому внимательно прочти эти комментарии перед решением.

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

Почему? Потому что каждый должен заниматься своим делом, класс должен только обсчитывать гамбургер, а вводом-выводом пусть занимаются другие. Иначе мы получим кашу, где разные функции смешаны вместе.

Типы начинок, размеры надо сделать константами. Никаких магических строк не должно быть.

Переданную информацию о параметрах гамбургера класс хранит внутри в своих полях. Вот как может выглядеть использование этого класса:

При неправильном использовании класс сообщает об этом с помощью выброса исключения: (урок на примере PHP: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a , учебник: https://learn.javascript.ru/exception )

Обрати внимание в коде выше на такие моменты:

  • класс не взаимодействует с внешним миром. Это не его дело, этим занимается другой код, а класс живет в изоляции от мира
  • обязательные параметры (размер и начинка) мы передаем через конструктор, чтобы нельзя было создать объект, не указав их
  • необязательные (добавка) добавляем через методы
  • имена методов начинаются с глагола и имеют вид «сделайЧтоТо»: calculateCalories() , addTopping()
  • типы начинок обозначены «константами» с понятными именами (на самом деле просто свойствами, написанным заглавными буквами, которые мы договорились считать «константами»)
  • об исключительных ситуациях сообщаем с помощью исключений
  • объект создается через конструктор — функцию, которая задает начальные значения полей. Имя конструктора пишется с большой буквы и обычно является существительным: new Hamburger(. )
  • «константы» вроде могут иметь значение, являющееся строкой или числом. От смены значения константы ничего не должно меняться (то есть эти значения не должны где-то еще быть записаны). К сожалению, в отличие от других языков (Java, PHP, C#) при опечатке в имени такой «константы» интепретатор JS не укажет на ошибку
  • в свойствах объекта гамбургера логично хранить исходные данные (размер, тип начинки), а не вычисленные из них (цена, число калорий и т.д.). Рассчитывать цену и калории логично в тот момент, когда это потребуется, а не заранее.
  • в JS нет синтаксиса, чтобы пометить свойство или метод приватным (доступным для использования только внутри класса), потому некоторые разработчики начинают их имена с подчеркивания и договариваются, что извне класса к ним никто не обращается. Вообще, в JS нет нормальных классов, потому многое основано на таких договоренностях.

В дополнение, вот еще инструкция, как решать задачи на ООП. Когда ты решаешь задачу на ООП, ты должен ответить на вопросы:

  • какие есть сущности, для которых мы сделаем классы? (Гамбургер).
  • какие у них есть свойства (размер, начинка, добавки). Цена или калории не являются свойствами так как они вычисляются из других свойств и хранить их не надо.
  • что мы хотим от них получить (какие у них должны быть методы). Например, сколько стоит гамбургер?
  • как сущности связаны? У нас одна сущность «Гамбургер» и она ни с чем не связана.

Заметь также, что в моем примере класс не взаимодействует с внешним миром. За это отвечает внешний относительно него код. Потому наш класс унивесален: ты можешь использовать его в консоли, выводя данные через console.log , а можешь приделать навороченный HTML-интерфейс с кнопками для запуска на планшете с тачскрином. Именно в таком стиле ты должен писать ООП код.

Послесловие. Если ты внимательно читал учебник по JS, то наверно знаешь, что в JS нет классов, а до версии ES5 нет и констант ( а как же решать задачу? ). Классы в JS имитируются разными споcобами, всякими костылями самый общеупотребимый — через добавление методов в прототипы объекта:

Если ты знаешь ООП в каком-то другом языке (например PHP, Java, Python), вот список соответствий между другими языками и JS:

  • класс = функция-конструктор + прототип
  • конструктор = функция с именем с большой буквы
  • поле объекта = создается в конструкторе через this.x = 1;
  • метод = функция на прототипе
  • константа класса = свойство, добавленное к функции-конструктору и написанное большими буквами: Hamburger.SOMETHING = ‘something’;
  • статические поля и методы = свойства добавленные к функции: Hamburger.somStaticMethod = function () < .. >;
  • private/public = нету, приватные свойства и методы можно обозначать подчеркиванием в начале
  • интерфейсы, абстрактные классы и методы = нету
  • наследование = в ES5 делается через Object.create , в ES3 через хак с прототипами (описан в learn.javascript.ru)

В ES5 константы можно реализовывать через свойства только для чтения. В ES6 добавлен синтаксис для классов (с константами), но для начала научись делать все по старинке, на ES3, так как такой код встретится в 99% библиотек. Вот новый синтаксис: http://frontender.info/es6-classes-final/

Обрати внимание, что в ES6 добавлен лишь синтаксис, и в итоге создается та же самая имитация класса через прототипы. Потому сначала ты должен научиться создавать их вручную, а потом только переходить на удобный синтаксис.

ES3, ES5, ES6 — это версии JS. ES3 это версия которая работает во всех браузерах с 2000 года. ES5, 6 — новые, их уровень поддержки описан тут:

13. В одном городе есть электрическая сеть. К ней могут быть подключены:

  • электростанции, вырабатывают мощность от 1 до 100 мегаватт
  • солнечные панели, генерируют от 1 до 5 мегаватт днем (в зависимости от вида панели, то есть некоторые панели генерируют 1 мегаватт, некоторые 2 и так далее) и 0 ночью
  • жилые дома, в них от 1 до 400 квартир, потребляют 4 кВт на квартиру днем и 1 кВт ночью.
  • линии электропередач, ведущие в другие города, по ним может подаваться недостающая или отдаваться лишняя энергия. У линий есть свойство «мощность», которая определяет, сколько мегаватт можно передать по ней, а также «цена мегаватта», которое показывает сколько можно получить или придется заплатить за переданный/полученный мегаватт. На разных линиях может быть разная цена.

Дан список всех элементов электросети. Напиши программу, рассчитывющую, сколько электричества необходимо закупить (или можно продать) днем и ночью для обеспечения баланса и сколько это будет стоить (или принесет прибыли). Используй продвинутый ООП подход для решения задачи.

14. напиши функцию, определяющую тип переменной. Результат должен быть одной из строк: ‘undefined’, ‘boolean’ (для true/false), ‘null’, ‘number’, ‘string’, ‘function’, ‘array’, ‘array-like’, ‘object’

array-like — это псевдомассив, то есть объект, у которого есть неотрицательное свойство length и элементы с 0 до length — 1 . Примеры псевдомассивов:

  • псевдопеременная arguments
  • коллекции, которые возвращают функции работы с DOM, вроде document.images , document.getElementsByTagName(..) , document.body.children

В JS есть оператор typeof , но у него есть подвохи:

  • typeof null дает ‘object’
  • typeof [] дает ‘object’

Определение массива через [] instanceof Array не сработает, если массив был создан в друго вкладке или фрейме браузера, так как в каждой вкладке свой объект window и свой window.Array .

Обычно для решения этой задачи используется хак с Object.prototype.toString.call(. ) : https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/toString#Example:_Using_toString_to_detect_object_type (обрати внимание: JS позволяет с помощью call() и apply() вызвать метод на произольном объекте, передав в качестве this что угодно).

15. Напиши функцию неглубокого копирования объектов и массивов.

По умолчанию, как ты наверно, знаешь, при копировании объектов или массивов (которые являются объекты) мы копируем лишь ссылку на тот же самый объект:

Функция неглубокого копирования должна создавать новый массив/объект, и копировать в него элементы из старого. При этом сами элементы копируются по ссылке:

Если в функцию копирования передан объект Date , надо создавать копию того же типа.

В библиотеке lodash для неглубокого копирования есть функция clone: http://lodash.com/docs#clone

16. Напиши функцию глубокого копирования объектов и массивов. Она должна делать не только копию переданного объекта/массива, но и копии вложенных них объектов/массивов. Также, копироваться должны объекты встроенного в JS конструктора Date

Решать можешь потом, так как сейчас не факт что ты сможешь их решить. Правильные ответы можно увидеть например в коде библиотеки lodash:

DOM, который построил Джек

Дальше идут задания на работу с DOM и событиями. DOM = Document Object Model — это набор объектов, которые соответствуют содержимому HTML-страницы, и позволяют взаимодействовать с и изменять содержимое страницы в браузере. Обычно каждому тегу на странице соответствует отдельный узел дерева DOM. Узлы образуют дерево, и для каждого узла можно получить родительский узел, список узлов-детей, соседние узлы.

CSSOM = CSS Object Model — это свойства и методы этих объектов, которые позволяют изменять CSS-стили элементов, а также получать информацию об их размерах и положении.

События в браузере — это события движения мыши, нажатия клавиш, прокрутки страницы. Ты можешь подписываться на эти события, и указанная тобой функция будет вызваться в случае их возникновения.

Теория для изучения (читать можно параллельно с решением задач):

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих