jsliang Job Search Series — 01 — Основы JavaScript

JavaScript Поиск работы

каталог

Чем отличается передок без закидывания от соленой рыбы?

содержание
каталог
2 Предисловие
Три широко используемых API DOM
Четыре различия между null и undefined
Пять потоков событий
5.1 addEventListener
5.2 Принцип
5.3 Случаи
5.4 Практические вопросы
5.5 Перестаньте пузыриться
5.6 Разница между onmouseover и onmouseenter
5.7 Популярная наука
Шесть различий между typeof и instanceof
Семь одно предложение, описывающее это
Восемь позиций JS
Перетаскивание девяти JS
10 setTimeout реализует setInterval
Одиннадцать достичь сна
12 Контекст выполнения
12.1 Типы контекста выполнения
12.2 Стек выполнения
Тринадцать функциональных программ
13.1 Особенности функционального программирования
13.2 Чистые функции
14 прогрессивных веб-приложений (PWA)
14.1 Преимущества
14.2 Недостатки
15 Нормализация
15.1 Спецификация CommonJS
15.2 Технические характеристики AMD
15.3 Спецификации CMD
15.4 Спецификация модулей ES6
Шестнадцать принципов компиляции Babel
Семнадцать вопросов
17.1 Общие API для массивов
17.2 Общие API-интерфейсы DOM
17.3 Дедупликация массива
17.4 Оцифрованные суммы
17.5 Проблемы обхода
17.6 setTimeout
17.7 requestAnimationFrame
17.8 Временная зона нечувствительности
17.9 Вывод результата печати
17.10 Вывод результата печати
17.11 Event Loop
17.12 Вывод результата печати
17.13 Сделать == 1 && a == 2 истинным
Еще восемнадцать

2 Предисловие

Назад к содержанию

В процессе проверки JavaScript вы можете столкнуться с:

  1. nullа такжеundefinedразница?
  2. addEventListenerфункция?

Такие разные вопросы илиa == 1 && a == 2Такой интересный вопрос.

Классифицируйте их по основам JavaScript и опишите их все в этой статье.

При этом будет более десятка простых вопросов для отработки рук.

Три широко используемых API DOM

Назад к содержанию

можно использоватьdocumentилиwindowAPI элемента для управления самим документом или получения подклассов документа (различных элементов на веб-странице).

// 获取元素
const node = document.getElementById(id); // 或者 querySelector(".class|#id|name");

// 创建元素
const heading = document.createElement(name); // name: p、div、h1...
heading.innerHTML = '';

// 添加元素
document.body.appendChild(heading);

// 删除元素
document.body.removeChild(node);

Пример:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>DOM 操作</title>
  <style>
    div {
      border: 1px solid #ccc;
      padding: 50px;
      width: 100px;
    }
  </style>
</head>
<body>
  <div id="dom1">元素 1</div>
  <div class="dom2">元素 2</div>
  
  <button class="btn">点我</button>

  <script>
    (function() {
      const btn = document.querySelector('.btn');

      // 注册点击事件
      btn.onclick = function() {
        const dom1 = document.getElementById('dom1');

        // 第一种添加元素
        const newDom1 = document.createElement('p');
        newDom1.innerHTML = '<a href="https://github.com/LiangJunrong/document-library">jsliang 的文档库</a>';
        dom1.appendChild(newDom1);

        // 第二种添加元素
        const newDom2 = document.createElement('ul');
        newDom2.innerHTML = `
          <li>aaa</li>
          <li>bbb</li>
        `;
        document.body.appendChild(newDom2);

        // 移除元素
        const dom2 = document.querySelector('.dom2');
        document.body.removeChild(dom2);
      }
    })()
  </script>
</body>
</html>

Четыре различия между null и undefined

Назад к содержанию

Сценарии использования разбиты следующим образом:

  • null:
  1. Number(null)получать0.
  2. В качестве аргумента функции это означает, что аргумент функции не является объектом.
  3. как конец цепочки прототипов объектов.Object.prototype.__proto__ === null.
  • undefined:
  1. Number(undefined)получатьNaN.
  2. Переменная объявлена, но ей не присвоено значение, равноеundefined.
  3. При вызове функции соответствующий параметр не предоставляется, такжеundefined.
  4. Объекту не присваивается значение, значение этого свойства равноundefined.
  5. Функция не имеет возвращаемого значения, она возвращает значение по умолчаниюundefined.

Пять потоков событий

Назад к содержанию

Что такое поток событий. Поток событий описывает порядок, в котором события поступают со страницы.DOM 2Поток событий уровня включает следующие этапы.

  • этап захвата событий
  • на целевой стадии
  • фаза всплытия события

Как сначала сделать пузырь события, а потом поймать:

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

5.1 addEventListener

Назад к содержанию

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

addEventListenerЦелью события может быть элемент в документеElement,Documentа такжеWindowили любой другой объект, который поддерживает события (например,XMLHttpRequest).

Справочная документация: [EventTarget.addEventListener - MDN][developer.Mozilla.org/this-cn/docs/…]

  • грамматика:target.addEventListener(type, listener, options/useCapture)
  1. type: строка, представляющая тип события прослушивания.
  2. listener: Отслеживаемое событие запускается и получает объект уведомления о событии.
  3. options: обозначение, связанное сlistenerНеобязательный объект параметра для свойства. Необязательные значенияcapture(Фаза захвата события распространяется на этот триггер),once(существуетlistenerПосле добавления значение вызывается не более одного раза),passive(Установить какtrueвремяlistenerникогда не звониpreventDefault()).
  4. useCapture: В дереве DOM зарегистрированыlistener, следует ли предшествовать элементу под нимEventTargetназовите этоlistener.

addEventListenerТретий параметр включает всплытие и захват, дляtrueзахвачен, дляfalseпри бульканье.

или объект{ passive: true }, дляSafariБраузер, используемый при отключении/включении прокрутки

  • Пример
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>监听器</title>
</head>
<body>
  <table id="outside">
    <tr><td id="t1">one</td></tr>
    <tr><td id="t2">two</td></tr>
  </table>

  <script>
    (function() {
      // 添加函数
      const modifyText = (text) => {
        const t2 = document.querySelector('#t2');
        if (t2.firstChild.nodeValue === text) {
          t2.firstChild.nodeValue = 'two';
        } else {
          t2.firstChild.nodeValue = text;
        }
      }

      // 给 Table 添加事件监听器
      const element = document.querySelector('#outside');
      element.addEventListener('click', function() { modifyText('four') }, false);
    })()
  </script>
</body>
</html>

Как и выше, этот пример просто реализует щелчокtwoпереключиться наfour, нажмитеfourпереключиться наtwoЭффект.

5.2 Принцип

Назад к содержанию

Захват событий и пузырь событийНетскейп(Нетскейп) иIEправильноDOMОписание порядка, в котором произошли события.

НетскейпдуматьDOMПолученное событие должно быть сначалаwindow, затем кdocument, затем спускаемся слой за слоем, и, наконец, конкретный элемент получает событие, т.е.захват событий.

IEдумаю, чтоDOMСобытия должны сначала приниматься конкретными элементами, затем слой за слоем, а затемdocument, наконец, прибылwindow,Прямо сейчасвсплывающее окно события.

наконецW3CОбе схемы унифицированы:DOMСобытия делятся на две фазы: захват событий и всплывающая всплывающая подсказка.

Когда элемент щелкнут, первая фаза захвата события,windowСобытие сначала принимается, затем захватывается слой за слоем и, наконец, принимается конкретным элементом; затем конкретный элемент всплывает слой за слоем, покаwindowПолучать события.

так:

  • всплывающее окно события: когда событие привязано к целевому элементу, событие будет срабатывать в его родительском элементе по очереди (при условии, конечно, что родительский элемент также имеет событие с таким же именем, например, и дочерний элемент, и исходный элемент). родительский элемент привязан к диапазонуclickСобытие запускает родительский элементclick).
  • захват событий: Вопреки пузыриться, он будет передан от верхнего слоя до нижнего слоя.

5.3 Случаи

Назад к содержанию

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

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>自定义事件</title>
</head>
<body>
  <ul class="ul">
    <li class="li">
      <button class="btn">点我</button>
    </li>
  </ul>
  
  <script>
    window.onload = function() {
      const myEvent = document.createEvent('CustomEvent');
      myEvent.initEvent('myEvent', true, true);

      const btn = document.querySelector('.btn');
      btn.addEventListener('myEvent', function(e) {
        console.log('button');
      })

      const li = document.querySelector('.li');
      li.addEventListener('myEvent', (e) => {
        console.log('li');
      })

      const ul = document.querySelector('.ul');
      li.addEventListener('myEvent', (e) => {
        console.log('ul');
      })

      document.addEventListener('myEvent', (e) => {
        console.log('document');
      })

      window.addEventListener('myEvent', (e) => {
        console.log('window');
      })

      setTimeout(() => {
        btn.dispatchEvent(myEvent);
      }, 2000);
    };
  </script>
</body>
</html>

Следующий порядок вывода Chrome:button -> li -> ul -> document -> window

Если это захват, то все наоборот.

5.4 Практические вопросы

Назад к содержанию

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

const text = document.getElementById('text');

text.onclick = function (e) {
  console.log('onclick')
}
text.onfocus = function (e) {
  console.log('onfocus')
}
text.onmousedown = function (e) {
  console.log('onmousedown')
}
text.onmouseenter = function (e) {
  console.log('onmouseenter')
}

Правильный порядок:onmouseenter -> onmousedown -> onfocus -> onclick.

Если вы добавитеonmouseup,То есть:

  • onmouseenter -> onmousedown -> onfocus -> onmouseup -> onclick

5.5 Перестаньте пузыриться

Назад к содержанию

  • event.stopPropagation();
btn.addEventListener('myEvent', function(e) {
  console.log('button');
  event.stopPropagation();
})

Предотвращая всплытие, программа будет выводить толькоbutton, вместо того, чтобы продолжать выводитьliЖдать.

5.6 Разница между onmouseover и onmouseenter

Назад к содержанию

Оба срабатывают при движении, ноonmouseoverбудет срабатывать несколько раз, в то время какonmouseenterСрабатывает только при входе.

5.7 Популярная наука

Назад к содержанию

Не все события всплывают, например:

  • onblur
  • onfocus
  • onmouseenter
  • onmouseleave

Шесть различий между typeof и instanceof

Назад к содержанию

  • typeof: Обнаружение типа переменной, кроме базового типаnullЗа исключением функции, он может нормально отображаться как соответствующий тип, а ссылочный тип будет отображаться как функция, кроме функции.function, остальные отображаются какobject.
  • instanceofОн в основном используется для определения того, находится ли объект-прототип конструктора в цепочке прототипов объекта.

typeofбудуnullОшибка отображения является исторической ошибкой,typeof nullвыводobject, так как ранняя версия JavaScript была 32-битной системой, по соображениям производительности используйте низкоуровневую информацию о типах переменных хранения,000Однако начало представляет объектnullпредставлен как все нули, поэтому он ошибочно оценивает какobject.

а такжеObject.prototype.toString.call()Делайте переменные суждения.

Подробности можно увидеть:JavaScript — переменные

Семь одно предложение, описывающее это

Назад к содержанию

Для функций объект, указывающий на последнюю вызывающую функцию, является внутренним объектом, автоматически генерируемым при запуске функции, и может использоваться только внутри функции; для глобальных объектовthisнаправлениеwindow.

Восемь позиций JS

Назад к содержанию

  • clientHeight: Указывает высоту видимой области, исключаяborderи полоса прокрутки
  • offsetHeight: Указывает высоту видимой области, включаяborderи полоса прокрутки
  • scrollHeight: Указывает высоту всех областей, включая ту часть, которая скрыта из-за прокрутки.
  • clientTop: указывает границуborderтолщина, как правило, в случае неуказанного0
  • scrollTop: Высота, которую нужно скрыть после прокрутки, получить объект относительноoffsetParentзаданные свойством родительские координаты (позиционированные элементы CSS илиbodyэлемент) высота от вершины.

Перетаскивание девяти JS

Назад к содержанию

  1. пройти черезmousedown,mousemove,mouseupреализация метода
  2. через HTML5Dragа такжеDropвыполнить

10 setTimeout реализует setInterval

Назад к содержанию

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

const say = () => {
  // do something
  setTimeout(say, 200);
};

setTimeout(say, 200);

Очистить этот таймер:

let i = 0;

const timeList = [];

const say = () => {
  // do something
  console.log(i++);
  timeList.push(setTimeout(say, 200));
};

setTimeout(say, 200);

setTimeout(() => {
  for (let i = 0; i < timeList.length; i++) {
    clearTimeout(timeList[i]);
  }
}, 1000);

Одиннадцать достичь сна

Назад к содержанию

Как следует, для достижения1000Сделайте что-нибудь еще через миллисекунды:

const sleep = time => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(time);
    }, time);
  });
};

sleep(1000).then((res) => {
  console.log(res);
});

12 Контекст выполнения

Назад к содержанию

12.1 Типы контекста выполнения

Назад к содержанию

В JavaScript существует 3 типа контекста выполнения:

  • глобальный контекст выполнения: это контекст по умолчанию или базовый, любой код не внутри функции находится в глобальном контексте. Он делает две вещи: создает глобальныйwindowобъект (в случае браузера) и установитьthisЗначение равно этому глобальному объекту. В программе существует только один глобальный контекст выполнения.
  • контекст выполнения функции: Всякий раз, когда вызывается функция, для этой функции создается новый контекст. Каждая функция имеет свой собственный контекст выполнения, но создается при вызове функции. Контекстов функций может быть любое количество. Всякий раз, когда создается новый контекст выполнения, он выполняет серию шагов в определенном порядке.
  • Контекст выполнения функции Eval: выполнить наevalКод внутри функции также будет иметь свой контекст выполнения, но поскольку разработчики JavaScript не часто используютeval, поэтому я не буду обсуждать это здесь.

12.2 Стек выполнения

Назад к содержанию

Стек выполнения, также известный как «стек вызовов» в других языках программирования, представляет собойLIFOСтек структур данных (последний вошел, первый вышел), используемый для хранения всех контекстов выполнения, созданных при выполнении кода.

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

Механизм выполняет функции, контекст выполнения которых находится на вершине стека. Когда выполнение функции завершается, контекст выполнения извлекается из стека, и поток управления переходит к следующему контексту в текущем стеке.

let a = 'Hello World!';

function first() {
  console.log('Inside first function');
  second();
  console.log('Again inside first function');
}

function second() {
  console.log('Inside second function');
}

first();
console.log('Inside Global Execution Context');

Тринадцать функциональных программ

Назад к содержанию

Функциональное программирование (сокращенно FP).

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

Пример: преобразование кода

['john-reese', 'harold-finch', 'sameen-shaw'] 
// 转换成 
[{name: 'John Reese'}, {name: 'Harold Finch'}, {name: 'Sameen Shaw'}]

Преобразуйте приведенный выше код.

const arr = ['john-reese', 'harold-finch', 'sameen-shaw'];
const newArr = [];
for (let i = 0, len = arr.length; i < len ; i++) {
  let name = arr[i];
  let names = name.split('-');
  let newName = [];
  for (let j = 0, naemLen = names.length; j < naemLen; j++) {
    let nameItem = names[j][0].toUpperCase() + names[j].slice(1);
    newName.push(nameItem);
  }
  newArr.push({ name : newName.join(' ') });
}
return newArr;

В этом коде есть 2 части:

  1. Разбивает строки в массиве и превращает строки в имена людей.john-reese -> John Reese
  2. Преобразование массива в объект.['John Reese'] -> [{ name: 'John Reese' }]

Таким образом, мы можем напрямую изменить:

/**
 * @name 改变人名展示方式
 * @param {array} arr 需要改变的数组
 * @param {string} type 支持不同格式的人名
 */
const changeName = (arr, type) => {
  return arr.map(item => item.split(type).map(name => name[0].toUpperCase() + name.slice(1)).join(' '));
};

/**
 * @name 数组改变成对象
 * @param {array} arr 需要改变的数组
 * @param {string} key 对应变成什么字段
 * @return {object} 返回改变后的对象
 */
const arrToObj = (arr, key) => {
  return arr.map(item => ({ [key]: item }));
};

const result = arrToObj(changeName(['john-reese', 'harold-finch', 'sameen-shaw'], '-'), 'name');
console.log(result); // [ { name: 'John Reese' }, { name: 'Harold Finch' }, { name: 'Sameen Shaw' } ]

Привет, это не просто инкапсуляция функций? Вообще говоря, инкапсулируется код, встречающийся в работе более 2 раз.

Функциональное программирование — это извлечение и инкапсуляция функций, которые можно извлечь.

Кажется, здесь постигли истину,jsliangЯ не понял определение в деталях, надеюсь, оно не вводит в заблуждение.

13.1 Особенности функционального программирования

Назад к содержанию

  1. Функции являются гражданами первого класса. Вы можете воспользоваться этим, чтобы поддержать извлечение во внешний мир.
  2. объявить что-то сделать. Функциональное программирование в основном определяет, что должна делать функция, а не то, как она это делает.
  3. легкая сборка мусора. Переменные внутри функции удобны для сборки мусора, переменных не будет слишком много, и пользователю не нужно много определений.
  4. Данные неизменны. Функциональное программирование требует, чтобы все данные были неизменяемыми.Если вам нужно изменить объект, вы должны создать его, а затем изменить, а не загрязнять исходные данные.
  5. нет статуса. Одна и та же функция возвращает одни и те же выходные данные для одних и тех же входных данных, независимо от изменений внешнего состояния, независимо от того, когда она выполняется.
  6. Нет побочных эффектов. Функцию A следует использовать только для завершения ее реализации, а не для изменения внешними изменениями, чтобы, когда она завершит выполнение, ее внутренние данные можно было повторно использовать. И он не изменяет переданные параметры.

Обратите внимание на передачу эталонных значений (Object, Array), и постарайтесь не загрязнять входящие данные.

13.2 Чистые функции

Назад к содержанию

Понятие чистой функции имеет 2 пункта:

  1. Не зависит от внешнего состояния (без гражданства): текущий результат функции не зависит от глобальных переменных,thisуказатель,IOоперация и т.д.
  2. Нет побочных эффектов (данные без изменений): Не изменяйте глобальные переменные и входные параметры.

преимущество:

  • Легко тестировать и оптимизировать
  • кешируемость
  • самодокументирующийся
  • меньше ошибок

14 прогрессивных веб-приложений (PWA)

Назад к содержанию

Прогрессивные веб-приложения (PWA) — это концепция, представленная Google в конце 2015 года. В основном веб-приложение, но выглядит и работает как нативное приложение. Веб-сайты, поддерживающие PWA, могут предлагать такие функции, как автономная работа, push-уведомления и доступ к оборудованию устройства.

14.1 Преимущества

Назад к содержанию

  • меньше и быстрее: прогрессивные веб-приложения намного меньше нативных приложений. Их даже не нужно устанавливать. Это они не тратят место на диске и загружаются очень быстро.
  • Отзывчивый интерфейс: веб-страницы, поддерживаемые PWA, могут автоматически адаптироваться к различным размерам экрана. Это может быть телефон, планшет, настольный компьютер или ноутбук.
  • Нет необходимости обновлять: Большинство мобильных приложений требуют регулярных еженедельных обновлений. Как и обычные веб-сайты, PWA всегда загружают последнюю обновленную версию всякий раз, когда происходит взаимодействие с пользователем, и не требуют одобрения приложения или магазина игр.
  • Экономически эффективным: нативные мобильные приложения необходимо разрабатывать отдельно для устройств Android и iOS, а стоимость разработки очень высока. С другой стороны, PWA имеют ту же функциональность, но за небольшую часть предыдущей цены и с низкими затратами на разработку.
  • SEO-преимущество: PWA обнаруживаются поисковыми системами и загружаются очень быстро. Как и на других веб-сайтах, их ссылками также можно делиться. Обеспечьте хороший пользовательский опыт и результаты, повышение рейтинга SEO.
  • Автономная функция: к PWA можно получить доступ в автономном режиме или при низком уровне интернет-соединения благодаря поддержке Service Worker API.
  • безопасность: PWA доставляется через соединение HTTPS и защищает данные пользователя при каждом взаимодействии.
  • Отправить уведомление: Благодаря поддержке push-уведомлений PWA легко взаимодействуют с пользователями и обеспечивают отличный пользовательский интерфейс.
  • обойти магазин приложений: если нативному приложению требуется какое-либо новое обновление, ему требуется несколько дней одобрения в App Store, и есть вероятность его отклонения или запрета.В этом аспекте PWA имеет свои уникальные преимущества и не требует поддержки App Store. Обновленные версии могут быть загружены непосредственно с веб-сервера без одобрения App Store.
  • Нулевая установка: во время просмотра PWA имеют свои собственные значки на телефонах и планшетах, как и мобильные приложения, но без длительного процесса установки.

14.2 Недостатки

Назад к содержанию

  • Меньший доступ к системным функциям: в настоящее время PWA имеют ограниченный доступ к собственным системным функциям, чем собственные приложения. Также не все браузеры поддерживают его полную функциональность, но, вероятно, в ближайшем будущем он станет новым стандартом разработки.
  • Большинство Android, несколько iOS: В настоящее время больше поддержки исходит от Android. Только часть его обеспечивается системой iOS.
  • нет критериев проверки: PWA не требуют проверки нативных приложений в магазине приложений, что может ускорить процесс, но им не хватает преимуществ продвижения в магазине приложений.

15 Нормализация

Назад к содержанию

CommonJSТехнические характеристики,AMDТехнические характеристики,CMDТехнические характеристики,ES6 ModulesВсе эти четыре спецификации представляют собой интерфейсный стандартизированный контент, так в чем же между ними разница?

До них мы прошли:

  • Функция — это модуль.function fn() {}
  • Объект — это модуль.let obj = new Object({ ... })
  • Функция немедленного выполнения (IIFE).(function() {})()

15.1 Спецификация CommonJS

Назад к содержанию

После этого естьCommonJSспецификация, на самом делеCommonJSМы видели многое, т.NodeНабор из:

  • Экспорт:module.exports = {},exports.xxx = 'xxx'
  • импорт:require(./index.js)
  • Метод поиска: найти, есть ли в текущем каталоге файл, если нет, найти текущий каталогnode_modulesдокумент. Хватит, всплывающий запрос, всегда обращающийся к системеnpmПоиск по каталогу.

Его особенности:

  1. Весь код выполняется в рамках модуля, не загрязняя другие файлы.
  2. requireПолученное значение является копией значения, то есть вы ссылаетесь на переменные в других JS-файлах, и операция модификации не повлияет на другие файлы.

Есть у него и свои недостатки:

  1. прикладной уровень. существуетindex.htmlсделано вvar index = require('./index.js')Операция сообщает об ошибке, поскольку в конечном итоге она выполняется в фоновом режиме и может бытьindex.jsЦитироватьindex2.jsСюда.
  2. Проблема с синхронной загрузкой.CommonJSВ спецификации модули загружаются синхронно, т.index.jsзагрузкаindex2.js,еслиindex2.jsЕсли вы застряли, вам придется долго ждать.

15.2 Технические характеристики AMD

Назад к содержанию

зачемAMDТехнические характеристики?

отвечать:CommonJSСпецификация бесполезна:

  1. Применимые клиенты
  2. Ожидание загрузки (проблема синхронной загрузки).

Так что же он делает?

Модули могут загружаться асинхронно.AMDдаAsynchronous Module DefinitionСокращение от «определения асинхронного модуля», запомните этоasyncПросто знайте, что это асинхронно.

15.3 Спецификации CMD

Назад к содержанию

CMD (Общее определение модуля) — это стандарт, рекомендованный seajs, CMD зависит от ближайшего, а затем снова используйте его.require.

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

15.4 Спецификация модулей ES6

Назад к содержанию

  • Экспорт:
  1. export a
  2. export { a }
  3. export { a as jsliang }
  4. export default function() {}
  • импорт:
  1. import './index'
  2. import { a } from './index.js'
  3. import { a as jsliang } from './index.js'
  4. import * as index from './index.js'

Функции:

  1. exportкоманда иimportКоманды могут появляться в любом месте модуля, если они находятся на верхнем уровне модуля. Если он находится на уровне блока, будет сообщено об ошибке, потому что в условном блоке кода статическая оптимизация не может быть выполнена, что нарушает первоначальный замысел дизайна модуля ES6.
  2. importКоманда имеет эффект подъема и будет поднята на голову всего модуля, который выполняется первым.

а такжеCommonJSразница:

  • CommonJSмодули загружаются во время выполнения,ES6 Modulesэто интерфейс вывода времени компиляции
  • CommonJSВывод — это копия значения;ES6 ModulesВывод представляет собой ссылку на значение, и изменения внутри экспортируемого модуля повлияют на изменение ссылки.
  • CommonJsИмпортированный путь к модулю может быть выражением, поскольку он используетrequire()метод; иES6 Modulesможет быть только строка
  • CommonJS thisуказывает на текущий модуль,ES6 Modulesизthisнаправлениеundefined
  • ES6 ModulesЭтих переменных верхнего уровня нет в:arguments,require,module,exports,__filename,__dirname

Шестнадцать принципов компиляции Babel

Назад к содержанию

  • babylonБудуES6/ES7Код разбирается наAST
  • babel-traverseправильноASTВыполните обходной перевод, чтобы получить новыйAST
  • новыйASTпройти черезbabel-generatorПеревести вES5

этот кусок словjsliangЭто не слишком глубоко, это легко понять, если вы просто поймете это:

  1. Форма, состоящая из черных и белых танграмм, разделенных на части (ES6/ES7анализируется вAST)
  2. Замените эти детали на цветные (ASTскомпилировать получить новыйAST)
  3. Соберите цветные детали в новые формы (ASTПеревести вES5)

Семнадцать вопросов

Назад к содержанию

17.1 Общие API для массивов

Назад к содержанию

  • push: добавить элемент в конец массива
  • unshift: добавить элементы в начало массива
  • pop: удалить элемент с конца массива
  • shift: удалить элемент из головы массива
  • splice: удалить элемент массива
  • slice: обрезать элементы массива
  • indexOf: найти первое вхождение элемента
  • lastIndexof: найти последнее вхождение элемента
  • findIndex: Найдите позицию, в которой элемент появляется впервые.
  • forEach: перебирать элементы
  • map: перебирать элементы
  • filter: элемент фильтра
  • some: содержит элемент
  • every: Все элементы соответствуют элементу
  • includes: проверить, включен ли элемент
  • concat: объединить элементы
  • join: объединить элементы в строки
  • toString: становится строкой
  • sort: порядок элементов

17.2 Общие API-интерфейсы DOM

Назад к содержанию

  • Получать
  • Создайте
  • Добавить к
  • удалять
// 获取元素
const node = document.getElementById(id); // 或者 querySelector(".class|#id|name");

// 创建元素
const heading = document.createElement(name); // name: p、div、h1...
heading.innerHTML = '';

// 添加元素
document.body.appendChild(heading);

// 删除元素
document.body.removeChild(node);

17.3 Дедупликация массива

Назад к содержанию

Дедупликация массива — часто упоминаемый момент:

const arr = [1, 1, 2, 3, 3];
// 期望得到:[1, 2, 3]

// 方法一:for 配合新数组截取
const newArr1 = [];
for (let i = 0; i < arr.length; i++) {
  if (!newArr1.includes(arr[i])) {
    newArr1.push(arr[i]); 
  }
}
console.log('newArr1:', newArr1);

// 方法二:使用 Set
const newArr2 = [...new Set(arr)];
console.log('newArr2:', newArr2);

// 方法三:使用 filter
const newArr3 = arr.filter((item, index) => arr.lastIndexOf(item) === index);
console.log('newArr3:', newArr3);

Интересный вопрос из интервью: не используйте массивыAPIВыполнить дедупликацию.

Примечание: нельзя использоватьpush,indexOfЖдатьAPI

17.4 Оцифрованные суммы

Назад к содержанию

  • Метод 1: Обход методом грубой силы
const num = String(1234567890);
let result = '';

for (let i = num.length - 1; i >= 0; i--) {
  if (i !== num.length - 1 && i % 3 === 0) {
    result = num[i] + ',' + result;
  } else {
    result = num[i] + result;
  }
}

console.log(result);
  • Способ 2: API-навыки
console.log(
  String(1234567890).split('').reverse().reduce((prev, next, index) => (index % 3) === 0 ? next + ',' + prev : next + prev)
);
  • Способ 3: API-навыки
console.log(
  (1234567890).toLocaleString('en-US')
);
  • Способ 4: регулярные выражения
String(1234567890).replace(/\B(?=(\d{3})+(?!\d))/g, ',');

17.5 Проблемы обхода

Назад к содержанию

Каков результат массива после выполнения следующего кода?

let array = [ , 1, , 2, , 3];
array = array.map((i) => ++i)
  • А:[ , 2, , 3, , 4]
  • Б:[NaN, 2, NaN, 3, NaN, 4]
  • С:[1, 2, 1, 3, 1, 4]
  • Д:[null, 2, null, 3, null, 4]

Ответ: А

объяснять:

  1. forEach(),filter(),reduce(),every()а такжеsome()пропустит вакансию.
  2. map()пропустит пробелы, но сохранит значение
  3. join()а такжеtoString()будет рассматривать вакансии какundefined,а такжеundefinedа такжеnullбудет рассматриваться как пустая строка.

17.6 setTimeout

Назад к содержанию

for (var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000);
}

Каков результат выполнения приведенного выше кода?

  • А: 5 5 5 5 5
  • Б: 0 0 0 0 0
  • С: 0 1 2 3 4
  • Д: 1 2 3 4 5

Ответ: А

Разобрать:

  1. var iсуществуетforПри использовании в , это вызовет переменное загрязнение, что приведет к глобальному обходуi,этоiбеги до конца,5
  2. setTimeoutэто задача макроса, вscriptЭта задача макроса выполняется после завершения выполнения, поэтому собранныйiда5
  3. Окончательный результат 55

17.7 requestAnimationFrame

Назад к содержанию

for (let i = 0; i < 5; i++) {
  requestAnimationFrame(() => {
    console.log(i);
  });
}

Результат выполнения приведенного выше кода:

  • А: 1 2 3 4 5
  • Б: 0 1 2 3 4
  • С: 4 4 4 4 4
  • Д: 5 5 5 5 5

Ответ: Б

Разобрать:

  1. let iСделатьforФормирует область действия на уровне блока.
  2. requestAnimationFrameпохожий наsetTimeout, но его можно рассматривать как микрозадачу, которая представляет собой метод, вызываемый после выполнения очереди микрозадач и до выполнения рендеринга пользовательского интерфейса.
  3. Поэтому этот вопрос не касаетсяrequestAnimationFrameбудет собиратьi, ноletПроблема блочной области видимости образуется, если изменить ее наvar i, по-прежнему выводить 55.

17.8 Временная зона нечувствительности

Назад к содержанию

1. Что выводит следующий код?

let a = 1;
let test = function() {
  console.log(a);
  a++;
}
test();

2. Что выводит следующий код?

let a = 1;
let test = function() {
  console.log(a);
  let a = 2;
  a++;
}
test();

Отвечать:

Вывод первого вопроса:1

Вывод второго вопроса:Uncaught ReferenceError: Cannot access 'a' before initialization

Разобрать:

Причина в том, что тот жеblockсередина,letЕсли она будет переопределена позже, на переменную нельзя будет сослаться раньше. При этом значение вложенного внешнего слоя взять нельзя.

17.9 Вывод результата печати

Назад к содержанию

function sayHi() {
  console.log(name);
  console.log(age);
  var name = "Lydia";
  let age = 21;
}

sayHi();

Вывод приведенного выше кода?


Ответ: не определено, ошибка

Разобрать:

Этот вопрос меняется, чтобы ясно видеть:

function sayHi() {
  var name; // 变量提升 - 变量声明
  console.log(name); // undefined
  console.log(age); // let 存在暂时性死区,不会变量提升
  name = "Lydia"; // 变量提升 - 变量赋值
  let age = 21;
}

sayHi();

17.10 Вывод результата печати

Назад к содержанию

function myFunc() {
  console.log(a);
  console.log(func());

  var a = 1;
  function func() {
    return 2;
  }
}

myFunc();

Подскажите, пожалуйста, что на выходе?


Отвечать:undefined 2

Разбор: не сложный, без разбора

17.11 Event Loop

Назад к содержанию

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

Вывод приведенного выше кода?


Ответы и анализ:

Первая тема:varсуществуетforВ синхронном коде есть переменное загрязнениеforПосле завершения выполнения снова выполните задачу макроса.setTimeout, найти текущийiоба становятся3, поэтому вывод3、3、3

Вторая тема:letсуществуетforОбласть видимости на уровне блока будет сформирована вiявляется новым значением, и каждое значение существует в области блока внутри цикла, поэтому вывод0、1、2

17.12 Вывод результата печати

Назад к содержанию

let date = new Date();

for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(new Date - date, i); // 1
  }, 1000);
}

console.log(new Date - date, i); // 2

Подскажите, пожалуйста, что на выходе?


Отвечать:

0 5
1001 5
1004 5
1005 5
1006 5
1007 5

Анализ: тема сначала переходит к задаче макросаscript, поэтому определитеdateПосле этого выполните строку, закомментированную как 2console.

Затем 5 макрозадач, все таймерыsetTimeout, поэтому он будет выполнен после, вывод:1000 5, но таймер не обязательно пунктуален, поэтому может быть1001,1002или что-то другое.

17.13 Сделать == 1 && a == 2 истинным

Назад к содержанию

Попробуйте закодировать так, чтобы:if(a == 1 && a == 2 && a == 3) {}Это положение соответствует действительности.

  • метод первый

Во время преобразования типов мы знаем, как объекты преобразуются в примитивные типы данных. если развернут[Symbol.toPrimitive], то возвращаетсяSymbol.toPrimitiveВозвращаемое значение.

Конечно, мы также можем развернуть эту функцию вvalueOfилиtoStringНа интерфейсе эффект тот же.

//利用闭包延长作用域的特性
let a = {
  [Symbol.toPrimitive]: (function () {
    let i = 1;
    return function () {
      return i++;
    }
  })()
}
  • Способ второй

использоватьObject.definePropertyсуществуетwindow/globalопределено вышеaсобственность, получитьaсвойство, оно будет называтьсяget

let val = 1;
Object.defineProperty(window, 'a', {
  get: function() {
    return val++;
  }
});
  • Способ третий
var a = [1, 2, 3];
a.join = a.shift;

массивtoStringметод возвращает строку, состоящую из значений каждого элемента массиваtoString()Возвращаемое значение называетсяjoin()Конкатенации методов (разделяются запятыми).

Поэтому мы можем повторноjoinметод. Возвращает первый элемент и удаляет его.

Еще восемнадцать

Назад к содержанию

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

Эта статья неплохая,jsliangВ первый раз, когда я сделал это, я все еще неправильно задавал вопросы, ха-ха.

Так что эта статья здесь, желаю друзьям поскорее найти нужноеOffer.


知识共享许可协议
библиотека документации jsliangЗависит отЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.com/l ian Jun Ron…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.