1. Проблемы с CSS
1. гибкий макет
display:flex; Установленный в родительском элементе, на дочерние элементы влияет flex-бокс, и они по умолчанию располагаются в линию. Если он превышает строку, он будет сжат пропорционально flex: 1; настройки дочернего элемента, установите, как дочерний элемент выделяет пространство родительского элемента, flex: 1, ширина дочернего элемента занимает весь родительский элемент align-items: center определяет выравнивание дочернего элемента в родительский контейнер, центр расположен по центру по вертикали justify -content:center Установить дочерний элемент в центре родительского элемента, при условии, что дочерний элемент не заполняет родительский элемент, так что дочерний элемент центрируется по горизонтали.
2. Новые возможности css3
переход свойство перехода указывает имя свойства CSS, которое задает эффект перехода.
transition-duration указывает, сколько секунд или миллисекунд требуется для завершения эффекта перехода.
transition-timing-function Определяет кривую скорости для эффекта скорости.
transition-delay определяет, когда начинается эффект перехода.
Свойство анимации можно использовать для управления каждым шагом анимации, управляя ключевыми кадрами для достижения более сложных эффектов анимации.
Aanimation реализует анимационный эффект, который в основном состоит из двух частей:
Объявите анимацию через кадр, аналогичную Flash-анимации;
Анимация, объявленная ключевым кадром, вызывается в свойстве анимации.
перевести эффект 3D-моделирования
3. Разница между alt и title в img
Атрибут alt в картинке — это текстовая подсказка, которая появляется, когда картинка не может нормально отображаться. alt хорош для SEO-оптимизации
Атрибут title на изображении представляет собой текстовую подсказку при наведении мыши на элемент.
4. Создайте треугольник с помощью чистого CSS
<style>
div {
width: 0;
height: 0;
border-top: 40px solid transparent;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-bottom: 40px solid #ff0000;
}
</style>
</head>
<body>
<div></div>
</body>
5. Как понять блочную модель CSS?
Стандартная блочная модель: ширина = ширина содержимого (контента) + граница + отступы
Блочная модель IE с низкой версией: ширина = ширина контента (контент+граница+заполнение)
6. Как центрировать div по горизонтали
Известная ширина, блочный элемент, добавить автоматический атрибут margin:0.
Ширина известна, абсолютное позиционирование по центру, верх, низ, лево и право равны 0, поле: авто
7. Как центрировать div по горизонтали и вертикали
div {
position: relative / fixed; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
margin-top:-150px;
margin-left:-250px;
外边距为自身宽高的一半 */
background-color: pink; /* 方便看效果 */
}
.container {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.container div {
width: 100px; /* 可省 */
height: 100px; /* 可省 */
background-color: pink; /* 方便看效果 */
}
8. Как очистить поплавок?
очистить, чтобы очистить поплавок (добавить пустой метод div) добавить пустой div под плавающий элемент и написать стиль css для элемента {очистить:оба;высота:0;переполнение:скрыто;}
Установите высоту родительского плавающего элемента
Родитель плавает одновременно (необходимо добавить плавание к родительскому родственному элементу)
Для родителя задан встроенный блок, а его поле: 0 метод автоматического центрирования недействителен
Добавьте overflow:hidden к родителю, чтобы очистить плавающий метод.
Универсальный метод очистки после плавающей очистки псевдокласса (текущий основной метод, рекомендуется)
float_div:after{
content:".";
clear:both;
display:block;
height:0;
overflow:hidden;
visibility:hidden;
}
.float_div{
zoom:1
}
9.css3 реализует трехколоночный макет, левый и правый фиксированный, средний адаптивный
Планировка Святого Грааля / Планировка двойного крыла
<style>
* {
margin: 0;
padding: 0;
}
.middle,
.left,
.right {
position: relative;
float: left;
min-height: 130px;
}
.container {
padding: 0 220px 0 200px;
overflow: hidden;
}
.left {
margin-left: -100%;
left: -200px;
width: 200px;
background: red;
}
.right {
margin-left: -220px;
right: -220px;
width: 220px;
background: green;
}
.middle {
width: 100%;
background: blue;
word-break: break-all;
}
</style>
</head>
<body>
<div class='container'>
<div class='middle'></div>
<div class='left'></div>
<div class='right'></div>
</div>
</body>
10. Разница между отображением: нет и видимостью: скрыто
display:none скрывает соответствующий элемент, больше не выделяет для него место в макете документа, а элементы по бокам схлопываются, как будто его никогда и не было.
visibility:hidden скрывает соответствующий элемент, но сохраняет исходное место в макете документа.
11. В чем разница между ссылкой и @import в CSS?
ссылка — это тег HTML, а @import — это CSS, предоставляемый страницей при загрузке страницы, ссылка будет загружена одновременно, а CSS, на который ссылается @import, будет ждать загрузки страницы перед загрузкой.
импорт может быть распознан только в IE5 или более поздних версиях, а ссылка является HTML-тегом, проблем с совместимостью нет.
Вес стиля ссылки выше, чем у @import.
12. Сходства и различия между абсолютным и фиксированным положением
Общая основа: 改变行内元素的呈现方式,display被置为block 让元素脱离普通流,不占据空间 默认会覆盖到非定位元素上
разница: absolute的”根元素“是可以设置的 fixed的”根元素“固定为浏览器窗口。 При прокрутке страницы расстояние между фиксированным элементом и окном браузера остается постоянным.
13. Разница между переходом и анимацией
Большинство свойств анимации и перехода одинаковы. Они оба изменяют значение свойства элемента с течением времени. Основное различие между ними заключается в том, что для перехода необходимо инициировать событие, чтобы изменить свойство. Анимации не нужно запускать какие-либо события для изменения значения атрибута во времени, а переход составляет 2 кадра, от .... до, причем анимация может быть покадровой.
переход указывает имя анимации указывает, сколько секунд или миллисекунд требуется для завершения эффекта перехода указывает эффект скорости определяет, когда начинается эффект перехода анимация указывает имя ключевого кадра для привязки к селектору
14. Приоритет CSS
不同级别:总结排序:!important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性
1.属性后面加!import 会覆盖页面内任何位置定义的元素样式
2.作为style属性写在元素内的样式
3.id选择器
4.类选择器
5.标签选择器
6.通配符选择器(*)
7.浏览器自定义或继承
**同一级别:后写的会覆盖先写的**
Принцип синтаксического анализа селекторов CSS: селектор находит элементы DOM справа налево, чтобы можно было как можно быстрее отфильтровать некоторые ненужные правила стиля и элементы.
15. Карта спрайтов:
多个图片集成在一个图片中的图
使用雪碧图可以减少网络请求的次数,加快允许的速度
通过background-position,去定位图片在屏幕的哪个位置
2. JS-проблема
1. В чем разница между typeof и instance обнаружения типов данных?
Тот же пункт: часто используются для определения того, является ли переменная пустой или какого она типа.
разница: Возвращаемое значение typeof — это строка, указывающая тип данных переменной. instanceof используется для определения того, принадлежит ли переменная экземпляру объекта.
16. Способы заставить элементы исчезнуть
visibility:hidden、display:none、z-index=-1、opacity:0
1.opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
2.visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
3.display:node, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
, Разговор о глубоком клонировании и мелком клонировании?
Мелкий клон: Копируется только базовый тип данных, а на данные ссылочного типа также будут ссылаться после копирования. Мы называем эту копию «(мелкой копией) поверхностной копией». Другими словами, неглубокая копия указывает только на скопированный адрес памяти. объект в исходном адресе изменяется, поверхностно скопированный объект также изменится соответственно.
Глубокий клон: Создайте новый объект, и другие объекты, на которые есть ссылки в свойстве, также будут клонированы, больше не указывая на исходный адрес объекта. JSON.parse, JSON.stringify()
3. Каковы новые возможности es6?
let определяет блочную переменную Нет подъема переменных, необходимо объявить перед использованием Переменная, объявленная с помощью let, не может иметь то же имя, что и переменная, объявленная с помощью let, var и conset.
const определяет переменную только для чтения Когда const объявляет переменную, ей должно быть присвоено значение. Переменная, объявленная const, должна быть инициализирована. После завершения инициализации модификация не допускается. Объявленная const переменная также является переменной с блочной областью видимости. Переменные, объявленные как const, не имеют «продвижения переменных» и должны быть объявлены перед использованием. Объявленная const переменная не может быть такой же, как предыдущая переменная let, var, const. Значение свойства в объекте\массиве, определенном константой, может быть изменено, но базовый тип данных не может быть изменен.
ES6 может устанавливать значения по умолчанию для функций формальных параметров
Добавьте перед массивом три точки (...) оператор расширения
Раскрытие массива, задание по деструкции объекта, задание по разрушению объекта
Особенности стрелочных функций Стрелочные функции эквивалентны анонимным функциям, они не могут использоваться в качестве конструкторов и не могут использоваться новыми функциями. Стрелочные функции не имеют набора аргументов, вместо этого используйте... остаточный оператор У стрелочных функций нет своего this. Его это унаследовано от этого в текущем контексте Стрелочные функции не имеют прототипов функций. Стрелочные функции нельзя использовать в качестве функций-генераторов, а ключевое слово yield нельзя использовать. Вы не можете использовать call, apply, bind для изменения указателя this в функции стрелки. Установка структуры данных, дедупликация массива
4. В чем разница между == и ===?
= назначение
== возвращает логическое значение, равное возвращает истину, неравное возвращает ложное значение; разрешить сравнение между различными типами данных; Если это выполняется с разными типами данных, преобразование между типами данных будет выполнено по умолчанию; Если это сравнение типов данных объекта, то сравнением является адрес пространства.
=== Возвращает false, если типы данных разные;
5. Каковы общие шаблоны проектирования?
1、js工厂模式
2、js构造函数模式
3、js原型模式
4、构造函数+原型的js混合模式
5、构造函数+原型的动态原型模式
6、观察者模式
7、发布订阅模式
6.Call Bind Примените разницу?
Первый параметр call() и apply() одинаков и является указанным объектом. Этот объект является контекстом выполнения функции.
Разница между call() и apply() заключается в параметрах между ними.
Все последующие аргументы call() после первого аргумента являются значениями, переданными в функцию.
apply() имеет только два параметра, первый — это объект, а второй — массив, который является параметром функции. Разница между методом bind() и первыми двумя состоит в том, что метод bind() вернет функцию, контекст выполнения которой был изменен, не выполняя ее немедленно, в то время как первые два выполняют функцию напрямую. Его параметры такие же, как у call().
7. Каковы методы наследования js?
Наследование прототипов цепи Core: используйте экземпляр родительского класса как прототип ребенка класса
Конструктивное наследование CORE: использование конструктора родительского класса для улучшения экземпляра подкласса эквивалентна копированию атрибутов экземпляра родительского класса в подкласс
наследование экземпляра Ядро: добавьте новые функции в экземпляры родительского класса и верните их как экземпляры дочернего класса.
копирование наследства
наследование композиции Ядро: вызывая родительский класс для построения, наследуйте свойства родительского класса и сохраняйте преимущества передачи параметров, а затем используйте экземпляр родительского класса в качестве прототипа дочернего класса для повторного использования функции.
Наследование паразитарного состава Ядро: отключите атрибуты экземпляра родительского класса паразитным методом, чтобы при двойном вызове конструктора родительского класса методы/атрибуты экземпляра не инициализировались дважды, избегая недостатков комбинированного наследования.
8. Что вы думаете о закрытии?
Проще говоря, замыкание — это объявление функции внутри функции, по сути, это построение моста между внутренней частью функции и внешней частью функции, чтобы дочерняя функция могла получить доступ ко всем локальным переменным. в родительской функции, а не наоборот.Это всего лишь Одна из функций замыканий, а другая - защищать переменные от внешнего загрязнения, чтобы они всегда существовали в памяти.Нам следует меньше использовать замыканий в нашей работе, т.к. замыкания потребляют слишком много памяти и не являются крайним средством.По возможности не используйте его.
9. Как вы понимаете прототипы и цепочки прототипов?
Поместите все свойства, общие для всех объектов, в один объект (объект, состоящий из общих свойств) в памяти кучи, а затем позвольте __proto__ каждого объекта хранить адрес этого «объекта, состоящего из общих свойств». И это общее свойство является прототипом, и цель прототипа — уменьшить ненужное потребление памяти. Цепочка прототипов — это механизм, с помощью которого объект ищет свойства или методы в прототипе класса, к которому принадлежит текущий экземпляр, через __proto__.Если прототип объекта найден, а требуемое свойство или метод не найдены, поиск заканчивается, и в конечном итоге он вернет undefined
10. Каков основной процесс рендеринга в браузере?
HTML-код просматривается в глубину для создания дерева DOM. После загрузки файла css он также будет обработан для создания соответствующей CSSOM. Когда все файлы css загружены и вся конструкция CSSOM завершена, дерево рендеринга будет сгенерировано вместе с DOM. Далее браузер войдет в ссылку Layout и рассчитает позиции всех узлов. Наконец, все содержимое узла отображается на экране через ссылку «Рисование».
11. Что произошло от ввода URL-адреса до ответа страницы?
1、浏览器的地址栏输入URL并按下回车。
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。3、DNS解析URL对应的IP。
4、根据IP建立TCP连接(三次握手)。
5、HTTP发起请求。
6、服务器处理请求,浏览器接收HTTP响应。
7、渲染页面,构建DOM树。
8、关闭TCP连接(四次挥手)
12. Разница между сеансом, файлом cookie и локальным хранилищем
Та же точка Все они сохраняются на стороне браузера и имеют одинаковое происхождение.
разница
- Данные файла cookie всегда в HTTP-запросе гомологичны, а именно Cookie пропускается взад-вперед между браузером и сервером.
- Однако sessionStorage и localStorage автоматически не отправляют данные на сервер, а только сохраняют их локально.
- Данные cookie также имеют понятие пути (path), которое может ограничить принадлежность cookie определенному пути. Ограничение на размер хранилища также отличается.Данные куки не могут превышать 4 КБ.В то же время, поскольку каждый http-запрос будет содержать куки, куки подходят только для хранения небольших данных.
- Хотя sessionStorage и localStorage также имеют ограничения на размер хранилища, они намного больше, чем файлы cookie, и могут достигать 5 МБ и более. Срок действия данных другой, sessionStorage: Он действителен только до закрытия текущего окна браузера, и, естественно, постоянно его держать невозможно;
- localStorage: действует всегда, окно или браузер также всегда сохраняются, поэтому используются как постоянные данные;
- Файл cookie действителен только до истечения установленного срока действия файла cookie, даже если окно или браузер закрыты. Различные области действия, sessionStorage не используется совместно в разных окнах браузера, даже на одной странице;
- localStorage совместно используется всеми окнами одного и того же происхождения; файлы cookie также используются всеми окнами одного происхождения.
13. Междоменные методы в js
Политика одного и того же происхождения (протокол + номер порта + доменное имя должны быть одинаковыми)
1, междоменный jsonp (только получить) Принцип: динамически создавайте тег скрипта. Использование атрибута src тега script не ограничено политикой одного и того же источника, поскольку все атрибуты src и атрибуты href не ограничены политикой одного и того же происхождения, и можно запрашивать содержимое ресурсов стороннего сервера.
шаг: 1). Чтобы создать тег скрипта 2) Атрибут src скрипта устанавливает адрес интерфейса 3) Параметр интерфейса должен иметь имя пользовательской функции, иначе фон не может возвращать данные 4) Примите возвращенные данные, определив имя функции
2. Базовое доменное имя document.domain такое же, но имя поддомена другое.
3. window.name используется в окне браузера, и все загружаемые доменные имена имеют общее имя window.name.
4. Поддержка настроек сервера для CORS Принцип: после того, как сервер установит HTTP-заголовок ответа Access-Control-Allow-Origin, браузер разрешит междоменные запросы.
5. Используйте новую функцию h5 window.postMessage()
14. Какие существуют методы оптимизации страницы интерфейса?
- Уменьшите количество HTTP-запросов
- Упрощение страниц на уровне дизайна и реализации
- Разумная настройка HTTP-кеша
- Консолидация и сжатие ресурсов
- Объединить картинки CSS и уменьшить количество запросов.
- Внизу внешнего сценария (загрузить содержимое сценария после загрузки информационного содержимого страницы)
- Веб-страницы с несколькими изображениями используют отложенную загрузку изображений.
- Минимизируйте использование замыканий в js
- Попробуйте объединить файлы css и js
- Попробуйте использовать значки шрифтов или значки SVG вместо изображений в традиционных форматах PNG.
- Уменьшите манипуляции с DOM
- Избегайте «вложенных петель» и «мертвые петли» в JS
- По возможности используйте делегирование событий (прокси событий) для обработки операций, связанных с событиями.
15. Четыре шага Аякса
1. Создайте экземпляр ajax
2. Выполните open, чтобы определить ссылку, к которой нужно получить доступ, и синхронно асинхронно.
3. Следите за статусом запроса
4. Отправьте запрос
16. Метод дедупликации массива
Установить объект ES6 Сначала отсортируйте исходный массив, сравните его с соседними и сохраните их в новом массиве, если они отличаются
function unique(arr){
var arr2 = arr.sort();
var res = [arr2[0]];
for(var i=1;i<arr2.length;i++){
if(arr2[i] !== res[res.length-1]){
res.push(arr2[i]);
}
}
return res;
}
利用下标查询
function unique(arr){
var newArr = [arr[0]];
for(var i=1;i<arr.length;i++){
if(newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i]);
}
}
return newArr;
}
17. Разница между запросами get и post в ajax
- get обычно используется для получения данных
- Если запрос на получение должен передать параметры, параметры будут присоединены к задней части URL-адреса по умолчанию, а затем отправлены на сервер;
- Размер параметров, передаваемых запросом на получение, ограничен, размер адресной строки браузера ограничен;
- получить менее безопасно
- get обычно переходит в кеш.Чтобы кеш не проходил через кеш, параметры за URL-адресом каждый раз разные; после ? обычно используется метка времени.
- post обычно используется для отправки данных
- Чтобы передать параметры в пост, вам нужно поместить параметры в тело запроса и отправить их на сервер;
- Параметры пост-запроса помещаются в тело запроса, размер не требуется;
- Почтовая безопасность относительно высока;
- Почтовый запрос не попадет в кеш;
18. Код состояния Ajax
2 запуска
- 200 : От имени запрос выполнен успешно;
3 старта
- 301 : Постоянная переадресация;
- 302: Временный перевод
- 304: чтение кеша [указывает, что на стороне браузера есть кеш, а на стороне сервера не обновлялся, и больше не запрашивает ресурсы со стороны сервера]
- 307: Временное перенаправление
Все, что начинается с 4, — проблема клиента;
- 400 : ошибка данных/формата
- 401: Недостаточное разрешение; (неквалифицированная личность, при доступе к веб-сайту вход в систему и не вход в систему различаются)
- 404 : Ошибка пути, файл не найден
Все, что начинается с 5, является проблемой на стороне сервера.
- 500 : Проблема с сервером
- 503: перегрузка;
19. Проблемы совместимости на мобильных терминалах
- Добавление события клика в мобильный терминал будет иметь задержку 300 с. Если вы используете событие щелчка, вам нужно ввести файл fastclick.js, чтобы решить проблему задержки 300 с. Обычно используйте ontouchstart, ontouchmove, ontouchend на мобильном терминале.
- Проблема проникновения мобильного конца, тачстарт раньше, чем тач и раньше, чем щелчок, и триггер клика задерживается. Это время составляет около 300 мс, что означает, что маска скрывается после срабатывания тапа. В это время щелчок еще не было запущено Через 300 мс из-за маски Слой скрыт, и наш щелчок инициируется по ссылке ниже Попробуйте использовать сенсорные события вместо кликов. Например, используйте событие touchend (рекомендуется). с фасткликом,GitHub.com/ft labs/fast…Предотвратить щелчок по тегу с помощью preventDefault Удалите этот крестик в IE10 ввод: -ms-clear{display:none;}
- установить кеш Мобильные страницы обычно кешируются после первой загрузки, и каждое обновление будет использовать кеш вместо повторной отправки запроса на сервер. Вы можете установить no-cache, если вы не хотите использовать кеш.
- Ошибка с закругленными углами Некоторые телефоны Android имеют закругленные углы, которые не работают фоновый клип: padding-box; Запрет увеличения и уменьшения масштаба веб-страниц на мобильных устройствах Это самое простое.Как разработчик мобильных веб-сайтов, вы все должны знать, что нужно установить область просмотра в мета
- Установите пользовательский зум отсечки, который обычно пишется при записи области просмотра.
20. Синхронный и асинхронный в JS и поток событий в js
Синхронизация: делайте одно дело одновременно
Асинхронный: выполнение нескольких действий одновременно JS является однопоточным и может выполнять только одно действие за раз, JS работает в браузере, а браузер является многопоточным и может выполнять несколько задач одновременно.
21. Распространенные асинхронные задачи в JS
Таймер, ajax, привязка событий, функция обратного вызова, асинхронное ожидание, обещание
22. Трехстороннее рукопожатие TCP и четырехсторонняя волна
трехстороннее рукопожатие
- Первое рукопожатие: клиент отправляет на сервер код SYN для запроса установления соединения для передачи данных;
- Второе рукопожатие: сервер SYN обрабатывает SYN (знак) сам с собой; это называется SYN+ACK (пакет подтверждения); он отправляется клиенту, и соединение может быть установлено
- Третье рукопожатие: клиент снова отправляет ACK на сервер, и сервер проверяет, что с ACK нет проблем, после чего соединение устанавливается;
помахал четыре раза
- Первая волна: клиент отправляет сообщение FIN (конец), чтобы уведомить сервер о том, что данные были переданы;
- Вторая волна: После получения сервер сообщает клиенту, что я получил SYN, и отправляет клиенту ACK (подтверждение), данные еще не переданы.
- Третья волна: сервер завершил передачу и снова отправляет FIN, чтобы уведомить клиента о том, что данные были переданы.
- Четвертая волна: клиент снова отправляет ACK и переходит в состояние TIME_WAIT, сервер и клиент закрывают соединение;
23. Почему при установлении соединения происходит трехстороннее рукопожатие и четырехстороннее махание рукой при отключении?
При установлении соединения сервер в состоянии LISTEN после получения сообщения SYN для запроса на установление соединения складывает ACK и SYN в одно сообщение и отправляет его клиенту. Когда соединение закрыто, когда сервер получает сообщение FIN от другой стороны, это означает только то, что другая сторона больше не отправляет данные, но все еще может получать данные, и она может не отправлять все данные другой стороне, поэтому сервер может закрыть его немедленно или отправить его.После того, как некоторые данные отправлены другой стороне, сообщение FIN отправляется другой стороне, чтобы выразить согласие закрыть соединение сейчас.Поэтому, ACK и FIN собственной стороны, как правило, отправлено отдельно, в результате чего еще один раз.
24. Принцип сравнения DOM
- Если тип элемента меняется, замените напрямую
- Если это текст, сравните содержимое в тексте, чтобы увидеть, есть ли разница.Если это элемент, вам нужно сравнить, равны ли атрибуты текущего элемента, и ключ будет сравниваться первым. типа, почему цикл рекомендует не использовать индекс, если он чисто для отображения? индекс можно использовать
25. Объем
глобальная область
- Когда браузер открывает страницу, браузер предоставляет глобальную среду выполнения для кода JS, тогда эта среда является глобальной областью действия. Страница имеет только одну глобальную область, и в глобальной области есть объект окна. окно — самый большой встроенный объект в глобальной области (переменные и функции, определенные в глобальной области, будут храниться под окном) Если это глобальная переменная, в окно будет добавлена пара ключ-значение; имя атрибута — это имя переменной, а значение атрибута — это значение, хранящееся в переменной. Если переменная была только var, сохраненное значение не определено. Глобальные переменные могут быть получены в приватной области, но приватные переменные не могут быть получены в глобальной области.
частная область
- Выполнение функции сформирует новую частную область (выполняется несколько раз, формируя несколько частных областей). Частная область формируется в глобальной области и имеет содержащую связь; В глобальной области может быть много частных областей. Переменные, определенные в частной области, являются частными переменными Параметры также являются приватными переменными Функция, определенная функцией function в теле функции, также является закрытой и не может использоваться в глобальной области видимости;
область действия блока
- Недавно введенная роль в ES6 IF {}, для {}, в то время как {}, переключатель, регистр переключения}, случай переключения}, случай переключения}, случай переключения}, случай переключения}, случай переключения}, случай переключения}. Var obj = {} // Марка объекта не является областью действия на уровне блока Одна и та же переменная на уровне блока не может быть объявлена повторно (переменная и функция не могут быть переименованы на уровне блока, иначе будет сообщено) цепочка прицелов
родительская область
- Там, где функция определена, ее область действия верхнего уровня не имеет ничего общего с областью действия, в которой функция выполняется. Цепочка областей: при получении значения, соответствующего переменной, сначала проверьте, является ли переменная частной переменной.Если это не частная переменная, продолжайте поиск в области верхнего уровня.Если верхний уровень не существует, он будет продолжать поиск верхнего уровня. , пока не будет найдена глобальная область; если глобальной области нет, будет сообщено об ошибке; такой поиск по уровням сформирует цепочку областей видимости Если в текущей области его нет, он продолжит поиск области более высокого уровня. Область верхнего уровня текущей функции не имеет ничего общего с областью, в которой функция выполняется, только определение функции (выделение)
26. Обещание обрабатывает асинхронность
Это новый класс (новый промис), добавленный в ES6, цель которого — управлять асинхронным программированием в JS, поэтому он называется «шаблон проектирования промисов». Новый промис проходит через три состояния: заполнение (состояние подготовки: инициализация прошла успешно, запущены асинхронные задачи), выполнено (состояние успеха), отклонено (состояние сбоя) == Сам промис запрограммирован синхронно, он может управлять асинхронными операциями (акцент), при новом промисе переданная функция будет выполняться сразу Функция Promise имеет два параметра: разрешение (когда асинхронная операция завершается успешно, выполняется метод разрешения), отклонено (при сбое асинхронной операции выполняется метод отклонения) В методе then() есть две функции: первая переданная функция — разрешение, а вторая переданная функция — отклонение. В ajax false представляет синхронизацию, а true представляет асинхронность.Если используется асинхронность, он не будет ждать полного завершения ajax.
27. Разница между map и forEach
Та же точка
- перебирают каждый элемент в массиве Методы forEach и map поддерживают 3 параметра каждый раз, когда выполняется анонимная функция.Параметры: item (каждый текущий элемент), index (значение индекса) и arr (исходный массив).Напишите, что вам нужно использовать. Это в анонимных функциях все указывает на окно может только пройти через массив
разница
- Метод карты возвращает новый массив, элементами массива являются значения, обработанные вызывающей функцией исходного массива. (Новый массив, соответствующий исходному массиву после обработки.) Метод map() не изменяет исходный массив Метод map() не обнаруживает пустые массивы Метод forEach() используется для вызова каждого элемента массива и передачи элемента в функцию обратного вызова (нет возврата, возвращаемое значение не определено).
Уведомление: forEach не будет вызывать функцию обратного вызова для пустого массива.
28. асинхронная функция ожидания
Функции async/await — это новый способ асинхронного кода.
Async / await реализуется на основе обещаний
Async/await делает асинхронный код более похожим на синхронный код
await можно использовать только в асинхронных функциях, а не в обычных функциях, он должен появляться парами
Возвращает экземпляр промиса по умолчанию, который нельзя изменить
Код ниже await является асинхронным, код позади является синхронным
29. это указывает на
- это в глобальной области видимости указывает на окно
- Если вы привязываете функцию к поведению события элемента, то это в функции указывает на текущий связанный элемент
- Значение this в функции зависит от того, есть ли перед выполнением функции .. Если есть ., кто бы ни был перед точкой, это указывает на, если точки нет, то указывает на окно
- это в самовыполняющейся функции всегда указывает на окно
- this функции в таймере указывает на окно
- это в конструкторе указывает на текущий экземпляр
- call, apply, bind могут изменить эту точку функции
- Этого нет в стрелочной функции.Если это выводится, оно выводит это в той области, где была определена стрелочная функция.
30. Прототип
Все типы данных функций рождаются со свойством-прототипом, значением свойства которого является объект. Значение свойства прототипа поставляется со свойством конструктора, значение свойства конструктора которого указывает на класс, к которому принадлежит текущий прототип. Все типы данных объекта рождаются с атрибутом _proto_, значение атрибута которого указывает на прототип класса, к которому принадлежит текущий экземпляр
31. Асинхронные обратные вызовы (как решить ад обратных вызовов)
promise、generator、async/await
promise: 1.是一个对象,用来传递异步操作的信息。代表着某个未来才会知道结果的时间,并未这个事件提供统一的api,供进异步处理
2.有了这个对象,就可以让异步操作以同步的操作的流程来表达出来,避免层层嵌套的回调地狱
3.promise代表一个异步状态,有三个状态pending(进行中),Resolve(以完成),Reject(失败)
4.一旦状态改变,就不会在变。任何时候都可以得到结果。从进行中变为以完成或者失败
promise.all() 里面状态都改变,那就会输出,得到一个数组
promise.race() 里面只有一个状态变为rejected或者fulfilled即输出
promis.finally()不管指定不管Promise对象最后状态如何,都会执行的操作(本质上还是then方法的特例)
32. Внешний поток событий
事件流描述的是从页面中接受事件的顺序,事件 捕获阶段 处于目标阶段 事件冒泡阶段 addeventListener 最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
1、事件捕获阶段:实际目标div在捕获阶段不会接受事件,也就是在捕获阶段,事件从document到<html>再到<body>就停止了。
2、处于目标阶段:事件在div发生并处理,但是事件处理会被看成是冒泡阶段的一部分。
3、冒泡阶段:事件又传播回文档
阻止冒泡事件event.stopPropagation()
function stopBubble(e) {
if (e && e.stopPropagation) { // 如果提供了事件对象event 这说明不是IE浏览器
e.stopPropagation()
} else {
window.event.cancelBubble = true //IE方式阻止冒泡
}
}
阻止默认行为event.preventDefault()
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault()
} else {
// IE浏览器阻止函数器默认动作的行为
window.event.returnValue = false
}
}
33. Как сначала зафиксировать событие, а затем всплывать?
В стандартной модели событий DOM оно сначала перехватывается, а затем всплывает. Но если вы хотите добиться эффекта сначала пузырения, а потом захвата, Для одного и того же события прослушивайте захват и всплывающее сообщение, соответствующие соответствующим функциям обработки соответственно.После прослушивания события захвата сначала приостановите выполнение, а затем выполняйте событие захвата, пока не будет перехвачено событие всплывающего окна.
- Какие события не поддерживают всплывающие события: события мыши: mouserleave mouseenter Событие фокуса: размытие фокуса Событие пользовательского интерфейса: изменение размера прокрутки
34. Как определить, является ли переменная объектом или массивом (prototype.toString.call()).
千万不要使用typeof来判断对象和数组,因为这种类型都会返回object。
typeOf() — это Boolean, Number, symbol, undefined, String, который определяет базовый тип. Для ссылочных типов: за исключением функции, все возвращают объект null и возвращают объект.
installOf() используется для определения того, является ли A экземпляром B, а installof проверяет прототип.
toString() является прототипом метода Object.Для объектов Object прямой вызов toString() вернет [Object Object] . Для других объектов его необходимо вызывать через call/apply, чтобы вернуть правильную информацию о типе.
Метод hasOwnProperty() возвращает логическое значение, указывающее, имеет ли объект указанное свойство в своих собственных свойствах.Этот метод игнорирует свойства, унаследованные от цепочки прототипов.
Метод isProperty() проверяет, существует ли объект в цепочке прототипов другого объекта.
35. Механизм setTimeout и setInterval
因为js是单线程的。浏览器遇到etTimeout 和 setInterval会先执行完当前的代码块,在此之前会把定时器推入浏览器的
待执行时间队列里面,等到浏览器执行完当前代码之后会看下事件队列里有没有任务,有的话才执行定时器里的代码
36. Разница между splice и slice, map и forEach, filter(), reduce()
1.slice(start,end):方法可以从已有数组中返回选定的元素,返回一个新数组,
包含从start到end(不包含该元素)的数组方法
注意:该方法不会更新原数组,而是返回一个子数组
2.splice():该方法想或者从数组中添加或删除项目,返回被删除的项目。(该方法会改变原数组)
splice(index, howmany,item1,...itemx)
·index参数:必须,整数规定添加或删除的位置,使用负数,从数组尾部规定位置
·howmany参数:必须,要删除的数量,
·item1..itemx:可选,向数组添加新项目
3.map():会返回一个全新的数组。使用于改变数据值的时候。会分配内存存储空间数组并返回,forEach()不会返回数据
4.forEach(): 不会返回任何有价值的东西,并且不打算改变数据,单纯的只是想用数据做一些事情,他允许callback更改原始数组的元素
5.reduce(): 方法接收一个函数作为累加器,数组中的每一个值(从左到右)开始缩减,最终计算一个值,不会改变原数组的值
6.filter(): 方法创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。它里面通过function去做处理
проблема ВУЭ
1. Расскажите о своем понимании vue
vue — это прогрессивный JS-фреймворк. Он прост в использовании, гибок и эффективен; Страница может быть разделена на несколько компонентов, когда другие страницы имеют аналогичные функции, инкапсулированные компоненты могут быть повторно использованы напрямую; Это декларативная структура для создания пользовательских интерфейсов, и она заботится только о слоях, а не о том, как она реализована.
2. Каков принцип V-модели?
Двусторонняя привязка данных Vue реализована путем перехвата данных в сочетании с издателем-подписчиком. Перехват данных заключается в захвате операций установки и получения данных объекта с помощью Object.defineProperty(). Делайте, что хотите, когда данные меняются
- принцип Отслеживайте изменения данных вашей собственной модели с помощью Observer, анализируйте и компилируйте инструкции шаблона с помощью Compile и, наконец, используйте Watcher для создания коммуникационного моста между Observer и Compile для достижения изменений данных -> просмотр обновления. При инициализации экземпляра vue пройдитесь по объекту данных, добавьте методы get и set к каждой паре ключ-значение, используя Object.definedProperty для пары ключ-значение данных, и используйте механизм DOM мониторинга событий, чтобы представление могло изменять данные.
3. Поговорим о понимании жизненного цикла
- Стадии beforeCreate: монтируемый элемент el и объекты данных являются примером неопределенного, но инициализированного data vue.
- Стадия создания: Доступны данные объекта данных экземпляра vue, доступ к данным и методам в нем возможен.
- Стадия BeforeMount: el и данные экземпляра vue инициализируются, но перед монтированием они являются виртуальными узлами dom.
- этап монтирования: экземпляр vue монтируется на настоящий DOM, а узел DOM можно получить через DOM
- Этап beforeUpdate: вызывается, когда обновляются данные ответа до того, как виртуальный DOM будет исправлен, подходит для доступа к существующему DOM перед обновлением, например, для ручного удаления добавленного прослушивателя событий.
- Стадия обновления: вызывается после повторного рендеринга и исправления виртуального DOM, чтобы сформировать новый DOM, который был обновлен, избежать рабочих данных в этой функции ловушки и предотвратить бесконечный цикл.
- Стадия beforeDestroy: вызывается перед уничтожением экземпляра, экземпляр все еще можно использовать, это может получить экземпляр, часто используется для уничтожения таймера, отмены привязки событий
- стадия уничтожения: вызывается после уничтожения экземпляра, все прослушиватели событий будут удалены после вызова, а все подэкземпляры будут уничтожены
4. В чем разница между VUE и REACT?
React в целом — это функциональная идея, компоненты спроектированы как чистые компоненты, а состояние и логика передаются через параметры, поэтому в React это односторонний поток данных;
Идея Vue является адаптивной, то есть на основе переменных данных путем создания Watcher для каждого атрибута для мониторинга, когда атрибут изменяется, соответствующий виртуальный дом обновляется в ответ.
5. Процесс vuex
页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation。
mutation会修改state中对于的值。 最后通过getter把对应值跑出去,在页面的计算属性中
通过mapGetter来动态获取state中的值
6. Каковы состояния и свойства vuex
- Общие данные хранятся в состоянии, и данные реагируют
- Геттер может выполнять вычислительные операции над состоянием, в основном используется для фильтрации некоторых данных и может повторно использоваться между несколькими компонентами.
- Метод, определенный мутациями, динамически изменяет данные в состоянии, и метод отправляется через фиксацию.Метод должен быть синхронным.
- Действия превращают метод обработки данных в мутациях в асинхронный, то есть оперируют данными асинхронно, распределяют действия через store.dispatch, пишут асинхронные методы в действиях, отправляют мутации через коммит и модифицируют данные.
- модули: модульный vuex
7. Два режима маршрутизации vue
- hash — символ # в URL адресной строки (этот hsah не является хеш-операцией в криптографии) Хотя хеш отображается в URL-адресе, он не будет включен в HTTP-запрос и не повлияет на серверную часть, поэтому изменение хеша не приведет к перезагрузке страницы.
- история — использует преимущества новых методов pushState() и replaceState() в интерфейсе истории HTML5.
Эти два метода применяются к станции истории браузера.На основе существующих назад, вперед и вперед они обеспечивают функцию модификации истории. Просто, когда они выполняют модификацию, ваш браузер не сразу отправляет запрос на серверную часть, хотя текущий URL-адрес изменен.
8. Роль значения ключа в vue
Когда Vue.js использует v-for для обновления списка отображаемых элементов, по умолчанию используется стратегия «повторное использование на месте». Если порядок элементов данных изменен, Vue не будет перемещать элементы DOM в соответствии с порядком элементов данных, а просто будет повторно использовать каждый элемент здесь и убедиться, что он показывает каждый элемент, который был отрисован по определенному индексу.
Роль ключа в основном заключается в эффективном обновлении виртуального DOM.
9$routeа также$routerразница
- $route — это «объект информации о маршрутизации», включая параметры информации о маршрутизации, такие как путь, параметры, хэш, запрос, полный путь, сопоставление и имя.
- $router — это объект «экземпляр маршрутизатора», который включает в себя методы перехода маршрутизации, функции подключения и т. д.
10. защита vue-маршрутизатора
- Навигационная защита router.beforeEach глобальная передняя защита
- to: Route: пункт назначения, который необходимо ввести (объект маршрута)
- from: Route: Маршрут, по которому уходит текущая навигация
- следующий: Функция: Обязательно вызовите этот метод, чтобы разрешить этот хук. (Обязательно используйте эту функцию для перехода на следующий маршрут, если нет, перехватите его) Эффект выполнения зависит от параметров вызова следующего метода.
- next(): перейти к следующему хуку в конвейере. Если все хуки выполнены, состояние навигации подтверждается.
- следующий (false): отменить входящий маршрут, и URL-адрес сбрасывается на исходный адрес маршрута (то есть адрес маршрута, который нужно оставить).
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => {
next();
});
router.beforeResolve((to, from, next) => {
next();
});
router.afterEach((to, from) => {
console.log('afterEach 全局后置钩子');
});
Защита только для маршрута. Вы можете определить защиту перед входом непосредственно в конфигурацию маршрута.
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
Охранники внутри компонентов Вы можете определить следующие ограничители навигации по маршруту непосредственно в компоненте маршрутизации.
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,我们用它来禁止用户离开
// 可以访问组件实例 `this`
// 比如还未保存草稿,或者在用户离开前,
将setInterval销毁,防止离开之后,定时器还在调用。
}
}
11. Что такое аксиомы? как использовать? Опишите процесс его использования для реализации функции входа в систему?
Модуль, который запрашивает фоновые ресурсы.
$ npm install axios -S装好
Тогда передача будет междоменной, что нужно настроить в config/index.js в конфигурационном файле. Если фоном является Tp5, определите маршрут ресурса. Используйте импорт в js, затем .get или .post. Возврат находится в функции .then в случае успеха и в функции .catch в случае неудачи.
12. модификатор vue
- stop: остановить всплытие события
- предотвратить: предотвратить поведение события по умолчанию
- один раз: срабатывает только один раз
- self: будет выполняться только тогда, когда запускается его собственное поведение события
13. Оптимизация производительности в проекте vue
1. Не пишите слишком много выражений в шаблоне
2. Добавить ключ при циклическом вызове подкомпонентов
3. V-Show Частого передачи обслуживания, ремонт нечастое использование V-iF
4. Используйте float как можно меньше, вы можете использовать flex
5. Загрузка по требованию, вы можете использовать require или import() для загрузки необходимых компонентов по требованию.
6. Маршрутизация ленивой загрузки
14. vue.extend и vue.component
- продлевать является грамматикой для построения компонента. Затем вы можете применить этот компонент к методу глобальной регистрации Vue.component. Вы также можете использовать компоненты в любом шаблоне vue. Он также может воздействовать на экземпляр vue или свойство компонентов компонента и использовать компонент Apple внутри.
- vue.component Вы можете создавать и брать компоненты.
Распространенные проблемы совместимости
24-битные изображения в формате png отображаются в качестве фона в браузерах iE6. Решение состоит в том, чтобы сделать PNG 8. Вы также можете обратиться к скрипту для обработки.
Поля и отступы по умолчанию в браузере отличаются. Решение состоит в том, чтобы добавить глобальное *{margin:0;padding:0;} для унификации.
Ошибка двойного поля IE6: после того, как метка атрибута блока является плавающей и есть горизонтальное поле, поле, отображаемое в IE6, больше, чем настройка.
Двойное расстояние, сгенерированное плавающим значением, т.е. (проблема двойного поля IE6: в IE6, если вы установите float для элемента и одновременно установите margin-left или margin-right, значение поля будет удвоено.) #box{ float: слева; ширина: 10 пикселей; поля: 0 0 0 100 пикселей;}
Реагировать на проблему
1. Разница между реагированием и vue
=> 相同点:
1.数据驱动页面,提供响应式的试图组件
2.都有virtual DOM,组件化的开发,通过props参数进行父子之间组件传递数据,都实现了webComponents规范
3.数据流动单向,都支持服务器的渲染SSR
4.都有支持native的方法,react有React native, vue有wexx
=> 不同点:
1.数据绑定:Vue实现了双向的数据绑定,react数据流动是单向的
2.数据渲染:大规模的数据渲染,react更快
3.使用场景:React配合Redux架构适合大规模多人协作复杂项目,Vue适合小快的项目
4.开发风格:react推荐做法jsx + inline style把html和css都写在js了
vue是采用webpack + vue-loader单文件组件格式,html, js, css同一个文件
2. Редуктор (чистая функция) в редуксе
Redux数据流里,reduces其实是根据之前的状态(previous state)和现有的action(current action)
更新state(这个state可以理解为上下累加器的结果)
每次redux reducer被执行时,state和action被传入,这个state根据action进行累加或者是'自身消减'(reduce),
进而返回最新的state,这也就是典型reduce函数的用法:state -> action -> state
3.Ссылки React
refs就想一个逃生窗,允许我们之间访问dom元素或者组件实例,可以向组件添加一个ref属性的值是一个回调函数,
它将接受地城dom元素或组件的已挂在实例,作为第一个参数
4. ключи в реакции
帮组我们跟踪哪些项目已更改、添加、从列表中删除,key是独一无二的,可以让我们高效的去定位元素,并且操作它
5. Жизненный цикл React
三个状态:Mounting(已插入真实的DOM)
Updating(正在被重新渲染)
Unmounting(已移除真实的DOM)
componentDIdMount 在第一次渲染后调用,只在客服端。之后组件已经生成对应的DOM结构,
componentDidUpdate 在组件完成更新后立即调用,在出初始化是不会调用
6. React дочерние компоненты передают значения родительским компонентам
父组件通过props 给子组件传递数据,子组件则是通过调用父组件传给它的函数给父组件传递数据。
7. Почему виртуальный DOM повышает производительностьУуху. Call.com/question/29…
虚拟DOM相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的doom操作,从而提高性能
具体实现步骤:
·用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档中
·当状态变更的时候,重新构造一棵树的对象树,然后用新的树和旧的树进行对比,记录两棵树差异
·把2所记录的差异应用到步骤1所构建的真正的DOM树上,试图就更新了。
8.алгоритм сравнения
1.把树形结构按照层级分解,只比较同级元素
2.给列表结构的每个单元添加key属性,方便比较。在实际代码中,会对新旧两棵树进行一个深度优先的遍历,这样每个节点都会有一个标记
3.在深度优先遍历的时候,每遍历到一个节点就把该节点和新的树进行对比。如果有差异的话就记录到一个对象里面
Vritual DOM 算法主要实现上面步骤的三个函数:element, diff, patch。然后就可以实际的进行使用
react只会匹配相同的class的component(这里的class指的是组件的名字)
合并操作,条用component的setState方法的时候,React将其标记为dirty.到每一个时间循环借宿,React检查所有标记dirty的component重新绘制
4.选择性子树渲染。可以重写shouldComponentUpdate提高diff的性能
9. Кратко опишите идею потока
flux的最大特点,就是数据的‘单向流动’
1.用户访问View
2.View发出用户的Action
3.Dispatcher收到Action,要求state进行相应的更新
4.store更新后,发出一个‘change’事件后,更新页面
10. Какая периодическая функция является оптимизацией производительности reac?
shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom.因为dom的描绘非常消耗性能,
如果我们在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能
11. Как React разделяет бизнес-компоненты и технические компоненты
根据组件的职责通常把组件分为UI组件和容器组件
UI组件负责UI的呈现,容器组件负责管理数据和逻辑
两者通过React-redux提供connect方法联系起来
12.setState
setState通过一个队列机制实现state更新,当执行setState时,会将需要更新的state很后放入状态队列
而不会立即更新this.state,队列机制可以高效地批量更新state。如果不通过setState而直接修改this.state的值
那么该state将不会被放入状态队列中。当下次调用setState并对状态队列进行合并时,就会忽略之前修改的state,造成不可预知的错误
同时,也利用了队列机制实现了setState的异步更新,避免了频繁的重复更新state
同步更新state:
setState 函数并不会阻塞等待状态更新完毕,因此 setNetworkActivityIndicatorVisible 有可能先于数据渲染完毕就执行。
第二个参数是一个回调函数,在setState的异步操作结束并且组件已经重新渲染的时候执行
也就是说,我们可以通过这个回调来拿到更新的state的值,实现代码的同步
例子:componentDidMount() {
fetch('https://test.com')
.then((res) => res.json())
.then(
(data) => {
this.setState({ data:data });
StatusBar.setNetworkActivityIndicatorVisible(false);
}
оптимизация производительности
1. Размер файла пакета webpack слишком велик? (наконец упакован в виде js-файла)
1.异步加载模块
2.提取第三库
3.代码压缩
4.去除不必要的插件
2. Как оптимизировать производительность сборок webpack
一、减少代码体积 1.使用CommonsChunksPlugin 提取多个chunk之间的通用模块,减少总体代码体积
2.把部分依赖转移到CDN上,避免每次编译过程都由Webpack处理
3.对一些组件库采用按需加载,避免无用的代码
二、减少目录检索范围
·在使用loader的时候,通过制定exclude和include选项,减少loader遍历的目录范围,从而加快webpack编译速度
三、减少检索路经:resolve.alias可以配置webpack模块解析的别名,对于比较深的解析路经,可以对其配置alias
В-третьих, оптимизировать работу мобильных терминалов.
1、首屏加载和按需加载,懒加载
2、资源预加载
3、图片压缩处理,使用base64内嵌图片
4、合理缓存dom对象
5、使用touchstart代替click(click 300毫秒的延迟)
6、利用transform:translateZ(0),开启硬件GUP加速
7、不滥用web字体,不滥用float(布局计算消耗性能),减少font-size声明
8、使用viewport固定屏幕渲染,加速页面渲染内容
9、尽量使用事件代理,避免直接事件绑定
В-четвертых, как Vue SPA оптимизирует скорость загрузки.
1.减少入口文件体积
2.静态资源本地缓存
3.开启Gzip压缩
4.使用SSR,nuxt.js
5. Мобильная задержка 300 мс
由来:
300毫米延迟解决的是双击缩放。双击缩放,手指在屏幕快速点击两次。safari浏览器就会将网页缩放值原始比例。由于用户可以双击缩放或者是滚动的操作,
当用户点击屏幕一次之后,浏览器并不会判断用户确实要打开至这个链接,还是想要进行双击操作
因此,safair浏览器就会等待300ms,用来判断用户是否在次点击了屏幕
解决方案:1.禁用缩放,设置meta标签 user-scalable=no
2.fastclick.js
原理:FastClick的实现原理是在检查到touchend事件的时候,会通过dom自定义事件立即
发出click事件,并把浏览器在300ms之后真正的click事件阻止掉
fastclick.js还可以解决穿透问题
6. Рефакторинг страницы;
Упростите структуру и повысьте читабельность без изменения внешнего поведения
Сервис-терминал
1. Код состояния:
2XX(成功处理了请求状态)
200 服务器已经成功处理请求,并提供了请求的网页
201 用户新建或修改数据成功
202 一个请求已经进入后台
204 用户删除成功
3XX(每次请求使用的重定向不要超过5次)
304 网页上次请求没有更新,节省带宽和开销
4XX(表示请求可能出错,妨碍了服务器的处理)
400 服务器不理解请求的语法
401 用户没有权限(用户名,密码输入错误)
403 用户得到授权(401相反),但是访问被禁止
404 服务器找不到请求的网页,
5XX(表示服务器在处理请求的时候发生内部错误)
500 服务器遇到错误,无法完成请求
503 服务器目前无法使用(超载或停机维护)
2. Принцип кэширования 304 (добавьте тег Etag .last-modified) 304 Последний запрос веб-страницы не был обновлен, экономя пропускную способность и накладные расходы.
1.服务器首先产生Etag,服务器可在稍后使用它来判断页面是否被修改。本质上,客户端通过该记号传回服务器要求服务器验证(客户端)缓存)
2.304是 HTTP的状态码,服务器用来标识这个文件没有被修改,不返回内容,浏览器接受到这个状态码会去去找浏览器缓存的文件
3.流程:客户端请求一个页面A。服务器返回页面A,并在A上加一个Tage客服端渲染该页面,并把Tage也存储在缓存中。客户端再次请求页面A
并将上次请求的资源和ETage一起传递给服务器。服务器检查Tage.并且判断出该页面自上次客户端请求之后未被修改。直接返回304
last-modified: 客服端请求资源,同时有一个last-modified的属性标记此文件在服务器最后修改的时间
客服端第二次请求此url时,根据http协议。浏览器会向服务器发送一个If-Modified-Since报头,
询问该事件之后文件是否被修改,没修改返回304
有了Last-Modified,为什么还要用ETag?
1、因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确(Last—Modified不能识别秒单位的修改)
2、某些服务器不能精确的得到文件的最后修改时间
3、一些文件也行会周期新的更改,但是他的内容并不改变(仅仅改变修改的事件),这个时候我们并不希望客户端认为文件被修改,而重新Get
ETag,为什么还要用Last-Modified?
1、两者互补,ETag的判断的缺陷,比如一些图片等静态文件的修改
2、如果每次扫描内容都生成ETag比较,显然要比直接比较修改时间慢的多。
ETag是被请求变量的实体值(文件的索引节,大小和最后修改的时间的Hash值)
1、ETag的值服务器端对文件的索引节,大小和最后的修改的事件进行Hash后得到的。
3. Разница между get/post
1.get数据是存放在url之后,以?分割url和传输数据,参数之间以&相连; post方法是把提交的数据放在http包的Body中
2.get提交的数据大小有限制,(因为浏览器对url的长度有限制),post的方法提交的数据没有限制
3.get需要request.queryString来获取变量的值,而post方式通过request.from来获取变量的值
4.get的方法提交数据,会带来安全问题,比如登录一个页面,通过get的方式提交数据,用户名和密码就会出现在url上
В-четвертых, понимание протокола http
1.超文本的传输协议,是用于从万维网服务器超文本传输到本地资源的传输协议
2.基于TCP/IP通信协议来传递数据(HTML,图片资源)
3.基于运用层的面向对象的协议,由于其简洁、快速的方法、适用于分布式超媒体信息系统
4.http请求信息request:
请求行(request line)、请求头部(header),空行和请求数据四部分构成
请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
请求头部,用来说明服务器要使用的附加信息
空行,请求头部后面的空行是必须的
请求数据也叫主体,可以添加任意的其他数据。
5.http相应信息Response
状态行、消息报头、空行和响应正文
状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成
消息报头,用来说明客户端要使用的一些附加信息
空行,消息报头后面的空行是必须的
响应正文,服务器返回给客户端的文本信息。
Пять, http и https
https:是以安全为目标的HTTP通道,简单讲是HTTP的安全版本,通过SSL加密
http:超文本传输协议。是一个客服端和服务器端请求和应答的标准(tcp),使浏览器更加高效,使网络传输减少
Шесть, разница между http1.0 1.1 2.0
长连接:HTTP1.0需要使用keep-alive参数来告知服务器建立一个长连接,而HTP1.1默认支持长连接
节约宽带:HTTP1.1支持只发送一个header信息(不带任何body信息)
host域(设置虚拟站点,也就是说,web server上的多个虚拟站点可以共享同一个ip端口):HTTP1.0没有host域
1.http2采用的二进制文本传输数据,而非http1文本格式,二进制在协议的解析和扩展更好
2.数据压缩:对信息头采用了HPACK进行压缩传输,节省了信息头带来的网络流量
3.多路复用:一个连接可以并发处理多个请求
4.服务器推送:我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源
Семь, веб-кеш
1.web缓存就是存在于客户端与服务器之间的一个副本、当你第一个发出请求后,缓存根据请求保存输出内容的副本
2.缓存的好处
(1)减少不必要的请求
(2)降低服务器的压力,减少服务器的消耗
(3)降低网络延迟,加快页面打开速度(直接读取浏览器的数据)
Восемь общих принципов веб-безопасности и защиты
1.sql注入原理:是将sql代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。也就是说,
在一些对server端发起的请求参数中植入一些sql代码,server端在执行sql操作时,会拼接对应参数,
同时也将一些sql注入攻击的“sql”拼接起来,导致会执行一些预期之外的操作。
防范:1.对用户输入进行校验
2.不适用动态拼接sql
2.XSS(跨站脚本攻击):往web页面插入恶意的html标签或者js代码。
举例子:在论坛放置一个看是安全的链接,窃取cookie中的用户信息
防范:1.尽量采用post而不使用get提交表单
2.避免cookie中泄漏用户的隐式
3.CSRF(跨站请求伪装):通过伪装来自受信任用户的请求
举例子:黄轶老师的webapp音乐请求数据就是利用CSRF跨站请求伪装来获取QQ音乐的数据
防范:在客服端页面增加伪随机数,通过验证码
XSS和CSRF的区别:
1.XSS是获取信息,不需要提前知道其他用户页面的代码和数据包
2.CSRF代替用户完成指定的动作,需要知道其他页面的代码和数据包
9. CDN (сеть доставки контента)
1.尽可能的避开互联网有可能影响数据传输速度和稳定性的瓶颈和环节。使内容传输的更快更稳定。
2.关键技术:内容存储和分发技术中
3.基本原理:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对的地区或者网络中。当用户访问网络时利用全局负载技术
将用户的访问指向距离最近的缓存服务器,由缓存服务器直接相应用户的请求(全局负载技术)
10. Трехстороннее рукопожатие TCP (и клиент, и сервер должны подтвердить, что они могут отправлять и получать)
客服端发c起请求连接服务器端s确认,服务器端也发起连接确认客服端确认。
第一次握手:客服端发送一个请求连接,服务器端只能确认自己可以接受客服端发送的报文段
第二次握手: 服务端向客服端发送一个链接,确认客服端收到自己发送的报文段
第三次握手: 服务器端确认客服端收到了自己发送的报文段
11. Полный процесс от ввода URL до получения страницыblog.CSDN.net/Сэм Джастин1/…
1.查询NDS(域名解析),获取域名对应的IP地址 查询浏览器缓存
2.浏览器与服务器建立tcp链接(三次握手)
3.浏览器向服务器发送http请求(请求和传输数据)
4.服务器接受到这个请求后,根据路经参数,经过后端的一些处理生成html代码返回给浏览器
5.浏览器拿到完整的html页面代码开始解析和渲染,如果遇到外部的css或者js,图片一样的步骤
6.浏览器根据拿到的资源对页面进行渲染,把一个完整的页面呈现出来
12. Принцип рендеринга браузера и процесс DOM -> CSSOM -> рендеринг -> макет -> печать
流程:解析html以及构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
概念:1.构建DOM树: 渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM node(包括js生成的标签)生成内容树
2.构建渲染树: 解析对应的css样式文件信息(包括js生成的样式和外部的css)
3.布局渲染树:从根节点递归调用,计算每一个元素的大小,位置等。给出每个节点所在的屏幕的精准位置
4.绘制渲染树:遍历渲染树,使用UI后端层来绘制每一个节点
重绘:当盒子的位置、大小以及其他属性,例如颜色、字体大小等到确定下来之后,浏览器便把这些颜色都按照各自的特性绘制一遍,将内容呈现在页面上
触发重绘的条件:改变元素外观属性。如:color,background-color等
重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观
注意:table及其内部元素需要多次计算才能确定好其在渲染树中节点的属性值,比同等元素要多发时间,要尽量避免使用table布局
重排(重构/回流/reflow): 当渲染书中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就是回流。
每个页面都需要一次回流,就是页面第一次渲染的时候
重排一定会影响重绘,但是重绘不一定会影响重排
13. Почему css вверху, а js сзади?
1.浏览器预先加载css后,可以不必等待HTML加载完毕就可以渲染页面了
2.其实HTML渲染并不会等到完全加载完在渲染页面,而是一边解析DOM一边渲染。
3.js写在尾部,主要是因为js主要扮演事件处理的功能,一方面很多操作是在页面渲染后才执行的。另一方面可以节省加载时间,使页面能够更加的加载,提高用户的良好体验
但是随着JS技术的发展,JS也开始承担页面渲染的工作。比如我们的UI其实可以分被对待,把渲染页面的js放在前面,时间处理的js放在后面
14. Способ хранения и способ передачи
1.indexBD: 是h5的本地存储库,把一些数据存储到浏览器中,没网络,浏览器可以从这里读取数据,离线运用。5m
2.Cookie: 通过浏览器记录信息确认用户身份,最大4kb,这也就限制了传输的数据,请求的性能会受到影响
3.Session: 服务器端使用的一种记录客户状态的机制(session_id存在set_cookie发送到客服端,保存为cookie)
4.localStroage: h5的本地存储,数据永久保存在客服端
файлы cookie, сеансовое хранилище, локальное хранилище
1. cookie, sessionStorage, localStorage хранятся на стороне клиента, а данные объекта сеанса хранятся на сервере Фактически, между браузером и сервером нужно передать только идентификатор сеанса, и сервер находит соответствующий объект сеанса пользователя в соответствии с идентификатором сеанса. Данные хранения сеанса безопаснее, как правило, хранят информацию о пользователе, браузеры подходят только для хранения общих данных. 2. Данные cookie всегда передаются в HTTP-запросе одного и того же источника, передаются туда и обратно между браузером и сервером, и в нем хранится идентификатор сеанса. sessionStorage, localStorage сохранять только локально 3. Ограничение по размеру другое, данные куки не превышают 4кб, а localStorage 2,6Мб в Google Chrome 4. Срок действия данных разный, куки действителен в течение установленного (настройками сервера) срока действия, вне зависимости от закрытия окна и браузера sessionStorage действителен только до закрытия текущего окна браузера и уничтожается при закрытии (временное хранилище) localStorage всегда работает
Разница между SessionStorage и localStorage: 1. sessionStorage используется для локального хранения данных в сеансе (сессии), доступ к которым возможен только на страницах, использующих сеанс (то есть во время первого процесса связи) И данные также уничтожаются после завершения сеанса, а не постоянного локального хранилища, хранилища на уровне сеанса. 2. localStorage используется для постоянного локального хранилища, срок действия которого не истечет, если данные не будут активно удалены.
Каково понимание токена, файла cookie и сеанса? ? ? ! ! !
1、token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件(最好的身份认证,安全性好,且是唯一的)
用户身份的验证方式
2、cookie是写在客户端一个txt文件,里面包括登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名
服务器生成,发送到浏览器、浏览器保存,下次请求再次发送给服务器(存放着登录信息)
3、session是一类用来客户端和服务器之间保存状态的解决方案,会话完成被销毁(代表的就是服务器和客户端的一次会话过程)
cookie中存放着sessionID,请求会发送这个id。sesion因为request对象而产生。
Аутентификация на основе токенов: (самый простой токен: уникальный идентификатор пользователя uid + отметка времени текущего события + подпись подписи)
1、用户通过用户名和密码发送请求
2、服务器端验证
3、服务器端返回一个带签名的token,给客户端
4、客户端储存token,并且每次用于发送请求
5、服务器验证token并且返回数据
每一次请求都需要token
Разница между файлом cookie и сеансом
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
Разница между сеансом и токеном
1、session认证只是把简单的User的信息存储Session里面,sessionID不可预测,一种认证手段。只存在服务端,不能共享到其他的网站和第三方App
2、token是oAuth Token,提供的是认证和授权,认证针对用户,授权是针对App,目的就是让某APP有权访问某用户的的信息。Token是唯一的,
token不能转移到其他的App,也不能转到其他用户上。(适用于App)
3、session的状态是存在服务器端的,客户端只存在session id, Token状态是存储在客户端的
Каковы недостатки файлов cookie? ? ? (Преимущество: сохранить данные клиента, разделить нагрузку на серверное хранилище)
1、数量和长度的限制。每个特定的域名下最多生成20个cookie(chorme和safari没有限制)
2、安全性问题。
Шаблоны проектирования
Во-первых, режим наблюдателя:nuggets.capable/post/684490… nuggets.capable/post/684490…В разработке и проектировании программного обеспечения это объект (субъект), который поддерживает ряд зависимых объектов (наблюдатель) и автоматически уведомляет их об изменении любого состояния. сильная зависимость Простое понимание: при изменении данных соответствующая функция обработки будет выполняться автоматически. Subjet, используемый для поддержки наблюдателей, для уведомления наблюдателей об определенных событиях.
2. Публикующий-подписчик имеет информационного посредника, а связь фильтрации низкая. Он определяет отношение "один ко многим", которое позволяет нескольким объектам-наблюдателям отслеживать подчиненный объект.При изменении подчиненного объекта все зависимые объекты будут уведомлены.
- -Разница между ними: 1. В режиме наблюдателя наблюдатель знает Субъект, и они связаны между собой, а издатель и подписчик общаются только через информационного посредника. 2. В модели публикации-подписки компоненты слабо связаны. Прямо противоположно шаблону наблюдателя. 3. Большинство наблюдателей синхронны, например, запуск событий. Субъект вызовет метод наблюдателя. В то время как подписчики публикации в основном асинхронны () 4. Шаблон наблюдателя должен быть реализован в адресном пространстве одного приложения, а шаблон публикации-подписчика больше похож на шаблон кросс-приложения.
Структуры данных и алгоритмы
1. Два стека реализуют очередь, а две очереди реализуют стекwoo woo woo.cn blog on.com/Mr Listening…
2. Красно-черное дерево (решите линейное расположение, когда несколько узлов последовательно вставляются в двоичное дерево)nuggets.capable/post/684490…
3. Реализация наименьшего стека (найти наименьший элемент, использовать два стека для сопоставления индексов элементов в стеке)nuggets.capable/post/684490…
Четыре, десять рейтинга
1.冒泡排序:重复走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。
实现过程:1.比较相邻的元素。如果第一个比第二个大,就交换他们两个
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数
3.针对所有的元素重复以上的步骤,除了最后一个
4.重复步骤1-3,直到排序完成。
2.选择排序:首先在未排序序列中找到最小值,放在排序序列的起始位置,然后,在从剩下未排序元素中继续寻找最小值,然后放在与排序序列的末尾
实现过程:
3.插入排序:构建有序序列,对于未排序数据,在已排序序列中冲后向前扫描,找到相应位置并插入
实现过程:1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已排序的元素序列中冲后向前扫描
3.如果该元素(以排序)大于新元素,将元素向后移一位
4.在取出一个元素,比较之前的,直到找到自己合适的位置
4.桶排序:将数据分布到有限数量的桶里,每个桶在分别排序
1.快速排序:快速排序使用分治法把一个串(list)分为两个子串(sub-lists).具体算法实现
实现过程:1.从数组中挑出一个元素,成为一个基准
2.重新排列数组,所有元素比基准小的摆在基准前面,所有元素比基准大的摆在基准后面(相同的可以摆在一边)
这个分区退出之后,该基准就处于数列的中间位置。成为分区操作。
3.递归的把小于基准值的子数列和大于基准值元素的子数列排序
算法实现: function quickSort (arr) {
if (arr.length <= 1) {return arr}
var destIndex = Math.floor(arr.length/2)
var left = [], right = [];
var dest = arr.splice(destIndex,1)[0];
for (var i =0;i<arr.length;i++){
if (arr[i]<dest) {
left.push(arr[i])
} else {
right.push(arr[i]) }
return quickSort(left).concat([dest],quickSort(right)
2.堆排序:利用对这种数据结构所涉及的一种排序算法,堆积是一个近乎完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或大于)它的父节点。
实现过程:1.
5. Дедупликация массиваnuggets.capable/post/684490…
1.双重循环
2.indexOf
3.数组排序去重 最快你Olong
6. Струна
判断回文字符串:(递归的思想)
1.字符串分隔,倒转,聚合[...obj].reverse().join('')
2.字符串头部和尾部,逐次向中间检测
实现:function isPalindrome(line) {
line += '';
for (var i=0,j=line.length-1;i<j;i++,j--) {
if (line.chartAt(i) !== line.chartAt(j) {
return false
}
3.递归
Семь, бинарный поиск (поиск в отсортированном массиве)
二分查找可以解决已排序数组的查找问题,即只要数组中包含T(要查找的值),那么通过不断的缩小包含T的数据范围,就可以最终要找到的数
(1) 一开始,数据范围覆盖整个数组。
(2) 将数组的中间项与T进行比较,如果T比数组的中间项小,则到数组的前半部分继续查找,反之,则到数组的后半部分继续查找。
(3) 就这样,每次查找都可以排除一半元素,相当于范围缩小一半。这样反复比较,反复缩小范围,最终会在数组中找到T
代码实现:function binarySearch (data, dest, start, end){
var end = end || data.length-1;
var start = start || 0;
var m = Math.floor((start+end)/2);
if (dest<data[m]){
return binarySearch(data, dest, 0, m-1)
} else {
return binarySearch(data, dest, m+1, end)
}}
return false
рукописный код
1. Реализовать бинд вручную (принцип через apply, call)
一句话概括:1.bind()返回一个新函数,并不会立即执行。
2.bind的第一个参数将作为他运行时的this,之后的一系列参数将会在传递的实参前传入作为他的参数
3.bind返回函数作为构造函数,就是可以new的,bind时指定的this值就会消失,但传入的参数依然生效
Function.prototype.bind = function (obj, arg) {
var arg = Array.prototype.slice.call(arguments, 1);
var context = this;
var bound = function (newArg) {
arg = arg.concat(Array.prototype.slice.call(newArg);
return context.apply(obj, arg)
}
var F = function () {} // 在new一个bind会生成新函数,必须的条件就是要继承原函数的原型,因此用到寄生继承来完成我们的过程
F.prototype = context.prototype;
bound.prototype = new F();
return bound;
}
2. AJAX (асинхронный javascript и xml)
ajax的原理:相当于在用户和服务器之间加一个中间层(ajax引擎),使用户操作与服务器响应异步化。
优点:在不刷新整个页面的前提下与服务器通信维护数据。不会导致页面的重载
可以把前端服务器的任务转嫁到客服端来处理,减轻服务器负担,节省宽带
劣势:不支持back。对搜索引擎的支持比较弱;不容易调试
怎么解决呢?通过location.hash值来解决Ajax过程中导致的浏览器前进后退按键失效,
解决以前被人常遇到的重复加载的问题。主要比较前后的hash值,看其是否相等,在判断是否触发ajax
function getData(url) {
var xhr = new XMLHttpRequest(); // 创建一个对象,创建一个异步调用的对象
xhr.open('get', url, true) // 设置一个http请求,设置请求的方式,url以及验证身份
xhr.send() //发送一个http请求
xhr.onreadystatechange = function () { //设置一个http请求状态的函数
if (xhr.readyState == 4 && xhr.status ==200) {
console.log(xhr.responseText) // 获取异步调用返回的数据
}
}
}
Promise(getData(url)).resolve(data => data)
AJAX状态码:0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send方法,正在发送请求
2 - (载入完成呢)send()方法执行完成
3 - (交互)正在解析相应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
```
#### 三、函数节流(throttle)
```
function throttle (func, wait) {
var timeout;
var previous = 0;
return function () {
context = this;
args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context,args)
}, wait);
}
}
}
}
```
#### 四、函数防抖(dobounce)
```
function debounce (func, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context,args)
}, wait);
}
}
```
#### 五、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
```
Object.prototype.clone = function() {
var newObject = this.constructor === Array ? [] : {} //对象的深拷贝 获取对应的构造函数 [] 或者 {}
for (let e in this) { //遍历对象的属性 in this[e]
newObject[e] = typeof this[e] === 'object' ? this[e].clone() : this[e] //对象中的属性如果还是对象 那就继续递归 否则就返回基本的数据类型
}
return newObject
}
```
#### 六、实现一个简单的Promise https://juejin.cn/post/6844903625769091079
```
class Promise {
constructor (executor) { // executor里面有两个参数,一个叫resolve(成功),一个叫reject(失败)。
this.status = 'pending',
this.value = undefined;
this.reason = undefined;
// 成功存放的数组
this.onResolvedCallbacks = [];
// 失败存放法数组
this.onRejectedCallbacks = [];
let resolve = (value) => {
if (this.status == 'pending') {
this.status = 'resolve';
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn())
}
}
let reject = (reason) => {
if (this.status == 'pending') {
this.status = 'reject';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try{
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then (onFullFilled,onRejected) {
if (this.status == 'resolved') {
onFullFilled(this.value)
}
if (this.status == 'rejectd') {
onRejected(this.reason);
}
if (this.status == 'pending') {
this.onResolvedCallbacks.push(()=>{
onFullFilled(this.value);
})
this.onRejectedCallbacks.push(()=> {
onRejected(this.reason);
})
}
}
}
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello world')
}, 1000);
})
p.then((data) =>{
console.log(data)
},(err) =>{
console.log(err);
})
```
#### 七、发布订阅者模式(观察者模式)
```
var event = {}; // 发布者
event.clientList = [] //发布者的缓存列表
event.listen = function (fn) { // 增加订阅者函数
this.clientList.push(fn)
}
event.trigger = function () { // 发布信息
for (var i =0;i<this.clientList.length;i++) {
var fn = this.clientList[i];
fn.apply(this, arguments);
}
}
event.listen (function(time) {
console.log('正式上班时间为:' +time)
})
event.trigger ('2018/7')
```
#### 八、手动写一个node服务器
```
const http = require('http');
const fs = require('fs');
const server = http.createServer((req,res) => {
if (reu.url == '/') {
const indexFile = fs.createReadStream('./index.html')
req.writeHead(200,{'context-Type':'text/html;charset = utf8})
indexFile.pipe(res)
}
server.listen(8080)
```