предисловие
Большая часть содержания статьи представляет собой сводку некоторых знаний, и она не охватит всего, код некоторых конкретных шагов реализации и лежащих в его основе принципов не будет опубликован, иначе он будет слишком длинным.
Но не волнуйтесь, подробное объяснение соответствующих точек знаний будет опубликовано со ссылками на статьи для вашей справки. Это заметки, которые обычно пишут блоггеры, и несколько отличных сообщений в блогах, которые я прочитал. Надеюсь, они помогут вам проверить и заполните пробелы и наведите порядок в интерфейсе.Система знаний~
В статье много контента, рекомендуется сначала отметить его, а потом читать.
Во-первых, основные статьи HTML
1. Какова роль типа документа?
- DOCTYPE — это стандартное объявление веб-страницы html5, которое должно быть объявлено в первой строке HTML-документа. Чтобы сообщить синтаксическому анализатору браузера, какой стандарт документа использовать для анализа документа, различные режимы рендеринга будут влиять на анализ браузером кода CSS и даже сценариев JavaScript.
2. В чем разница между HTML, XHTML и XML?
- HTML (язык гипертекстовой разметки): до html4.0 у HTML были реализации, а затем стандарты, что приводило к очень запутанному и свободному HTML.
- XML (расширяемый язык разметки): в основном используется для хранения данных и структуры, JSON аналогичен, но более легкий и эффективный.
- XHTML (расширяемый язык гипертекстовой разметки): основан на двух предыдущих
3, понимание семантики HTML?
- Семантика: относится к использованию соответствующих семантических тегов html, таких как тег заголовка представляет заголовок, тег статьи представляет тело и т. д.
- Преимущества: улучшенная читабельность, хорошо подходит для SEO-оптимизации.
4. Общие метатеги?
- набор символов, используемый для описания закодированной формы HTML-документа
<meta charset="UTF-8" >
- http-equiv, что эквивалентно функции заголовка файла http.Например, следующий код может установить дату истечения срока действия кеша http
<meta http-equiv="expires" content="Wed, 20 Jun 2019 22:33:00 GMT">
- область просмотра, которая управляет размером и масштабом области просмотра.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
5. В чем разница между defer и async в тегах script?
- defer: После того, как скрипт загружен асинхронно, он не будет выполняться сразу, а будет выполняться после парсинга документа.
- async: выполнение сразу после загрузки скрипта
6. Способ внешнего хранилища?
- Файлы cookie: Хорошая совместимость, удобно иметь файл cookie в заголовке запроса. Недостаток в том, что размер всего 4k. Добавление файлов cookie в заголовок запроса автоматически тратит трафик. Каждый домен ограничен 20 файлами cookie. и должен быть инкапсулирован сам по себе.
- localStorage: HTML5 добавляет пару ключ-значение (Key-Value) в качестве стандартного метода. Преимущество заключается в простоте использования, постоянном хранении (если не удалено вручную), размере 5M и совместимости с IE8+.
- sessionStorage: в основном похож на localStorage, разница в том, что sessionStorage очищается при закрытии страницы и, в отличие от cookies и localStorage, не может использоваться совместно всеми окнами одного и того же источника.Это метод хранения на уровне сеанса. .
- IndexedDB: база данных NoSQL, хранящаяся с парами ключ-значение, может выполнять операции быстрого чтения, очень подходит для веб-сценариев, и очень удобно работать с JavaScript.
2. CSS-статьи
1. Блочная модель CSS
Стандартная модель: расчеты ширины и высоты не включают отступы и границы; задается box-sizing: content-box; (по умолчанию в браузере).
Модель IE: расчет ширины и высоты включает в себя отступы и рамку; задается размером окна: граница-бокс; .
2. BFC (контекст блочного форматирования)
Функции:
- Это отдельный контейнер, элементы внутри и наружных элементов не влияют друг на друга;
- Вертикальные поля BFC будут перекрываться;
- Область BFC не перекрывает область плавающего элемента;
- При расчете высоты БТЭ в расчете также участвуют плавающие элементы.
Как создать:
- значение float не равно none;
- Значение position не является статическим или относительным;
- display inline-box, table, table-cell и т. д.;
- перелив не виден
эффект:
- очистить поплавок
- Предотвращение перекрытия полей между соседними элементами в одном контейнере BFC
3. Реализовать вертикальное центрирование
- Фиксированная ширина и высота
div.parent {
position: relative;
}
div.child {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}
或
div.child {
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
- Ширина и высота не фиксированы
div.parent {
display: flex;
justify-content: center;
align-items: center;
}
或
div.parent{
display:flex;
}
div.child{
margin:auto;
}
或
div.parent {
position: relative;
}
div.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
或
div.parent {
display: grid;
}
div.child {
justify-self: center;
align-self: center;
}
Для получения дополнительных типов макетов см.:Галантерея Реализация различных типовых макетов + анализ примеров известных сайтов
4. Проанализируйте и сравните плюсы и минусы непрозрачности: 0, видимости: скрыто, отображения: нет и применимых сценариев.
- Структурно: display:none исчезнет из дерева рендеринга, элемент не будет занимать место и на него нельзя будет щелкнуть; visible: hidden не исчезнет из дерева рендеринга, элемент продолжит занимать место, но на него нельзя будет щелкнуть; opacity: 0 будет не исчезают из дерева рендеринга, элементы занимают место и кликабельны.
- Наследование: display: none и opacity: 0 не являются наследуемыми свойствами; если родительский элемент устанавливает display:none или opacity: 0, дочерний элемент не может отображаться независимо от того, как он установлен; visible: hidden будет унаследован дочерним элементом элемент, а дочерний элемент можно установить, установив для параметра visibility: visible; значение unhide.
- Производительность: display: none приведет к перераспределению, и потребление производительности будет большим; видимость: hidden вызовет перерисовку, и потребление производительности будет относительно небольшим; opacity: 0 перестроит слой, и производительность будет высокой
5. Разница между тегом ссылки и тегом импорта
- ссылка принадлежит тегу html, а @import предоставляется css;
- Когда страница загружена, ссылка будет загружена одновременно, а css, на который ссылается @import, будет загружен после загрузки страницы;
- Вес стиля ссылки выше, чем у @import;
- ссылка может быть импортирована динамически с помощью js, но @import не может;
- link Это не требует совместимости, а @import требует распознавания IE5 или выше.
6. Решение проблемы с пикселями Retina 1px на мобильных устройствах
- viewport + rem
- background-image
- Псевдоэлементы + масштаб преобразования ()
- box-shadow
Для получения дополнительной информации см.:7 способов исправить проблему с границей 1px на мобильных экранах Retina
7. Управление номером строки текстового дисплея
- одна линия
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
- Многострочный
overflow: hidden;
text-overflow: ellipsis; // 超出显示'...'
display: -webkit-box; // 将元素作为弹性伸缩盒子模型显示 。
-webkit-line-clamp: 2; // 用来限制在一个块元素显示的文本的行数
-webkit-box-orient: vertical; // 设置或检索伸缩盒对象的子元素的排列方式
8. Способ очистки поплавка
1、
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
2、clear:both
3、overflow:hidden
9. В чем разница между переходом и анимацией?
- переход: используется для эффектов перехода, без концепции кадра, только начальное и конечное состояния, с низкими потерями производительности.
- animate: используется для анимации, имеет концепцию кадров, может запускаться многократно и имеет промежуточные состояния, а накладные расходы на производительность велики.
10. Реализовать сектор
.sector {
width: 0;
height: 0;
border-width: 50px;
border-style: solid;
border-color: red transparent transparent;
border-radius: 50px;
}
3. JS-статьи
1. Встроенные типы JS
- Основные типы: null, undefined, boolean, число, строка, символ.
- Объект: Тип ссылки
подсказки: NaN также имеет тип number, и NaN не равен самому себе.
2. Типовая оценка
- Typeof
console.log(typeof 1); // number
console.log(typeof 'a'); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof function fn(){}); // function
console.log(typeof {}); // object
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof new Error()); // object
Советы: typeof Для базовых типов, кроме null, может отображаться правильный тип, для объектов, кроме функций, отображается object
- Object.prototype.toString
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
function checkType() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]))
}
}
checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)
Для получения дополнительной информации см.:JavaScript учится на прошлом — суждение о типах
3. Понимание прототипа и цепочки прототипов
- Прототип: каждая функция имеет свойство прототипа, которое указывает на объект-прототип; преимущество использования объекта-прототипа заключается в том, что все экземпляры объекта имеют общие свойства и методы, которые он содержит.
- Цепочка прототипов: в основном решает проблему наследования, каждый объект имеет объект-прототип, указывает на свой объект-прототип через указатель __proto__ и наследует от него методы и свойства, а объект-прототип также может иметь прототип, указывает на null.
- На следующей диаграмме показаны отношения между конструкторами, объектами-прототипами, экземплярами и цепочками прототипов:
Для получения дополнительной информации см.:JavaScript освежает прошлое — прототипы и цепочки прототипов
4. Контекст выполнения
- глобальный контекст выполнения
- контекст выполнения функции
- eval контекст выполнения
Для получения дополнительной информации см.:JavaScript обновляется и изучает новые вещи — среду выполнения и область действия
5. Закрытие
- Замыкание — это функция, которая имеет доступ к переменным в области видимости другой функции.
- Замыкания будут удерживать переменные внутри функции в памяти, вызывая большие накладные расходы памяти, поэтому не злоупотребляйте замыканиями. Решение состоит в том, чтобы присвоить неиспользуемым локальным переменным значение null перед выходом из функции;
Классический вопрос на собеседовании: измените следующий код так, чтобы он выводил от 0 до 9.
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
方法一、利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
for (var i = 0; i < 10; i++) {
setTimeout(i => {
console.log(i);
}, 1000, i)
}
方法二、使用 let 变量 的特性
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1000)
}
等价于
for (let i = 0; i < 10; i++) {
let _i = i;// const _i = i;
setTimeout(() => {
console.log(_i);
}, 1000)
}
方法三、利用函数自执行的方式,把当前 for 循环过程中的 i 传递进去,构建出块级作用域。
for (var i = 0; i < 10; i++) {
(i => {
setTimeout(() => {
console.log(i);
}, 1000)
})(i)
}
6. Проблема, на которую указывает это
На что это указывает, зависит от того, как была вызвана функция:
- Вызов функции действия: это указывает на глобальный объект в нестрогом режиме и не определено в строгом режиме.
- Вызов метода действия: это указывает на объект, вызывающий функцию
- Вызов конструктора: это указывает на объект экземпляра, созданный новым
- Call() и Apply: их первый параметр — это точка point.
Для получения подробной информации см.:JavaScript учится новому из прошлого — 4 способа вызова функций
- Добавлено: это в функциях стрелок
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
Стрелочные функции на самом деле не имеют this.this в этой функции зависит только от this первой функции вне нее, которая не является стрелочной функцией. В этом примере, поскольку вызов соответствует первому случаю в предыдущем коде, это окно. И это, однажды привязанное к контексту, не будет изменено никаким кодом.
7. Реализация вызова и применения
Function.prototype.call2 = function(context) {
var context = context || window;
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args + ')');
delete context.fn
return result;
}
Function.prototype.apply = function (context, arr) {
var context = Object(context) || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
}
else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
Подробнее о реализации см.:JavaScript узнает что-то новое из прошлого — реализация call() и apply()
8. Реализация связывания
Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new TypeError("error");
}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
// 通过一个空函数作一个中转,避免绑定函数的 prototype 的属性被修改
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}
Подробнее о реализации см.:JavaScript учится на прошлом — реализация метода bind()
9. Принцип реализации новых
Что делает новый оператор?
- Создать пустой объект
- Затем пусть __proto__ этого пустого объекта указывает на прототип функции.
- Выполнить код в конструкторе, this в конструкторе указывает на объект
- Если конструктор имеет возвращаемое значение, в качестве возвращаемого значения используется объект. Если возврата нет или возвращается примитивный тип, новый объект используется в качестве возвращаемого значения.
function objectFactory() {
var obj = new Object(),
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
var ret = Constructor.apply(obj, arguments);
return typeof ret === 'object' ? ret : obj;
};
Подробнее о реализации см.:JavaScript учится новому из прошлого — реализация нового оператора
9. Реализация instanceof
function instance_of(L, R) {
//L 表示左表达式,R 表示右表达式
var O = R.prototype; // 取 R 的显示原型
L = L.__proto__; // 取 L 的隐式原型
while (true) {
if (L === null) return false;
if (O === L)
// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
10. Глубокое и поверхностное копирование
- Неглубокая копия — если элементы копируемого объекта относятся к примитивным типам, копия будет сделана, не затрагивая друг друга. И если элемент скопированного объекта является объектом или массивом, будет скопирована только ссылка на объект и массив.В это время, если модификация производится на старом и новом объектах, они будут влиять друг на друга.
// 数组浅拷贝:slice()、concat()
// 对象浅拷贝:Object.assign()、ES6的扩展运算符
- Глубокая копия — полностью копирует объект, даже если объект вложен, оба разделены, изменяют свойства объекта и не влияют друг на друга.
// 递归实现
function clone(source) {
var target = {};
for(var i in source) {
if (source.hasOwnProperty(i)) {
if (typeof source[i] === 'object') {
target[i] = clone(source[i]); // 如果是引用类型,则继续遍历
} else {
target[i] = source[i];
}
}
}
return target;
}
Разумеется, это всего лишь простая реализация, без учета особых случаев, таких как функции в объектах или массивах, обычные копии специальных типов и т.п.
// JSON.parse(JSON.stringify)
var arr = [
{ value: 1 },
{ value: 2 },
{ value: 3 }
];
var copyArr = JSON.parse(JSON.stringify(arr))
copyArr[0].value = 0;
console.log(arr); // [{value: 1}, { value: 2 }, { value: 3 }]
console.log(copyArr); // [{value: 0}, { value: 2 }, { value: 3 }]
Вышеописанный метод прост и груб, но его недостаток в том, что функцию нельзя скопировать.
Для получения дополнительных сведений о реализации глубокого копирования вы можете обратиться к:Окончательный поиск глубокого копирования (90% людей не знают)
11. Реализация антишейка и троттлинга (простой вариант)
- Anti-shake: функция будет выполняться только один раз в течение n секунд после срабатывания высокочастотного события.Если высокочастотное событие запускается снова в течение n секунд, время будет пересчитано
funtion debounce(fn) {
// 创建一个标记用来存放定时器的返回值
let timeout = null;
return function() {
// 每次触发事件时都取消之前的延时调用方法
clearTimeout(timeout);
// 然后又创建一个新的 setTimeout, 这样就能保证 1000ms 间隔内如果重复触发就不会执行 fn 函数
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, 1000);
};
}
- Регулирование: высокочастотные события запускаются, но выполняются только один раз в n секунд, поэтому регулирование снижает частоту выполнения функции.
function throttle(fn) {
// 通过闭包保存一个标记
let canRun = true;
return function(){
// 每次开始执行函数时都先判断标记是否为 true,不为 true 则 return
if (!canRun) return;
// 上一次定时器执行完后 canRun 为 true,所以要先设置为false
canRun = false;
setTimeout(() => {
fn.apply(this, arguments);
// 最后在 setTimeout 执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false,在开头被 return 掉
canRun = true;
}, 1000)
}
}
12. Реализация наследования ES5
// 组合继承
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
console.log(this.age);
}
13. История развития, преимущества и недостатки асинхронных решений JS
- функция обратного вызова
ajax('XXX1', () => {
// callback 函数体
ajax('XXX2', () => {
// callback 函数体
ajax('XXX3', () => {
// callback 函数体
})
})
})
Преимущество: решить проблему синхронизации
Недостатки: ад обратных вызовов, невозможность отлова ошибок с помощью try catch, невозможность возврата
- Promise
ajax('XXX1')
.then(res => {
// 操作逻辑
return ajax('XXX2')
}).then(res => {
// 操作逻辑
return ajax('XXX3')
}).then(res => {
// 操作逻辑
})
Преимущество: решает проблему callback hell
Недостатки: обещание не может быть отменено, ошибки должны быть пойманы по функции обратного вызова
- Generator
function *fetch() {
yield ajax('XXX1', () => {})
yield ajax('XXX2', () => {})
yield ajax('XXX3', () => {})
}
let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()
// 配合 co 库使用
const co = require('co')
function *fetch() {
yield ajax('XXX1', () => {})
yield ajax('XXX2', () => {})
yield ajax('XXX3', () => {})
}
co(fetch()).then(data => {
//code
}).fetch(err => {
//code
})
Преимущества: Может контролировать выполнение функций, взаимодействовать с автоматическими исполнителямисомодульУпрощенные ручные шаги
Недостаток: неудобно использовать без библиотеки ко-функций.
- async/await
// async其实是一个语法糖,它的实现就是将 Generator 函数和自动执行器(co),包装在一个函数中
async function test() {
// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
// 如果有依赖性的话,其实就是解决回调地狱的例子了
await fetch('XXX1')
await fetch('XXX2')
await fetch('XXX3')
}
read().then((data) => {
//code
}).catch(err => {
//code
});
Достоинства: Код понятен, не нужно писать много потом цепочек типа промисов, решена проблема callback hell
Недостатки: await трансформирует асинхронный код в синхронный, если несколько асинхронных операций не имеют зависимостей, использование await приведет к падению производительности.
14. Разница между setTimeout, Promise, Async/Await
Для этой проблемы мы должны сначала понять механизм цикла обработки событий JS.Рекомендуется сначала прочитать эту статью:На этот раз досконально изучите механизм выполнения JavaScript.
- setTimeout — функция обратного вызова setTimeout будет помещена в очередь задач макроса и выполнена после того, как стек выполнения будет опустошен.
console.log('script start') //1. 打印 script start
setTimeout(function() {
console.log('settimeout') // 4. 打印 settimeout
}) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end') //3. 打印 script start
// 输出顺序:script start->script end->settimeout
- Promise — сам по себе Promise является синхронной функцией немедленного выполнения.Когда в экзекьюторе выполняется resolve или reject, это асинхронная операция. Тогда сначала будет выполняться /catch, а после завершения основного стека будет вызываться resolve/reject. сохраненный метод выполняется.
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function() {
console.log('settimeout')
})
console.log('script end')
// 输出顺序: script start->promise1->promise1 end->script end->promise2->settimeout
- async/await — асинхронная функция возвращает объект Promise.Когда функция выполняется, как только она сталкивается с ожиданием, она сначала возвращается и ждет, пока запущенная асинхронная операция не будет завершена, а затем выполняет оператор за телом функции. Это можно понимать как отказ от потока и выпрыгивание из тела асинхронной функции.
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:script start->async1 start->async2->script end->async1 end
15. Простая реализация промисов
Использование промисов (подробное использование промисов см.Документация Ruan Yifeng по ES6)
var promise = new Promise((resolve,reject) => {
if (操作成功) {
resolve(value)
} else {
reject(error)
}
})
promise.then(function (value) {
// success
},function (value) {
// failure
})
Простая реализация
function myPromise(constructor) {
let self = this;
self.status = "pending" // 定义状态改变前的初始状态
self.value = undefined; // 定义状态为resolved的时候的状态
self.reason = undefined; // 定义状态为rejected的时候的状态
function resolve(value) {
if(self.status === "pending") {
self.value = value;
self.status = "resolved";
}
}
function reject(reason) {
if(self.status === "pending") {
self.reason = reason;
self.status = "rejected";
}
}
// 捕获构造异常
try {
constructor(resolve,reject);
} catch(e) {
reject(e);
}
}
Добавьте метод then
myPromise.prototype.then = function(onFullfilled,onRejected) {
let self = this;
switch(self.status) {
case "resolved":
onFullfilled(self.value);
break;
case "rejected":
onRejected(self.reason);
break;
default:
}
}
var p = new myPromise(function(resolve,reject) {
resolve(1)
});
p.then(function(x) {
console.log(x) // 1
})
Рекомендуется более подробно ознакомиться с принципом Promise.Принцип реализации обещания (с исходным кодом), Эта статья очень подробная и простая для понимания.
16. История развития модуляризации интерфейса
- IIFE: используйте самовыполняющиеся функции для написания модульности, возможности: выполнение кода в отдельной области действия, чтобы избежать конфликтов переменных.
(function(){
return {
data:[]
}
})()
- AMD: Используйте requireJS для написания модульности, особенность: зависимости должны быть объявлены заранее.
define('./index.js',function(code){
// code 就是index.js 返回的内容
})
- CMD: Используйте seaJS для написания модуляризации. Особенности: Для зависимых модулей выполнение откладывается, и зависимости могут быть записаны рядом. Когда зависимости необходимы, зависимости могут быть введены, а файлы зависимостей могут быть динамически импортированы.
define(function(require, exports, module) {
var indexCode = require('./index.js');
});
- CommonJS: модульность, которая приходит с nodejs.
var fs = require('fs');
- Модули ES: модульность, представленная ES6, поддерживает импорт для импорта другого js.
import a from 'a';
17. В чем разница между модулями ES6 и модулями CommonJS?
- Когда модули ES6 компилируются, они могут определять зависимости модулей, а также входные и выходные переменные; модули CommonJS загружаются во время выполнения.
- Модули ES6 автоматически используют строгий режим, независимо от того, «использовать строгий»;
- require может выполнять динамическую загрузку, а оператор импорта - нет. Оператор импорта должен находиться в области видимости верхнего уровня.
- Верхний уровень this в модулях ES6 указывает на undefined, а верхний уровень this в модулях CommonJS указывает на текущий модуль.
- Модули CommonJS выводят копию значения, модули ES6 выводят ссылку на значение.
4. Основы сети
1. Основные возможности протокола HTTP
- Простой, быстрый, гибкий, без подключения, без сохранения состояния
2. Компоненты HTTP-сообщения
- Сообщение запроса:
- Строка запроса (метод http + адрес страницы + протокол http + версия)
- Заголовок запроса (ключ + значение)
- Пустая строка (сервер использует пустую строку, чтобы определить, что следующая часть больше не является заголовком запроса, а анализируется как тело запроса)
- Тело запроса (часть данных)
- Ответное сообщение: строка состояния ответа + пробел + заголовок + тело ответа
3. HTTP-метод
- ПОЛУЧИТЬ => получить ресурс
- POST => передать ресурс
- PUT => обновить ресурс
- УДАЛИТЬ => удалить ресурс
- HEAD => получить заголовок сообщения
4. Разница между POST и GET
- GET безвреден, когда браузер отступает, а POST снова отправляет запрос *
- Запросы GET будут активно кэшироваться браузером, а запросы POST — нет, если только они не установлены вручную *
- Параметры запроса GET будут полностью сохранены в истории браузера, а параметры POST не будут сохранены *
- Параметры, отправляемые в URL-адресе для GET-запросов, ограничены по длине, в то время как POST не имеет ограничений *
- GET-параметры передаются через URL, а POST помещается в тело запроса *
- Запросы GET могут быть закодированы только в URL-адресе, а POST поддерживает несколько методов кодирования.
- URL-адрес, сгенерированный GET, можно добавить в закладки, но POST нельзя.
- Для типа данных параметра GET принимает только символы ASCII, а POST не имеет ограничений.
- GET менее безопасен, чем POST, потому что параметры отображаются непосредственно в URL-адресе, поэтому его нельзя использовать для передачи конфиденциальной информации.
5. Код состояния HTTP
-
1xx: Информация об индикации — указывает, что запрос принят, продолжить обработку
-
2xx: Успех — указывает, что запрос был успешно принят.
- 200: ОК, что указывает на то, что запрос от клиента корректно обрабатывается на стороне сервера.
- 204: Нет содержимого, что указывает на то, что запрос выполнен успешно, но ответное сообщение не содержит основной части объекта.
- 205: сбросить содержимое, указывающее, что запрос выполнен успешно, но ответное сообщение не содержит основной части объекта, но отличается от ответа 204 тем, что запрашивающая сторона должна сбросить содержимое.
- 206: частичное содержимое, клиент отправляет запрос GET с заголовком Range, и сервер завершает его (например, запрашивая файлы большего размера, такие как воспроизведение аудио- и видеоадресов с тегами vedie или аудиотегами)
-
3xx: перенаправление — для выполнения запроса требуются дальнейшие действия.
- 301: перемещен навсегда, постоянное перенаправление, указывающее, что ресурсу был присвоен новый URL-адрес.
- 302: найдено временное перенаправление, указывающее на то, что ресурсу временно присвоен новый URL
- 303: см. другое, указывающее, что для ресурса существует другой URL-адрес, и для получения ресурса следует использовать метод GET.
- 304: не изменен, что указывает на то, что сервер разрешает доступ к ресурсу, но запрос не соответствует условиям из-за возникновения
- 301: временное перенаправление, похожее на 302, но ожидает, что клиент сохранит метод запроса без изменений и отправит запрос на новый адрес.
-
4xx: Ошибка клиента — запрос имеет синтаксическую ошибку или запрос не может быть выполнен
- 400: неверный запрос, в сообщении запроса есть синтаксическая ошибка
- 401: неавторизованный, что указывает на то, что для отправленного запроса требуется аутентификационная информация, прошедшая HTTP-аутентификацию.
- 403: запрещено, что указывает на то, что доступ к запрошенному ресурсу был запрещен сервером
- 404: не найдено, что указывает на то, что запрошенный ресурс не найден на сервере.
-
5xx: Ошибка сервера — серверу не удалось выполнить допустимый запрос.
- 500: внутренняя ошибка сервера, указывающая на то, что при выполнении запроса произошла ошибка на стороне сервера.
- 501: не реализовано, что указывает на то, что сервер не поддерживает функцию, требуемую текущим запросом.
- 503: служба недоступна, что указывает на то, что сервер временно перегружен или отключен для обслуживания и не может обрабатывать запросы.
6. Понимание трехстороннего рукопожатия TCP и четырехсторонней волны
Трехстороннее рукопожатие и четырехсторонняя волна могут имитировать процесс вызова по рации
- Трехстороннее рукопожатие:
A: 你好,我是A
B:收到,我是B
A:好的,我们可以开始通话啦
- Четыре волны:
A:我已经没什么话说了,结束通话吧
B:稍等,我还有最后一句话要说
B:我已经说完啦
A:好的,你可以关掉对讲机了,不用回复了(然后A等待2MSL无回复,也关掉对讲机)
Для получения более подробной информации см.:Интервью -- Сеть TCP/IP
7. HTTPS
HTTPS по-прежнему передает информацию через HTTP, но информация шифруется через протокол TLS.
Шифрование в TLS:
- Симметричное шифрование — обе стороны имеют одинаковый ключ, и обе стороны знают, как шифровать и расшифровывать зашифрованный текст.
- Асимметричное шифрование — есть открытый и закрытый ключи, открытый ключ может знать каждый, и данные могут быть зашифрованы с помощью открытого ключа, но данные должны быть расшифрованы с использованием закрытого ключа, а закрытый ключ может быть известен только стороне который распространял открытый ключ.
Процесс рукопожатия HTTPS:
- На первом этапе клиент сообщает номер версии протокола, случайное число, сгенерированное клиентом (Client random), и метод шифрования, поддерживаемый клиентом.
- На втором этапе сервер подтверждает метод шифрования, используемый обеими сторонами, и предоставляет цифровой сертификат и случайное число (Server random), сгенерированное сервером.
- На третьем этапе клиент подтверждает, что цифровой сертификат действителен, затем генерирует новое случайное число (Premaster secret) и использует открытый ключ в цифровом сертификате для шифрования случайного числа и отправки его на сервер.
- На четвертом этапе сервер использует свой собственный закрытый ключ для получения случайного числа (т. е. секрета Premaster), отправленного клиентом.
- На пятом этапе клиент и сервер используют три предыдущих случайных числа для генерации «сеансового ключа» в соответствии с согласованным методом шифрования, который используется для шифрования всего последующего диалогового процесса.
7. Особенности HTTP 2.0
- Двоичная передача: вся передаваемая информация разбивается на более мелкие сообщения и кадры и кодируется в двоичном формате.
- Мультиплексирование: несколько запросов могут быть отправлены в одном TCP-соединении.
- Сжатие заголовка
- Сервер Push: сервер может дополнительно передавать ресурсы клиенту без явного запроса клиента.
http1.0 http1.1 http2.0 особенности и отличия
8. Процесс ввода пользователем URL для рендеринга страницы
- Пользователь вводит URL
- Браузер ищет IP-адрес доменного имени Разрешение доменного имени (разрешение DNS)
- Найдя IP-адрес, установите трехстороннее рукопожатие TCP и установите соединение с целевым сервером.
- После успешного рукопожатия через указанный протокол (http) браузер отправляет http-запрос целевому хосту, запрашивая пакеты данных
- Сервер обрабатывает полученный запрос и возвращает данные в браузер
- Браузер получает ответное сообщение HTTP
- Закройте соединение. Браузер анализирует документ.
- Чтение содержимого страницы, рендеринг в браузере, разбор исходного кода html
- Создание дерева Dom, анализ стиля css, взаимодействие с js
- В процессе генерации дерева рендеринга браузер начинает вызывать GPU для отрисовки, синтеза слоя и отображения содержимого на экране.
5. Браузеры и веб-безопасность
1. Механизм события
- Три этапа срабатывания события:
捕获阶段 —— window 往事件触发处传播,遇到注册的捕获事件会触发
目标阶段 —— 传播到事件触发处时触发注册的事件
冒泡阶段 —— 从事件触发处往 window 传播,遇到注册的冒泡事件会触发
- Конкретный процесс захвата событий DOM:
window对象 => document对象 => html标签 => body标签 => ... => 目标元素(冒泡反之)
- Общие применения объектов событий
event.preventDefault() // 阻止默认事件,例如a标签的跳转行为
event.stopPropagation() // 阻止冒泡
event.stopImmediatePropagation() // 事件响应优先级:例如同一元素绑定不同事件时,触发a事件不让b事件触发
event.currentTarget // 当前绑定事件的元素
event.target // 当前被点击的元素
2. Междоменный
Та же политика происхождения:
- Когда браузер выходит считать ограничения по безопасности, есть разница в протоколе, доменном имени и порте, который является междоменным.В это время не могут быть отправлены Ajax-запросы, не могут быть получены Cookie, LocalStorage и IndexDB, и DOM не может быть получен.
Несколько решений по доменам:
- JSONP — эксплойт
<script>Ярлык не имеет функции междоменного ограничения, через<script>Тег указывает на адрес, к которому необходимо получить доступ, и предоставляет функцию обратного вызова для получения данных.
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script>
<script>
function jsonp(data) {
console.log(data)
}
</script>
Оберните метод jsonp
function jsonp({url, params, cb}) {
return new Promise((resolve, reject) => {
//创建script标签
let script = document.createElement('script');
//将回调函数挂在 window 上
window[cb] = function(data) {
resolve(data);
//代码执行后,删除插入的script标签
document.body.removeChild(script);
}
//回调函数加在请求地址上
params = {...params, cb}
let arrs = [];
for(let key in params) {
arrs.push(`${key}=${params[key]}`);
}
script.src = `${url}?${arrs.join('&')}`;
document.body.appendChild(script);
});
}
//使用
function sayHi(data) {
console.log(data);
}
jsonp({
url: 'http://localhost:3000/say',
params: {
//code
},
cb: 'sayHi'
}).then(data => {
console.log(data);
});
- CORS - настройки сервера
Access-Control-Allow-OriginCORS можно включить. Этот атрибут указывает, какие доменные имена могут получить доступ к ресурсу. Если установлен подстановочный знак, это означает, что все веб-сайты могут получить доступ к ресурсу. - document.domain — применяется только к тому же доменному имени второго уровня, например
a.test.comа такжеb.test.com, просто добавьте на страницуdocument.domain = 'test.com'Указывает, что доменные имена второго уровня одинаковы для обеспечения междоменного доступа. - postMessage — новый метод междоменной связи H5, например, окно A (http:A.com) отправляет информацию в междоменное окно B (http:B.com)
# 在A中发送数据
window.postMessage('data', 'http://B.com');
# 在窗口B中监听
window.addEventListener('message', function(event){
console.log(event.origin);
console.log(event.source);
console.log(event.data);
}, false)
- Хэш: часть после «#» в URL-адресе не будет обновлять страницу при изменении хеша.
# 使用场景:当页面A通过iframe或frame嵌入了跨域的页面B
# 在A中的代码:
var B = document.getElementByTagName('iframe');
B.src = B.src + '#' + 'data';
# 在B中的代码:
window.onhashchange = function () {
var data = window.location.hash;
}
3. Механизм рендеринга
- Процесс рендеринга в браузере:
- Обработка HTML и построение дерева DOM
- Обработать CSS Построить дерево правил CSS
- Объедините дерево DOM и дерево правил CSS в одно дерево рендеринга.
- Макет в соответствии с деревом рендеринга и расчет положения каждого узла
- Вызовите графический процессор, чтобы нарисовать, скомпоновать слой и отобразить его на экране.
- Перекрасить и переплавить
- Перерисовка — когда узлу необходимо изменить свой внешний вид, не влияя на макет, например, изменить цвет.
- Reflow — необходимо изменить макет или свойства геометрии
- Когда происходит перерисовка и перекомпоновка (перерисовка обязательно произойдет, а перерисовка не обязательно вызывает перекомпоновку.)
- Добавить или удалить видимые элементы DOM
- Положение элемента меняется
- Изменяются размеры элемента (включая поля, внутренние границы, размер границы, высоту и ширину и т. д.)
- Изменения содержимого, такие как изменение текста или замена изображения другим изображением другого размера.
- Изменяется размер окна браузера (поскольку перекомпоновка вычисляет положение и размер элементов на основе размера области просмотра)
- Уменьшите количество перерисовок и перекомпоновок
- Используйте перевод вместо топа
- Используйте видимость вместо display: none , потому что первая вызывает только перерисовку, а вторая вызывает перекомпоновку (меняет макет).
- Измените DOM в автономном режиме, например: сначала задайте отображение DOM: none (с перекомпоновкой), затем вы измените его 100 раз, а затем снова отобразите.
- Не помещайте значение свойства узла DOM в цикл как переменную в цикле.
- Не используйте макет таблицы, небольшое изменение может привести к перестановке всей таблицы.
- Выбор скорости реализации анимации, чем быстрее скорость анимации, тем больше время перекомпоновки, вы также можете использовать
requestAnimationFrame - Селекторы CSS ищутся справа налево, чтобы избежать слишком глубокой глубины DOM.
- Превратите часто выполняемые анимации в слои, которые предотвратят перекомпоновку узла и влияние на другие элементы. Например, для тега видео браузер автоматически превратит узел в слой.
Дополнительные сведения о перерисовке и перекомпоновке см. по адресу:Вы действительно понимаете reflow и redraw?
4. Механизм кэширования браузера
Принцип кэширования — запрошенные ресурсы сохраняются на локальном диске, и при следующем получении ресурсов они считываются напрямую с диска, а не отправляются запросы на сервер.
Классификация кэша:
- Сильная кэширование - реализуется через два заголовков ответа:
Expiresа такжеCache-Control. Сильный кеш означает, что в течение периода кеша не требуется никаких запросов, а код состояния равен 200.
Expires: Wed, 22 Oct 2018 08:41:00 GMT
// Expires 是 HTTP / 1.0 的产物,表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。
// 并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。
Cache-control: max-age=30
// Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires 。该属性表示资源会在 30 秒后过期,需要再次请求。
- Кэш согласования. Если срок действия кеша истекает, мы можем использовать кеш согласования для решения проблемы. Согласование кеша требует запроса и возвращает 304, если кеш действителен.
Согласованное кэширование требует совместной реализации как клиента, так и сервера.
-
Last-Modifiedа такжеIf-Modified-Since- представляет дату последней модификации локального файла,If-Modified-SinceбудуLast-ModifiedЗначение отправляется на сервер, запрашивая сервер, был ли ресурс обновлен после даты, и если есть обновление, новый ресурс будет отправлен обратно. (Однако, если вы откроете файл в локальном кеше, это вызоветLast-Modifiedбыл изменен, поэтому появился в HTTP/1.1ETag. ) -
ETagа такжеIf-None-Match——ETagПодобно снятию отпечатков файлов,If-None-Matchбудет текущимETagОтправлено на сервер для запроса ресурсаETagЕсть ли изменение, если есть изменение, новый ресурс будет отправлен обратно. а такжеETagсоотношение приоритетовLast-Modifiedвысоко
-
Чтобы узнать больше о механизме кэширования браузера, см.:Глубокое понимание механизма кэширования браузера.
5. Веб-безопасность
XSS
- Основная концепция: XSS, также известная как атака с использованием междоменных сценариев, английское название Межсайтовый сценарий.
- Как атаковать: внедрить вредоносные теги или js-код на страницу, чтобы атаковать веб-сайт.
- Как защититься: сделать злонамеренно вставленные теги или код js неисполняемыми, например экранировать содержимое ввода и вывода.
CSRF
- Основная концепция: CSRF, также известная как подделка межсайтовых запросов, английское название Подделка межсайтовых запросов
- Как атаковать: используйте состояние входа пользователя для инициирования вредоносных запросов.
- Как защищаться:
- Запросы Get не изменяют данные
- Запретить сторонним сайтам доступ к пользовательским файлам cookie
- Интерфейс запроса блокировки стороннего веб-сайта
- Запрос сопровождается проверочной информацией, такой как проверочный код или токен.
Для получения дополнительной информации о веб-безопасности см.:[Интервью] Веб-безопасность, которую вы должны знать при приеме на работу зимой
6. Оптимизация производительности
1. Связанные с сетью
- Предварительное разрешение DNS
<link rel="dns-prefetch" href="//host_name_to_prefetch.com" />
- Кэширование (см. Механизмы кэширования браузера выше)
- Используйте HTTP/2.0
- Предварительная загрузка - может задержать загрузку некоторых важных файлов, которые не влияют на первый экран, но могут сократить время загрузки первого экрана, недостатком является плохая совместимость.
<link rel="preload" href="http://example.com" />
- Предварительный рендеринг — предварительный рендеринг файлов для загрузки в фоновом режиме.
<link rel="prerender" href="http://example.com" />
2. Оптимизируйте процесс рендеринга
- Оптимизация на уровне кода (о том, как уменьшить перерисовку и перекомпоновку, см. в статье о браузере)
- Ленивое выполнение — используйте некоторую логику, а затем выполняйте ее, которую можно разбудить таймерами или событиями.
- Отложенная загрузка — задержка загрузки некритических ресурсов, таких как изображения, видеоресурсы и т. д.
3. Оптимизация файлов
Оптимизация изображения:
- Старайтесь не использовать изображения, если вместо этого вы можете использовать симуляцию css.
- Маленькие изображения в формате base64
- Спрайт
- Выберите правильный формат изображения
- Выберите формат WebP, размер небольшой, недостатком является плохая совместимость.
- Используйте PNG для эскизов и SVG для значков.
- Фотографии используют JPEG
Другие оптимизации файлов:
- CSS-файл в
headсередина - Включить сжатие файлов на сервере
- Поместите тег сценария внизу тела, потому что выполнение файла JS заблокирует рендеринг.
- файлы сценариев загружаются асинхронно
- defer: добавьте атрибут defer в тег скрипта. Отсрочка будет выполнена после разбора HTML. Если их несколько, они будут выполняться в порядке загрузки.
- async: добавьте атрибут async в тег скрипта, async выполняется сразу после загрузки, если их несколько, порядок выполнения не имеет ничего общего с порядком загрузки
- Для кода, который требует много времени для вычисления, рассмотрите возможность использования Webworker, который позволяет нам открывать отдельный поток для выполнения скриптов, не влияя на рендеринг.
- Используйте CDN
4. Другое
Оптимизируйте свой проект с помощью Webpack:
- Для Webpack4 используйте производственный режим для проектов упаковки, который автоматически включает сжатие кода.
- Включить встряхивание дерева, чтобы удалить неиспользуемый код
- Оптимизируйте изображение, для маленького изображения вы можете использовать метод base64 для записи в файл
- Разделите код в соответствии с маршрутом, чтобы обеспечить загрузку по требованию.
- Добавьте хэш к имени упакованного файла, чтобы реализовать файл кеша браузера.
Мониторинг ошибок:
- Немедленная ошибка запуска
- try...catch
- window.onerror
- ошибка загрузки ресурса
- object.onerror
- в расширенном браузере
performance.getEntries()Вы можете получить ресурсы, которые были загружены, а затем отслеживать ресурсы, которые не загружаются.
- Ошибка выполнения междоменного js — добавьте атрибут crossorigin в тег скрипта, а затем установите заголовок ответа js-ресурса Access-Control-Allow-Origin
- Создайте файл sourceMap при упаковке для облегчения отладки.
отчет об ошибке:
- Способ коммуникационного отчета с использованием Ajax
- Сделайте запрос через src тега img.
7. Рамки
1. Как понять паттерн MVVM?
Как следует из названия, шаблон Model-View-ViewModel
- Вид: интерфейс
- Модель: модель данных
- ViewModel: как мост, отвечающий за связь View и Model.
преимущество:
- Разделите представление и модель, чтобы уменьшить связанность кода и улучшить повторное использование представления или логики.
- Автоматически обновлять DOM, избегая частых манипуляций с DOM
- Улучшить тестируемость
недостаток:
- Баги сложно отлаживать, например, некоторые инструкции написаны на View, но отлаживать их средствами отладки нет возможности.
- Когда модуль больше, модель также становится больше, что, вероятно, приведет к увеличению накладных расходов памяти.
- Для крупномасштабной иерархии графических приложений существует множество состояний представления, а затраты на создание и обслуживание ViewModel также будут высокими.
2. Принцип отзывчивости Vue
Vue использует метод захвата данных в сочетании с режимом публикации-подписки, перехватывает установщик и получатель каждого свойства через Object.defineProperty(), публикует сообщения подписчикам при изменении данных и запускает соответствующий обратный вызов мониторинга.
- Наблюдатель обходит объекты данных, добавляет сеттеры и геттеры ко всем свойствам и отслеживает изменения данных.
- компиляция анализирует инструкцию шаблона, заменяет переменные в шаблоне данными, затем инициализирует представление страницы рендеринга, привязывает функцию обновления к узлу, соответствующему каждой инструкции, и добавляет подписчиков, которые отслеживают данные. и обновить вид
- Подписчик Watcher является связующим звеном между Observer и Compile, основные действия:
- Добавьте себя к подписчику свойства (dep) при его создании
- Когда свойство изменяет уведомление dep.notice(), вызывается его собственный метод update() и активируется связанный обратный вызов в Compile.
Аналоговая реализация может относиться кВопрос из интервью: можете ли вы написать двустороннюю привязку данных для Vue?, код не будет размещен здесь.
3. Принцип виртуального ДОМ (Virtual Dom)
- Объект DOM достигается по моделированию JS
- Алгоритм сравнения дерева Dom, сравнение одного и того же уровня (поскольку элементы DOM редко перемещаются между уровнями в реальном бизнесе), необходимо оценить три ситуации.
- нет нового узла, ничего не делать
- Имя тега и ключ нового узла отличаются от старого, и узел заменяется напрямую.
- Имя тега и ключ нового узла (может не быть) такие же, как у старого, затем оцените, изменился ли атрибут, и продолжайте обход поддерева.
- Определить, изменилось ли свойство
- Повторите старый список свойств, чтобы увидеть, существует ли каждое свойство в новом списке свойств.
- Проверьте новый список атрибутов, чтобы определить, изменялись ли существующие значения атрибута (и проверьте, появляются ли новые атрибуты)
- Определить, изменилось ли свойство
- Различия в рендеринге
- Разницу между двумя деревьями можно получить с помощью алгоритма diff
- Глубоко пройдитесь по дереву и обновите DOM в соответствии с разницей
Существует также алгоритм сравнения списков при обходе дочерних узлов, который направлен наkeyИ обрабатываются узлы, в которых одновременно существуют старый и новый списки. Когда дочерние узлы просто меняют свои позиции, если они сравниваются в соответствии с одним и тем же уровнем, они будут заменены, что приведет к большим накладным расходам DOM, и алгоритм сравнения списка будет перемещать узлы для обновления DOM, сравнивая порядок старые и новые списки узлов. , в некоторых случаях могут играть определенную роль в оптимизации производительности.
Подробную реализацию кода Virtual Dom см. по адресу:Глубокий анализ: как реализовать алгоритм виртуального DOM
4. Принцип фронтальной маршрутизации
Важно: следите за изменениями URL, а затем сопоставляйте правила маршрутизации, не обновляя страницу.
Метод реализации:
- На основе Hash - лучшая совместимость, но наличие '#' не красиво
- Нажмите, чтобы перейти или перейти в историю браузера: вызвать событие изменения хэша -> проанализировать URL-адрес -> сопоставить с соответствующим правилом маршрутизации
- Ручное обновление: инициировать событие загрузки -> ...
- На основе History API - новая схема маршрутизации HTML5, более удобная и читаемая, плохая совместимость
- Действия браузера, такие как переход вперед и назад: запуск события popstate -> анализ URL-адреса -> соответствие соответствующему правилу маршрутизации
- Нажмите, чтобы перейти: вызовите функцию pushState, чтобы добавить состояние в историю браузера -> ...
- Обновите страницу или введите URL-адрес: он запросит сервер, поэтому использование истории требует, чтобы серверная часть взаимодействовала с перенаправлением -> ...
Для получения подробной информации см.:Интервьюер: Вы разбираетесь во внешней маршрутизации?
5. Сравнение преимуществ и недостатков прокси и объекта.
Преимущества прокси:
- Вы можете слушать непосредственно объекты, а не свойства
- Вы можете напрямую отслеживать изменения в массиве
- Дополнительные методы перехвата
- Прокси возвращает новый объект, вы можете только манипулировать новым объектом для достижения цели, а Object.defineProperty может только проходить свойства объекта и напрямую изменять
- Прокси как новый стандарт будет подвергаться постоянной оптимизации производительности производителями браузеров.
Преимущества Object.defineProperty заключаются в следующем:
- Хорошая совместимость, поддержка IE9
6. Жизненный цикл Vue
Относится к процессу создания данных инициализации, компиляции шаблонов, монтирования DOM, рендеринга, обновления и выгрузки.
- beforeCreate: при создании экземпляра компонента до того, как свойства компонента вступят в силу.
- created: Экземпляр компонента полностью создан и свойства привязаны, но настоящий DOM не сгенерирован, а $el недоступен.
- beforeMount: вызывается перед началом монтирования, соответствующая функция рендеринга вызывается в первый раз
- смонтирован: el заменяется созданным vm.$el и вызывается после его монтирования на экземпляре
- beforeUpdate: вызывается перед обновлением данных компонента, перед исправлением виртуального DOM.
- update: после обновления данных компонента
- активировано: исключительно для поддержки активности, вызывается при активации компонента
- deadactivated: исключительно для поддержки активности, вызывается при уничтожении компонента
- beforeDestory: вызывается перед уничтожением компонента
- уничтожено: вызывается после уничтожения компонента
7, разница между V-IFS и V-шоу
- Когда v-if переключает состояние, дом будет уничтожен и перестроен.Когда начальное условие рендеринга ложно, элемент не будет рендериться;
- v-show — это просто элемент управления для отображения и скрытия, независимо от того, каковы начальные условия, элемент всегда будет отображаться;
- v-if подходит для сценариев, в которых условия меняются редко, v-show подходит для сценариев, в которых условия часто меняются.
8. Разница между вычислением и просмотром
- вычисленный: он часто используется в вычислительных сценариях, которые потребляют производительность. Он имеет возможность кэширования. После выполнения геттера он будет кэширован. Только после того, как значение атрибута, от которого он зависит, изменится, вычисленное значение, полученное в следующий раз, будет пересчитано.
- СМОТРЕТЬ: обычно используется для некоторых данных, наблюдения
props,$emitЛибо значение этого компонента меняется для выполнения callback для последующих операций, кеша нет, и значение будет выполняться при перерендере страницы.
9. Для чего нужны ключи в Vue
- Ключ с уникальной идентификацией может повысить эффективность алгоритма сравнения, а компоненты списка в некоторых сложных сценах могут обновляться и отображаться более точно.
- В сценарии рендеринга простого компонента списка без сохранения состояния производительность без ключа на самом деле лучше, чем с ключом, потому что без ключа Vue будет повторно использовать узлы по умолчанию, экономя затраты на уничтожение/создание компонентов.
Причины, по которым рекомендуется использовать уникальный идентификатор в качестве ключа:
- Приведение уникального ключа может гарантировать правильность состояния обновленного компонента и избежать ошибок в некоторых сценариях.Хотя это увеличит накладные расходы на производительность, пользователь в принципе не почувствует разницы.
10. следующая галочка
nextTickЭто позволяет нам выполнить отложенный обратный вызов после следующего цикла обновления DOM, чтобы получить обновленный DOM.
- Vue2.4 использовал микрозадачи
- В новой версии микрозадачи используются по умолчанию, а макрозадачи в v-on
- Реализация макрозадач: сначала будет судить, можно ли использовать setImmediate, если нет, то перейти на MessageChannel, если ничего из вышеперечисленного не работает, использовать setTimeout
11, способ общения между компонентами vue
-
props/$emit -
$children/$parent- использовать в родительских компонентахthis.$childrenПолучить массив экземпляров подкомпонентов, которые можно использовать в подкомпонентахthis.$parentПолучите объект экземпляра родительского компонента.- советы: в
#appпродолжать$parentполучить этоnew Vue(), а затем получить сверху этого$parentявляетсяundefined; в то время как базовый подкомпонент получает$childrenВы получаете пустой массив.
- советы: в
-
provide/inject—— Новый API vue2.2, родительский компонент проходитprovideсвойства для предоставления переменных, которые затем используются в дочерних компонентахinjectвводить переменные. -
ref/$refs——refПри использовании с обычными элементами DOM он относится к элементу DOM; если он используется с дочерними компонентами, он относится к экземпляру компонента. -
$attrs/$listeners—— Новое в vue2.4, можно осуществлять межуровневую коммуникацию компонентов eventBus
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
// A.vue
<template>
<div>
<button @click="sendFirstName"></button>
</div>
</template>
<script>
import {EventBus} from './event-bus.js'
export default {
data(){
return{
firstName:'leborn'
}
},
methods:{
sendFirstName(){
EventBus.$emit('getFirstName', {
firstName:this.firstName
})
}
}
}
</script>
// B.vue
<template>
<div>姓名: {{name}}</div>
</template>
<script>
import { EventBus } from './event-bus.js'
export default {
data() {
return {
name: ''
}
},
mounted() {
EventBus.$on('getFirstName', param => {
this.name = param.firstName + 'james';
})
}
}
</script>
12. Оптимизация производительности проекта Vue
Уровень кода:
- Разумное использование v-if и v-show
- Различать использование вычислений и часов
- v-для обхода добавляет ключ к элементу
- v-для обхода избегайте одновременного использования v-if
- События, добавленные через addEventListener, должны быть вручную удалены из прослушивателя событий с помощью removeEventListener при уничтожении компонента.
- Ленивая загрузка изображения
- Отложенная загрузка маршрута
- Сторонние плагины вводятся по запросу
- SSR-рендеринг на стороне сервера, быстрая скорость загрузки на первом экране, хороший SEO-эффект
Оптимизация уровня Webpack:
- сжимать изображения
- Извлечение общего кода с помощью CommonsChunkPlugin
- Извлечь CSS компонента
- Оптимизировать исходную карту
- Создайте анализ вывода результатов, используя инструмент визуального анализа webpack-bundle-analyzer.
Базовая оптимизация веб-технологий:
- включить сжатие gzip
- кеш браузера
- Использование CDN
- Анализ производительности с помощью Chrome Performance
Для получения подробной информации см.:Оптимизация производительности проекта Vue - практическое руководство (наиболее полное/подробное в сети)
13. Жизненный цикл реакции
class ExampleComponent extends React.Component {
// 用于初始化 state
constructor() {}
// 用于替换 `componentWillReceiveProps` ,该函数会在初始化和 `update` 时被调用
// 因为该函数是静态函数,所以取不到 `this`
// 如果需要对比 `prevProps` 需要单独在 `state` 中维护
static getDerivedStateFromProps(nextProps, prevState) {}
// 判断是否需要更新组件,多用于组件性能优化
shouldComponentUpdate(nextProps, nextState) {}
// 组件挂载后调用
// 可以在该函数中进行请求或者订阅
componentDidMount() {}
// 用于获得最新的 DOM 数据
getSnapshotBeforeUpdate() {}
// 组件即将销毁
// 可以在此处移除订阅,定时器等等
componentWillUnmount() {}
// 组件销毁后调用
componentDidUnMount() {}
// 组件更新后调用
componentDidUpdate() {}
// 渲染组件函数
render() {}
// 以下函数不建议使用
UNSAFE_componentWillMount() {}
UNSAFE_componentWillUpdate(nextProps, nextState) {}
UNSAFE_componentWillReceiveProps(nextProps) {}
}
14. Когда setState синхронен в React, а когда асинхронен?
- Реагируйте с помощью обработки событий (например, onClick), setState вызовов не обновляются одновременно это.
причина: В реализации функции setState синхронное обновление this.state будет определяться в соответствии с переменной isBatchingUpdates. isBatchingUpdates по умолчанию имеет значение false, что означает, что setState будет обновлять this.state синхронно. Но React вызовет функцию batchedUpdates при вызове обработчика событий, измените isBatchingUpdates на true, в это время setState не будет синхронно обновлять this.state
- Письменный тестовый вопрос для setState: что выведет следующий код
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 1 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 2 次 log
setTimeout(() => {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 3 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 4 次 log
}, 0);
}
render() {
return null;
}
};
- Первый и второй раз находятся в жизненном цикле самой реакции, isBatchingUpdates имеет значение true, и состояние не будет обновляться напрямую в это время, оба выводят 0
- Два setState за пределами setTimeout будут объединены и выполнены только один раз, в это время state.val равно 1
- setTimeout приведет к тому, что isBatchingUpdates будет ложным, в это время setState выполняется синхронно, выход 2, 3
Выход: 0 0 2 3
конец
Интерфейсных точек знаний слишком много и они слишком сложны.Для некоторого контента, который не задействован, например, webpack, babel и т. д., может быть добавлено продолжение. Если эта статья может помочь вам, это будет сделано, поставив большой палец вверх.Пожалуйста, простите меня, если я не могу вам помочь~
Наконец, я предлагаю вам сделать резюме самостоятельно при чтении некоторых технических статей, иначе легко забыть с первого взгляда, да, это так у блогеров, и если статья не является строгой, пожалуйста, укажите это в области комментариев.