Use 0 in the console to refer to this element что это
Хитрый вопрос по JavaScript, который задают на собеседованиях в Google и Amazon
Привет Хабр! Есть один вопрос, с виду — не такой уж и сложный, который нередко задают разработчикам на собеседованиях.
Сегодня мы его разберём и поговорим о подходах к поиску ответа. Задавая вопрос, о котором идёт речь, интервьюер предлагает рассказать о том, что выведет примерно такой код:
А вы знаете, что появится в консоли?
Сразу хочется сказать, что этот вопрос направлен на понимание таких механизмов JS, как замыкания, области видимости и функция setTimeout. Правильный ответ выглядит так:
Если вы ожидали чего-то другого, надеемся, в этом материале мы сможем рассказать о том, почему вывод этого фрагмента кода оказался именно таким, и о том, как привести его в более приличный вид.
Почему этот вопрос так популярен?
Один пользователь Reddit рассказал о том, что ему задавали такой вопрос на собеседовании в Amazon. Я и сам сталкивался с подобными вопросами, направленными на понимание циклов и замыканий в JS, даже на собеседовании в Google.
Этот вопрос позволяет проверить владение некоторыми важными концепциями JavaScript. Учитывая особенности работы JS, ситуация, которая смоделирована в представленном фрагменте кода, нередко может возникать и в ходе реальной работы. В частности, это касается использования setTimeout или какой-нибудь другой асинхронной функции в цикле.
Хорошее понимание функциональных и блочных областей видимости в JavaScript, особенностей устройства анонимных функций, замыканий и IIFE, поможет вашему профессиональному росту и позволит показать себя с хорошей стороны на собеседованиях.
Подходы к ответу на вопрос и к избавлению от undefined
Первый предусматривает передачу необходимого параметра во внутреннюю функцию, второй основан на использовании возможностей ES6.
Итак, вот первый вариант:
Вот второй вариант:
На Reddit мне удалось найти похожий ответ на этот вопрос. Вот — хорошее разъяснение особенностей замыканий на StackOverflow.
Итоги
Можно отметить, что вопрос, с которого мы начали этот материал, часто сбивает с толку людей, обладающих небольшим опытом в области JavaScript или в функциональном программировании. Причина заключается в непонимании сущности замыканий. При формировании замыкания не выполняет передача значения переменной или ссылки на неё. Замыкание захватывает саму переменную.
Уважаемые читатели! Знаете ли вы интересные вопросы, которые задают на собеседованиях по JavaScript? Если да — просим поделиться.
Работа с DOM из консоли
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-nodes.
Исследовать и изменять DOM можно с помощью инструментов разработки, встроенных в браузер. Посмотрим средства для этого на примере Google Chrome.
Доступ к элементу
Откройте документ losi.html и, в инструментах разработчика, перейдите во вкладку Elements.
Чтобы проанализировать любой элемент:
Справа будет различная информация об элементе:
Отображение DOM во вкладке Elements не совсем соответствует реальному. В частности, там не отображаются пробельные узлы. Это сделано для удобства просмотра. Но мы-то знаем, что они есть.
Зачастую бывает нужно выбрать элемент DOM и сделать с ним что-то на JavaScript.
Находясь во вкладке Elements, откройте консоль нажатием Esc (или перейдите на вкладку Console).
Запустите на элементе команду, которая делает его красным:
В браузере это может выглядеть примерно так:
Мы выделили элемент, применили к нему JavaScript в консоли, тут же увидели изменения в браузере.
Есть и обратная дорожка. Любой элемент из JS-переменной можно посмотреть во вкладке Elements, для этого:
Таким образом, можно легко перемещаться из Elements в консоль и обратно.
Ещё методы консоли
Для поиска элементов в консоли есть два специальных метода:
Более полная документация по методам консоли доступна на страницах Console API Reference для Chrome и Command Line API для Firebug, а также на firebug.ru.
Другие браузеры реализуют похожую функциональность, освоив Chrome/Firebug, вы легко с ними разберётесь.
Use 0 in the console to refer to this element что это
You may use the @var tag to document the Type of the following Structural Elements:
Syntax
Description
The @var tag defines which Type of data is represented by the value of a constant, property or variable.
Each constant or property definition or variable where the Type is ambiguous or unknown SHOULD be preceded by a DocBlock containing the @var tag. Any other variable MAY be preceded with a DocBlock containing the @var tag.
The @var tag MUST contain the name of the element it documents. An exception to this is when a declaration only refers to a single property or constant. In that case, the name of the property or constant MAY be omitted.
The name is used when compound statements are used to define a series of constants or properties. Such a compound statement can only have one DocBlock while several items are represented.
Effects in phpDocumentor
Constants, properties and global variables, that are tagged with the @var tag, will have their Type displayed in their signature.
If the Type is a class that is documented by phpDocumentor, then a link to that class’ documentation is provided.
Examples
Another example is to document the variable in a foreach explicitly; many IDEs use this information to help you with auto-completion:
Even compound class constant and property statements may be documented:
Ошибки в JavaScript и как их исправить
JavaScript может быть кошмаром при отладке: некоторые ошибки, которые он выдает, могут быть очень трудны для понимания с первого взгляда, и выдаваемые номера строк также не всегда полезны. Разве не было бы полезно иметь список, глядя на который, можно понять смысл ошибок и как исправить их? Вот он!
Ниже представлен список странных ошибок в JavaScript. Разные браузеры могут выдавать разные сообщения об одинаковых ошибках, поэтому приведено несколько примеров там, где возможно.
Как читать ошибки?
Перед самим списком, давайте быстро взглянем на структуру сообщения об ошибке. Понимание структуры помогает понимать ошибки, и вы получите меньше проблем, если наткнетесь на ошибки, не представленные в этом списке.
Типичная ошибка из Chrome выглядит так:
Теперь к самим ошибкам.
Uncaught TypeError: undefined is not a function
Связанные ошибки: number is not a function, object is not a function, string is not a function, Unhandled Error: ‘foo’ is not a function, Function Expected
Возникает при попытке вызова значения как функции, когда значение функцией не является. Например:
Эта ошибка обычно возникает, если вы пытаетесь вызвать функцию для объекта, но опечатались в названии.
Другие вариации, такие как “number is not a function” возникают при попытке вызвать число, как будто оно является функцией.
Как исправить ошибку: убедитесь в корректности имени функции. Для этой ошибки, номер строки обычно указывает в правильное место.
Uncaught ReferenceError: Invalid left-hand side in assignment
Связанные ошибки: Uncaught exception: ReferenceError: Cannot assign to ‘functionCall()’, Uncaught exception: ReferenceError: Cannot assign to ‘this’
Вызвано попыткой присвоить значение тому, чему невозможно присвоить значение.
Наиболее частый пример этой ошибки — это условие в if:
В этом примере программист случайно использовал один знак равенства вместо двух. Выражение “left-hand side in assignment” относится к левой части знака равенства, а, как можно видеть в данном примере, левая часть содержит что-то, чему нельзя присвоить значение, что и приводит к ошибке.
Uncaught TypeError: Converting circular structure to JSON
Связанные ошибки: Uncaught exception: TypeError: JSON.stringify: Not an acyclic Object, TypeError: cyclic object value, Circular reference in value argument not supported
Так как a и b в примере выше имеют ссылки друг на друга, результирующий объект не может быть приведен к JSON.
Как исправить ошибку: удалите циклические ссылки, как в примере выше, из всех объектов, которые вы хотите сконвертировать в JSON.
Unexpected token ;
Связанные ошибки: Expected ), missing ) after argument list
Интерпретатор JavaScript что-то ожидал, но не обнаружил там этого. Обычно вызвано пропущенными фигурными, круглыми или квадратными скобками.
Токен в данной ошибке может быть разным — может быть написано “Unexpected token ]”, “Expected <” или что-то еще.
Как исправить ошибку: иногда номер строки не указывает на правильное местоположение, что затрудняет исправление ошибки.
Ошибка с [ ] < >( ) обычно вызвано несовпадающей парой. Проверьте, все ли ваши скобки имеют закрывающую пару. В этом случае, номер строки обычно указывает на что-то другое, а не на проблемный символ.
Unexpected / связано с регулярными выражениями. Номер строки для данного случая обычно правильный.
Unexpected; обычно вызвано символом; внутри литерала объекта или массива, или списка аргументов вызова функции. Номер строки обычно также будет верным для данного случая.
Uncaught SyntaxError: Unexpected token ILLEGAL
Связанные ошибки: Unterminated String Literal, Invalid Line Terminator
В строковом литерале пропущена закрывающая кавычка.
Как исправить ошибку: убедитесь, что все строки имеют правильные закрывающие кавычки.
Uncaught TypeError: Cannot read property ‘foo’ of null, Uncaught TypeError: Cannot read property ‘foo’ of undefined
Связанные ошибки: TypeError: someVal is null, Unable to get property ‘foo’ of undefined or null reference
Попытка прочитать null или undefined так, как будто это объект. Например:
Как исправить ошибку: обычно вызвано опечатками. Проверьте, все ли переменные, использованные рядом со строкой, указывающей на ошибку, правильно названы.
Uncaught TypeError: Cannot set property ‘foo’ of null, Uncaught TypeError: Cannot set property ‘foo’ of undefined
Связанные ошибки: TypeError: someVal is undefined, Unable to set property ‘foo’ of undefined or null reference
Попытка записать null или undefined так, как будто это объект. Например:
Как исправить ошибку: это тоже обычно вызвано ошибками. Проверьте имена переменных рядом со строкой, указывающей на ошибку.
Uncaught RangeError: Maximum call stack size exceeded
Связанные ошибки: Uncaught exception: RangeError: Maximum recursion depth exceeded, too much recursion, Stack overflow
Обычно вызвано неправильно программной логикой, что приводит к бесконечному вызову рекурсивной функции.
Как исправить ошибку: проверьте рекурсивные функции на ошибки, которые могут вынудить их делать рекурсивные вызовы вечно.
Uncaught URIError: URI malformed
Связанные ошибки: URIError: malformed URI sequence
Как исправить ошибку: убедитесь, что вызовы decodeURIComponent на строке ошибки получают корректные входные данные.
XMLHttpRequest cannot load some/url. No ‘Access-Control-Allow-Origin’ header is present on the requested resource
Связанные ошибки: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at some/url
Эта проблема всегда связана с использованием XMLHttpRequest.
Как исправить ошибку: убедитесь в корректности запрашиваемого URL и в том, что он удовлетворяет same-origin policy. Хороший способ найти проблемный код — посмотреть на URL в сообщении ошибки и найти его в своём коде.
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
Связанные ошибки: InvalidStateError, DOMException code 11
Означает то, что код вызвал функцию, которую нельзя было вызывать в текущем состоянии. Обычно связано c XMLHttpRequest при попытке вызвать на нём функции до его готовности.
Как исправить ошибку: посмотрите на код в строке, указывающей на ошибку, и убедитесь, что он вызывается в правильный момент или добавляет нужные вызовы до этого (как с xhr.open ).
Заключение
JavaScript содержит в себе одни из самых бесполезных ошибок, которые я когда-либо видел, за исключением печально известной Expected T_PAAMAYIM_NEKUDOTAYIM в PHP. Большая ознакомленность с ошибками привносит больше ясности. Современные браузеры тоже помогают, так как больше не выдают абсолютно бесполезные ошибки, как это было раньше.
Какие самые непонятные ошибки вы встречали? Делитесь своими наблюдениями в комментариях.
The Complete Guide to useRef() and Refs in React
In this post you’ll learn how to use React.useRef() hook to create persisted mutable values (also known as references or refs), as well as access DOM elements.
Table of Contents
reference.current accesses the reference value, and reference.current = newValue updates the reference value. Pretty simple.
There are 2 rules to remember about references:
Now, let’s see how to use useRef() in practice.
1.1 Use case: logging button clicks
The component LogButtonClicks uses a reference to store the number of clicks on a button:
Updating the reference value countRef.current++ doesn’t trigger component re-rendering. This is demonstrated by the fact that ‘I rendered!’ is logged to the console just once, at initial rendering, and no re-rendering happens when the reference is updated.
Now a reasonable question: what’s the main difference between references and state?
Reference and state diff
Let’s reuse the component LogButtonClicks from the previous section, but this time use useState() hook to count the number of button clicks:
Open the demo and click the button. Each time you click, you will see in the console the message ‘I rendered!’ — meaning that each time the state is updated, the component re-renders.
So, the 2 main differences between references and state:
From a higher point of view, references store infrastructure data of side-effects, while the state stores information that is directly rendered on the screen.
1.2 Use case: implementing a stopwatch
You can store inside a reference infrastructure data of side effects. For example, you can store into reference pointers: timer ids, socket ids, etc.
The component Stopwatch uses setInterval(callback, time) timer function to increase each second the counter of a stopwatch. The timer id is stored into a reference timerIdRef :
Additionally, if the component unmounts with the stopwatch active, the cleanup function of useEffect() is going to stop the timer too.
In the stopwatch example, the reference was used to store the infrastructure data — the active timer id.
Side challenge: can you improve the stopwatch by adding a Reset button? Share your solution in a comment below!
2. Accessing DOM elements
Another useful application of the useRef() hook is to access DOM elements. This is performed in 3 steps:
2.1 Use case: focusing an input
You would need to access DOM elements, for example, to focus on the input field when the component mounts.
To make it work you’ll need to create a reference to the input, assign the reference to ref attribute of the tag, and after mounting call the special method element.focus() on the element.
Here’s a possible implementation of the component:
const inputRef = useRef() creates a reference to hold the input element.
Ref is null on initial rendering
During initial rendering, the reference supposed to hold the DOM element is empty:
During initial rendering React still determines what is the output of the component, so there’s no DOM structure created yet. That’s why inputRef.current evaluates to undefined during initial rendering.
useEffect(callback, []) hook invokes the callback right after mounting, when the input element has already been created in DOM.
callback function of the useEffect(callback, []) is the right place to access inputRef.current because it is guaranteed that the DOM is constructed.
3. Updating references restriction
The function scope of the functional component should either calculate the output or invoke hooks.
That’s why updating a reference (as well as updating state) shouldn’t be performed inside the immediate scope of the component’s function.
The reference must be updated either inside a useEffect() callback or inside handlers (event handlers, timer handlers, etc).
useRef() hook creates references.
Between the component re-renderings, the value of the reference is persistent.
Updating a reference, contrary to updating state, doesn’t trigger component re-rendering.
References can also access DOM elements. Assign the reference to ref attribute of the element you’d like to access:
Want to improve you React knowledge further? Follow A Simple Explanation of React.useEffect().