<p><strong>Ответ: <code>1, -1</code>.</strong></p>
<p>Непустой массив не содержит своего элемента:</p>
<pre class="language-javascript"><code>const a = [,];
const len = a.length; // 1, какой-то элемент существует
const index = a.indexOf(a[0]); // -1, у нас есть массив с ненулевой длиной, который не содержит своего первого элемента. Что за черт?</code></pre>
<h4>В чем же проблема?</h4>
<p><code>a[0]</code> это <code>undefined</code>. <code>undefined</code> является примитивным типом javascript. Но когда мы инициализируем массив, спецификация ES5 сообщает нам следующее об <a href="https://es5.github.io/#x11.1.4" target="_blank" rel="noopener">инициализаторах массива</a>:</p>
<pre class="language-html"><code>Elided array elements are not defined.
...
The missing array element contributes to the length of the Array and increases the index of subsequent elements.</code></pre>
<p>Здесь нет <code>undefined</code>-элементов, они являются <code>not initialized</code>. Когда мы вызываем <code>indexOf</code> у массива, один из шагов, который происходит:</p>
<pre class="language-html"><code>Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument ToString(k).</code></pre>
<p>В нем <code>k</code> число, соответствующее индексу массива, и <code>O</code> сам массив. Поскольку исключенные элементы не были определены, массив не имеет свойства для соответствующего индекса.</p>
<h4>Ладно, но почему мы получаем <code>undefined</code> при вызове первого элемента массива?</h4>
<p>JavaScript - это язык сценариев, основанный на прототипах, и <code>Array</code> тоже является объектом. Итак, если в массиве нет свойства <code>0</code>, внутренний движок переходит глубже к прототипу, и если в цепочке прототипов такого свойства нет - <code>return undefined</code>. Когда мы пытаемся получить доступ к свойству <code>value</code>, <code>0</code> элемента массива, вызывается внутренний метод <code>[[GetProperty]]</code>. Если такого свойства нет, мы пытаемся получить его из цепочки прототипов. В конечно итоге, мы получаем <code>undefined</code> если поиск останавливается на <code>null</code> (конец цепочки прототипов).</p>
<p><strong>Ответ: <code>1, -1</code>.</strong></p>
<p>Непустой массив не содержит своего элемента:</p>
<pre class="language-javascript"><code>const a = [,];
const len = a.length; // 1, какой-то элемент существует
const index = a.indexOf(a[0]); // -1, у нас есть массив с ненулевой длиной, который не содержит своего первого элемента. Что за черт?</code></pre>
<h4>В чем же проблема?</h4>
<p><code>a[0]</code> это <code>undefined</code>. <code>undefined</code> является примитивным типом javascript. Но когда мы инициализируем массив, спецификация ES5 сообщает нам следующее об <a href="https://es5.github.io/#x11.1.4" target="_blank" rel="noopener">инициализаторах массива</a>:</p>
<pre class="language-html"><code>Elided array elements are not defined.
...
The missing array element contributes to the length of the Array and increases the index of subsequent elements.</code></pre>
<p>Здесь нет <code>undefined</code>-элементов, они являются <code>not initialized</code>. Когда мы вызываем <code>indexOf</code> у массива, один из шагов, который происходит:</p>
<pre class="language-html"><code>Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument ToString(k).</code></pre>
<p>В нем <code>k</code> число, соответствующее индексу массива, и <code>O</code> сам массив. Поскольку исключенные элементы не были определены, массив не имеет свойства для соответствующего индекса.</p>
<h4>Ладно, но почему мы получаем <code>undefined</code> при вызове первого элемента массива?</h4>
<p>JavaScript - это язык сценариев, основанный на прототипах, и <code>Array</code> тоже является объектом. Итак, если в массиве нет свойства <code>0</code>, внутренний движок переходит глубже к прототипу, и если в цепочке прототипов такого свойства нет - <code>return undefined</code>. Когда мы пытаемся получить доступ к свойству <code>value</code>, <code>0</code> элемента массива, вызывается внутренний метод <code>[[GetProperty]]</code>. Если такого свойства нет, мы пытаемся получить его из цепочки прототипов. В конечно итоге, мы получаем <code>undefined</code> если поиск останавливается на <code>null</code> (конец цепочки прототипов).</p>
Ниже представлено пояснение.
Ответ: 1, -1
.
Непустой массив не содержит своего элемента:
const a = [,];
const len = a.length; // 1, какой-то элемент существует
const index = a.indexOf(a[0]); // -1, у нас есть массив с ненулевой длиной, который не содержит своего первого элемента. Что за черт?
В чем же проблема?
a[0]
это undefined
. undefined
является примитивным типом javascript. Но когда мы инициализируем массив, спецификация ES5 сообщает нам следующее об инициализаторах массива:
Elided array elements are not defined.
...
The missing array element contributes to the length of the Array and increases the index of subsequent elements.
Здесь нет undefined
-элементов, они являются not initialized
. Когда мы вызываем indexOf
у массива, один из шагов, который происходит:
Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument ToString(k).
В нем k
число, соответствующее индексу массива, и O
сам массив. Поскольку исключенные элементы не были определены, массив не имеет свойства для соответствующего индекса.
Ладно, но почему мы получаем undefined
при вызове первого элемента массива?
JavaScript - это язык сценариев, основанный на прототипах, и Array
тоже является объектом. Итак, если в массиве нет свойства 0
, внутренний движок переходит глубже к прототипу, и если в цепочке прототипов такого свойства нет - return undefined
. Когда мы пытаемся получить доступ к свойству value
, 0
элемента массива, вызывается внутренний метод [[GetProperty]]
. Если такого свойства нет, мы пытаемся получить его из цепочки прототипов. В конечно итоге, мы получаем undefined
если поиск останавливается на null
(конец цепочки прототипов).