что такое хинт в javascript

Метапрограммирование в JavaScript

Метапрограммирование — вид программирования, связанный с созданием программ, которые порождают другие программы как результат своей работы, либо программ, которые меняют себя во время выполнения. (Википедия)

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

JavaScript по своей природе является очень мощным динамическим языком и позволяет приятно писать гибкий код:

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

В дополнение к гибкому синтаксису, у нас есть ещё и куча полезных функций для написания динамического кода: Object.create, Object.defineProperty, Function.apply и многие другие.

Рассмотрим же их поподробнее.

1. Генерация кода

Стандартным средством для динамического выполнения кода является функция eval, позволяющая выполнить код из переданной строки:

К сожалению, eval имеет много нюансов:

Для решения этих проблем есть прекрасная альтернатива — new Function.

В отличие от eval, мы всегда можем явно передавать параметры через аргументы функции и динамически указывать ей контекст this (через Function.apply или Function.call). К тому же создаваемая функция всегда вызывается в глобальной области видимости.

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

2. Работа с функциями

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

Function.length — позволяет узнать количество аргументов у функции:

Function.apply и Function.call — позволяют динамически менять контекст this у функции:

Отличаются они друг друга только тем, что в Function.apply аргументы функции подаются в виде массива, а в Function.call — через запятую. Эту особенность раньше часто использовали, чтобы передавать в функцию список аргументов в виде массива. Распространённый пример — это функция Math.max (по умолчанию она не умеет работать с массивами):

С появлением нового spread-оператора можно просто писать так:

Function.bind — позволяет создать копию функцию из существующей, но с другим контекстом:

Function.caller — позволяет получить вызывающую функцию. Использовать её не рекомендуется, так как она отсутствует в стандарте языка и не будет работать в строгом режиме. Это было сделано из-за того, что если различные движки JavaScript реализуют описанную в спецификации языка оптимизацию tail call, то вызов Function.caller может начать приводить к неправильным результатам. Пример использования:

Function.toString — возвращает строковое представление функции. Это очень мощная возможность, позволяющая исследовать как содержимое функции, так и её аргументы:

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

Простые примеры с парсингом функций регулярками:

Источник

Хинт Hint

Хинт — это подсказка, появляющаяся при наведении на элемент.

Обычно маленькую подсказку называют тултип, а большую хинт. Но в Контур.Гайдах всё наоборот. Так исторически сложилось. Зато проще запомнить: меньше слово — меньше контрол.

При общении с пользователями мы говорим не «хинт», а «всплывающая подсказка».

Когда использовать

Используется на элементах, которые не вмещают полное название или требуют небольшого пояснения. Например: панель действий, иконки без текста, сокращенные слишком длинные названия в таблице.

Описание работы

Хинт появляется при наведении курсора на элемент, с задержкой в 400 миллисекунд. Это нужно чтобы при движении курсора по странице не было моргания хинтов.

Исчезает хинт мгновенно, как только курсор «уйдет» с элемента. Хинт исчезает и в том случае, если после его появления прокрутить страницу.

Хинт должен полностью заменить в интерфейсе стандартные хинты браузера, вместо системных подсказок из тегов alt и title.

Текст

Текст хинта — максимально короткий, в идеале не больше 70 символов. Не может содержать инструкцию.

Не дублируйте название объекта в хинте.

Размер и расположение

Максимальная ширина прямоугольной области 200 px.

Хинт появляется сверху от элемента к которому относится. Если сверху нет места — открывается вниз. Можно указать приоритет — сверху или снизу, и даже слева или справа.

Если хинт находится сверху или снизу от элемента, то текст в нем выравнивается по центру. Если справа или слева — то выравнивание по левому краю.

Источник

8 практичных хитростей веб-разработчика — применить немедленно!

HTML, CSS и JS хинты, которые полезно знать — перевод 8 Tricks for Web Developers You Can Put Into Practice Immediately

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

Поэтому я, Daan, объединил те некоторые из HTML, CSS и JavaScript приемов, о которых, на мой взгляд, будет полезно узнать каждому веб-разработчику. Надеюсь, что хоть с парочкой из трюков я вас познакомлю первым!

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

Можно стилизовать ссылки разными методами; один из способов это сделать — приписать ко внешним ссылкам специализированный класс.

Но это громоздко и ненужно, поскольку для простых задач можно и не создавать лишний класс.
Рассмотрим CSS-селектор:

Селектор принимает все те a теги, атрибут href которых содержит две косые черты (для фильтрации относительных URL-адресов) и не содержит URL-адреса вашего веб-сайта. То есть, фильтр проходят только внешние ссылки.
Просто, неправда ли?!

2. Легкий подсчет

Наверное, console.log вы уже много раз использовали. Но знали ли вы о других, более полезных для отладки функциях?

В приведенном выше примере массив names содержит пять имен. Функция count вызывается каждый цикл, поэтому счетчик вернет 5.

3. Углы

4. Подписи и субтитры

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

Атрибут label определяет заголовок текстовой дорожки. Атрибут kind указывает тип текстовой дорожки и может иметь одно из следующих значений: заголовки, главы, описания, метаданные или субтитры. Атрибут srclang определяет язык текста дорожки и является обязательным, если атрибут kind это субтитры.

5. Динамические свойства

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

Приятно знать, что в ES6 можно комбинировать динамические свойства с интерполяцией.

Давайте рассмотрим следующий пример, в котором мы добавили дополнительное свойство к объекту person с помощью интерполяции:

Последний способ добавить динамическое свойство к объекту — определить его так же, как при добавлении пары ключ-значение в массив:

Большое преимущество этого метода — он позволяет добавлять динамические свойства не только при объявлении объекта; такой способ часто комбинируется с оператором if :

6. Стилизация необязательных и обязательных элементов ввода.

Вот как это выглядит:

7. Список, разделенный запятыми.

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

Вот как выглядит результат:

8. Уникальные значения массива

Источник

Статические анализаторы JavaScript и ошибки, от которых они помогут отучиться (Часть 1)

Далеко не каждая строка моего кода получается идеальной с первого же раза. Ну, в некоторых случаях… Иногда… Ладно – практически никогда. Правда заключается в том, что я трачу значительно больше времени на исправление своих собственных глупых ошибок, чем мне хотелось бы. Именно поэтому я использую статические анализаторы практически в каждом написанном мной файле JavaScript.

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

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

JSLint, JSHint и Closure Compiler

Есть три основных варианта статических анализаторов для JavaScript: JSLint, JSHint и Closure Compiler.

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

JSLint показывает в этом коде две ошибки:

Первая проблема – это определение переменной i в условиях цикла. JSLint также не принимает оператор ++ в конце определения цикла. Он хочет, чтобы код выглядел следующим образом:

Я ценю создателей JSLint, но как по мне – это перебор. Он оказался жестким и для Антона Ковалева, поэтому он создал JSHint.

JSHint работает так же, как и JSLint, но он написан в дополнение к Node.js, а потому он более гибкий. JSHint включает большое количество опций, что позволяет выполнять пользовательские проверки путем написания своего собственного генератора отчетов.
Запустить JSHint можно с сайта, но в большинстве случаев лучше установить JSHint в качестве локального инструмента командной строки с помощью Node.js. Как только вы установите JSHint, его можно запустить в ваших файлах с помощью такой команды:

JSHint также включает плагины для популярных текстовых редакторов, поэтому его можно запускать в процессе написания кода.

Closure Compiler от Google – это совсем другая разновидность программы. Как предполагает его название, он представляет собой не только программу для проверки, но и компилятор. Он написан на Java и основан на анализаторе Rhino от Mozilla. Closure Compiler включает простой режим для выполнения базовой проверки кода, и более сложные режимы, позволяющие выполнять дополнительную проверку и обеспечивать соблюдение определений отдельных видов.

Closure Compiler сообщает об ошибках в коде JavaScript, но также создает минимизированные версии JavaScript. Компилятор удаляет пустое пространство, комментарии и неиспользуемые переменные и упрощает длинные выражения, делая скрипт максимально компактным.

Google сделал очень простую версию компилятора, доступную в сети, но скорее всего, вы захотите скачать Closure Compiler и запустить его локально.

Closure Compiler после проверки кода выводит список файлов в один минимизированный файл. Таким образом, вы можете запустить его, скачав файл compiler.jar.

Выбираем правильную программу проверки

В своих проектах я комбинирую Closure Compiler и JSHint. Closure Compiler выполняет минимизацию и базовую проверку, в то время как JSHint проводит более сложный анализ кода. Эти две программы отлично работают вместе, и каждая из них охватывает те области, которые не может охватить другая. Кроме того, я могу использовать возможности расширения JSHint, чтобы писать пользовательские программы проверки. Одна написанная мной общая программа проверяет определенные функции, которые мне не нужны, например вызов функций, которых не должно быть в моем проекте.

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

В этой статье для большинства примеров используется JSHint, но Closure Compiler обычно выдает похожие предупреждения.

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

JavaScript предлагает два оператора сравнения для управления такими динамическими типами: == и ===. Давайте рассмотрим это на примере.

Оператор сравнения == — это остатки языка С, в который JavaScript уходит корнями. Его использование практически всегда является ошибкой: сравнивание значений отдельно от типов редко является тем, что разработчик на самом деле хочет сделать. На самом деле, число «сто двадцать три» отличается от строки «один два три». Эти операторы легко неправильно написать и еще легче неправильно прочесть. Проверьте этот код с помощью JSHint и вы получите следующее:

Неопределенные переменные и поздние определения

Давайте начнем с простого кода:

Видите баг? Я совершаю эту ошибку каждый раз. Запустите этот код, и вы получите ошибку:

Давайте сделаем проблему немного более сложной:

Запустите этот код, и вы получите следующее:

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

Во втором случае он сообщит такое:

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

Проблема второго примера коварно незаметная и сложная. Переменная myVar теперь исчезла из своей области видимости и поднялась в глобальную область. Это означает, что она будет существовать и иметь значение Hello, World даже после запуска функции test. Это называется «загрязнение глобальной области видимости».

Переменная myVar будет существовать для каждой другой функции, которая будет запущена после функции test. Запустите следующий код после того, как выполните функцию test:

Вы все равно получите Hello, World. Переменная myVar будет висеть по всему вашему коду как шаблон, который приводит к сложным багам, которые вы будете искать всю ночь перед релизом, а все потому, что вы забыли вписать var.

Источник

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

Проверь себя

Вот список интересных выражений, о которых мы только что говорили:

Тут полно такого, что выглядит более чем странно, но без проблем работает в JS, задействуя неявное приведение типов. В подавляющем большинстве случаев неявного приведения типов в JS лучше всего избегать. Рассматривайте этот список как упражнение для проверки ваших знаний о том, как работает приведение типов в JavaScript. Если же тут для вас ничего нового не нашлось — загляните на wtfjs.com.


JavaScript полон странностей

Неявное преобразование типов и явное преобразование типов

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

Три вида преобразования типов

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

Примитивные типы данных

▍Преобразование к типу String

Все примитивные типы преобразуются в строки вполне естественным и ожидаемым образом:

В случае с типом Symbol дело несколько усложняется, так как значения этого типа можно преобразовать к строковому типу только явно. Здесь можно почитать подробности о правилах преобразования типа Symbol.

▍Преобразование к типу Boolean

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

▍Преобразование к типу Number

Неявное приведение значения к числовому типу — тема более сложная, так как оно применяется, пожалуй, чаще чем преобразование в строку или в логическое значение. А именно, преобразование к типу Number выполняют следующие операторы:

Вот как в числа преобразуются примитивные значения:

Вот два особых правила, которые стоит запомнить:

При применении оператора == к null или undefined преобразования в число не производится. Значение null равно только null или undefined и не равно ничему больше.

Значение NaN не равно ничему, включая себя. В следующем примере, если значение не равно самому себе, значит мы имеем дело с NaN

Преобразование типов для объектов

Вот псевдо-реализация метода [[ToPrimitive]] :

В целом, работа алгоритма выглядит следующим образом:

Вот пример поведения Date при преобразовании типов:

Стандартные методы toString() и valueOf() можно переопределить для того, чтобы вмешаться в логику преобразования объекта в примитивные значения.

Метод Symbol.toPrimitive ES6

Разбор примеров

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

Разберём каждый из этих примеров.

▍true + false

Оператор + с двумя операндами вызывает преобразование к числу для true и false :

▍12 / ‘6’

▍«number» + 15 + 3

▍15 + 3 + «number»

▍[1] > null

Оператор сравнения > выполняет числовое сравнение [1] и null :

▍«foo» + + «bar»

▍’true’ == true и false == ‘false’

▍[] + null + 1

Логические операторы || и && в процессе работы приводят значение операндов к логическому типу, но возвращают исходные операнды (которые имеют тип, отличный от логического). Значение 0 ложно, а значение ‘0’ истинно, так как является непустой строкой. Пустой объект <> так же преобразуется к истинному значению.

▍[1,2,3] == [1,2,3]

Этот пример лучше объяснить пошагово в соответствии с порядком выполнения операций.

▍new Date(0) — 0

▍new Date(0) + 0

Итоги

Преобразование типов — это один из базовых механизмом JavaScript, знание которого является основой продуктивной работы. Надеемся, сегодняшний материал помог тем, кто не очень хорошо разбирался в неявном преобразовании типов, расставить всё по своим местам, а тем, кто уверенно, с первого раза, никуда не подсматривая, смог решить «вступительную задачу», позволил вспомнить какой-нибудь интересный случай из их практики.

Уважаемые читатели! А в вашей практике случалось так, чтобы путаница с неявным преобразованием типов в JavaScript приводила к таинственным ошибкам?

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • что такое хинное дерево
  • что такое хинкали фото
  • что такое хинкали и как их едят
  • что такое хинкали и как их готовить
  • что такое хинкали блюдо

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии