Запишите вопросы интервью и ответы на вопросы интервью, возникшие во время недавней смены работы
css-раздел
коробочная модель
Вопрос: Расскажите про блочную модель css
Блочная модель делится на стандартную модель и странную блочную модель (блочная модель IE).
Стандартная блочная модель: ширина и высота блочной модели — это только ширина и высота содержимого.
Странная блочная модель: ширина и высота блочной модели — это общая ширина и высота содержимого + отступы + граница.
Вопрос: Как установить две модели в css
/* 标准模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
Вопрос: Вы когда-нибудь сталкивались с перекрывающимися полями и как это решить? Проблема перекрытия полей показана на следующем рисунке.
Используйте BFC для решения проблемы, далее подробно описывается BFC
Справочный код: Используя характеристики BFC, поместите другой блок в другой независимый BFC, чтобы два блока не влияли друг на друга.
<section class="top">
<h1>上</h1>
margin-bottom:30px;
</section>
<div style="overflow: hidden;">
<section class="bottom">
<h1>下</h1>
margin-top:50px;
</section>
</div>
BFC
Вопрос: Расскажите мне о BFC
-
Что такое БФК
BFC (контекст форматирования блоков) Формат формата, представляет собой режим рендеринга CSS из макета модели моделей в веб-странице, относится к отдельной области рендеринга или изолированный автономный контейнер.
-
Условия формирования БТЭ
- элемент float, значение float, отличное от none
- Элемент позиционирования, позиция (абсолютный, фиксированный)
- В дополнение к видимому значению переполнения (скрытое, автоматическое, прокрутка)
-
Характеристики БФК
- Внутренние ящики располагаются один за другим в вертикальном направлении.
- Расстояние по вертикали определяется запасом
- Область bfc не перекрывает область элемента float.
- При расчете высоты бфц в расчете также участвуют плавающие элементы
- bfc — это независимый контейнер на странице, и дочерние элементы внутри контейнера не будут влиять на внешние элементы.
принцип рем
Суть макета rem заключается в пропорциональном масштабировании, которое обычно основано на ширине.Предположим, ширина экрана разделена на 100 частей, каждая ширина равна 1rem, а ширина 1rem равна ширине экрана/100, а затем дочерний элемент устанавливает свойство единицы вещного имущества
Изменяя размер шрифта элемента html, вы можете установить фактический размер дочерних элементов.
Лучшее решение, чем rem (недостаток не совместим)
vw (1vw — 1% ширины области просмотра, 100vw — ширина области просмотра), vh (100vh — высота области просмотра)
Реализация трехколоночного макета
(фиксированная ширина с обеих сторон, адаптивная посередине)
Вот пять реализаций:
- гибкий способ достижения
/* css */
.box {
display: flex;
justify-content: center;
height: 200px;
}
.left {
width: 200px;
background-color: red;
height: 100%;
}
.content {
background-color: yellow;
flex: 1;
}
.right {
width: 200px;
background-color: green;
}
/* html */
<div class="box">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
- Плавающий метод, содержимое этого метода должно быть размещено внизу
/* css */
.box {
height: 200px;
}
.left {
width: 200px;
background-color: red;
float: left;
height: 100%;
}
.content {
background-color: yellow;
height: 100%;
}
.right {
width: 200px;
background-color: green;
float: right;
height: 100%;
}
/* html */
<div class="box">
<div class="left"></div>
<div class="right"></div>
<div class="content"></div>
</div>
- Абсолютное позиционирование достигается
/* css */
.box {
position: relative;
height: 200px;
}
.left {
width: 200px;
background-color: red;
left: 0;
height: 100%;
position: absolute;
}
.content {
background-color: yellow;
left: 200px;
right: 200px;
height: 100%;
position: absolute;
}
.right {
width: 200px;
background-color: green;
right: 0;
height: 100%;
position: absolute;
}
/* html */
<div class="box">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
- реализация макета таблицы
/* css */
.box {
display: table;
height: 200px;
}
.left {
width: 200px;
background-color: red;
height: 100%;
display: table-cell;
}
.content {
background-color: yellow;
height: 100%;
display: table-cell;
}
.right {
width: 200px;
background-color: green;
height: 100%;
display: table-cell;
}
/* html */
<div class="box">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
- макет сетки
/* css */
.box {
display: grid;
grid-template-columns: 200px auto 200px;
grid-template-rows: 200px;
}
.left {
background-color: red;
}
.content {
background-color: yellow;
}
.right {
background-color: green;
}
/* html */
<div class="box">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
Центрировать коробку по горизонтали и вертикали
Вот пять реализаций:
- ширина и высота известны
/* css */
#box{
width: 400px;
height: 200px;
position: relative;
background: red;
}
#box1{
width: 200px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -50px;
background: green;
}
/* html */
<div id="box">
<div id="box1">
</div>
</div>
- ширина и высота неизвестны
/* css */
#box{
width: 800px;
height: 400px;
position: relative;
background: red;
}
#box1{
width: 100px;
height: 50px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background: green;
}
/* html */
<div id="box">
<div id="box1">
</div>
</div>
- гибкий макет
/* css */
#box{
width: 400px;
height: 200px;
background: #f99;
display: flex;
justify-content: center;//实现水平居中
align-items: center;//实现垂直居中
}
#box1{
width: 200px;
height: 100px;
background: green;
}
/* html */
<div id="box">
<div id="box1">
</div>
</div>
- Позиция панорамирования+преобразование
/* css */
#box{
width: 400px;
height: 200px;
background: red;
position: relative;
}
#box1{
width: 200px;
height: 100px;
background: #9ff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* html */
<div id="box">
<div id="box1">
</div>
</div>
- макет ячейки таблицы
/* css */
#box{
display: table-cell;
vertical-align: middle
}
#box1{
margin: 0 auto;
}
/* html */
<div id="box">
<div id="box1">
</div>
</div>
js-часть
Что такое закрытие и цель закрытия
Функция, которая может читать внутренние переменные других функций, или просто понимается как функция, определенная внутри функции, и внутренняя функция содержит ссылку на переменную внутри внешней функции.
Использование замыканий:
- Чтение переменных внутри других функций
- Хранить значение переменной всегда в памяти
- Применение замыканий в JavaScript имеет ключевое слово return, цитирующее отрывок из секретного сада JavaScript, потому что:
Замыкания — очень важная функция JavaScript, а это означает, что текущая область всегда может обращаться к переменным во внешней области. Поскольку функции — единственные структуры в JavaScript, имеющие собственную область видимости, создание замыканий зависит от функций.
Разница между вызовом, применением и привязкой: как реализовать вызов, применение метода
Сходства:
- Все они используются для изменения точки объекта this функции.
- Первый параметр — это объект, на который он должен указывать.
- Последующие параметры могут использовать передачу параметров. разница:
- получение режима передачи параметра вызова функции: fn.call (this, 1, 2, 3)
- apply принимает параметры функции следующим образом: fn.apply(this,[1, 2, 3])
- Возвращаемое значение bind — это новая функция, которую необходимо вызвать снова: fn.bind(this)(1, 2, 3)
Вручную реализовать метод вызова:
Function.prototype.myCall = function(context = window, ...rest) {
context.fn = this; //此处this是指调用myCall的function
let result = context.fn(...rest);
//将this指向销毁
delete context.fn;
return result;
};
Вручную реализуйте метод применения:
Function.prototype.myCall = function(context = window, params = []) {
context.fn = this; //此处this是指调用myCall的function
let result
if (params.length) {
result = context.fn(...params)
}else {
result = context.fn()
}
//将this指向销毁
delete context.fn;
return result;
};
Вручную реализуйте метод привязки:
Function.prototype.myBind = function(oThis, ...rest) {
let _this = this;
let F = function() {}
// 根据 bind 规定,如果使用 new 运算符构造 bind 的返回函数时,第一个参数绑定的 this 失效
let resFn = function(...parmas) {
return _this.apply(this instanceof resFn ? this : oThis, [
...rest,
...parmas
]);
};
// 继承原型
if (this.prototype) {
F.prototype = this.prototype;
resFn.prototype = new F;
}
return resFn;
};
Как понять прототип и цепочку прототипов
У каждой функции есть прототип
Каждый объект имеет__proto__
пример__proto__указатель на прототип конструктора
js движок будет следовать__proto__-> Порядок прототипа искался вверх, пока не будет найден Object.prototype, Object является собственным базовым объектом, и поиск останавливается здесь, если он не найден, он сообщит об ошибке или вернет undefined
Несколько способов наследования js
Общее наследование: наследование композиции, наследование паразитарной композиции.
Комбинированное наследование: используйте вызов для наследования свойств родительского класса и используйте прототип подкласса, чтобы он был равен экземпляру родительского класса, чтобы наследовать метод родительского класса.
Недостатки: вызов родительского класса дважды, что приводит к потере производительности.
function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
console.log(this.name);
};
function Child(name) {
Parent.call(this, name)
}
Child.prototype = new Parent;
let c = new Child("YaoChangTuiQueDuan");
c.say()
Паразитическое наследование композиции: используйте вызов для наследования свойств родительского класса, используйте прототип чистой функции, чтобы он был равен прототипу родительского класса, а затем используйте прототип подкласса, чтобы он был равен экземпляру чистой функции.
function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
console.log(this.name);
};
function ExtendMiddle() {}
function Child(name) {
Parent.call(this, name)
}
ExtendMiddle.prototype = Parent.prototype;
Child.prototype = new ExtendMiddle
let c = new Child("YaoChangTuiQueDuan");
c.say()
eventloop
Пожалуйста, обратитесь к статьеEventloop — это не страшно, страшно встретить Promise
Что вы делали в новом процессе? Внедрить новый вручную
- вновь созданный объект
- ссылка на прототип
- связать это
- вернуть новый объект
function create(...rest) {
// 创建一个空的对象
let obj = new Object()
// 获得构造函数
let Con = rest.shift()
// 链接到原型
obj.__proto__ = Con.prototype
// 绑定 this,执行构造函数
let result = Con.apply(obj, arguments)
// 确保 new 出来的是个对象
return typeof result === 'object' ? result : obj
}
Скажем, какой-нибудь часто используемый es6
- let/const
- строка шаблона
- присваивание деструктуризации
- область действия блока
- Promise
- Class
- параметры функции по умолчанию
- модульный
- стрелочная функция
- Set
- Map
- Array.map
- так далее
Основное использование и принцип Promise, а также реализация упрощенной версии Promise
Несколько особенностей промисов:
- Обещает ловить ошибки так же, как и try/catch
- Обещания имеют изменения состояния, а изменения состояния необратимы.
- Обещания — это микрозадачи
- .then обратные вызовы в промисах асинхронны
- В Promise.then каждый раз возвращает новое обещание
- Обещания хранят возвращаемое значение
Простая реализация промисов:
class MyPromise {
constructor(fn) {
this.resolvedCallbacks = [];
this.rejectedCallbacks = [];
this.state = "PADDING";
this.value = "";
fn(this.resolve.bind(this), this.reject.bind(this));
}
resolve(value) {
if (this.state === "PADDING") {
this.state = "RESOLVED";
this.value = value;
this.resolvedCallbacks.forEach(cb => cb());
}
}
reject(value) {
if (this.state === "PADDING") {
this.state = "REJECTED";
this.value = value;
this.rejectedCallbacks.forEach(cb => cb());
}
}
then(resolve = function() {}, reject = function() {}) {
if (this.state === "PADDING") {
this.resolvedCallbacks.push(resolve);
this.rejectedCallbacks.push(reject);
}
if (this.state === "RESOLVED") {
resolve(this.value);
}
if (this.state === "REJECTED") {
reject(this.value);
}
}
}
Вы когда-нибудь использовали Async / ждут говорить о разнице и связи с обещанием?
- Промис используется, и он не конфликтует с промисом
- Он полностью синхронен в записи, без какой-либо функции обратного вызова.
- await должен использоваться в асинхронных функциях
- Если метод ожидания является промисом, он вернет результат обработки промиса. Дождавшись успешной обработки промиса, выполните следующий код. Если это не объект промиса, верните само значение, а затем выполните код ниже синхронно.
- Код, написанный после await, эквивалентен выполнению Promise.resolve().
- Используйте try/catch для отлова ошибок
Как использовать для ... iTerator на объекте
Вы можете установить один на прототип объектаSymbol.iteratorметод, который возвращает объект, содержащийnextметод,nextМетод также возвращает объект, содержащийvalueа такжеdone. value указывает значение завершения каждой итерации, done указывает, завершена ли итерация, если false, то итерация продолжится, если true, итерация завершена и итерация будет остановлена.
Object.prototype[Symbol.iterator] = function () {
let values = Object.values(this);
let keys = Object.keys(this);
let len = 0;
return {
next() {
return {
value: {
value: values[len],
key: keys[len++]
},
done: len > values.length
}
}
}
}
Разница между модульностью в CommonJS и ES6
- Первый поддерживает динамический импорт, то есть require(${path}/xx.js), второй на данный момент не поддерживается, но есть предложения
- Первый — это синхронный импорт, поскольку он используется для сервера, а все файлы являются локальными, а синхронный импорт малоэффективен, даже если основной поток завис. Последний является асинхронным импортом, потому что он используется в браузере, а файлы нужно скачивать.Если также используется синхронный импорт, это сильно повлияет на рендеринг.
- Первый является копией значения при экспорте.Даже если экспортируемое значение изменится, импортированное значение не изменится, поэтому, если вы хотите обновить значение, вы должны импортировать его снова. Однако последний использует привязку в реальном времени, и все импортированные и экспортированные значения указывают на один и тот же адрес памяти, поэтому импортированное значение будет следовать за экспортированным значением.
- Последний будет скомпилирован в require/exports для выполнения
Какое отношение module.exports имеет к экспорту
Для удобства Node предоставляет переменную exports для каждого модуля, указывающую на module.exports, что эквивалентно экспорту, являющемуся ссылкой на адрес module.exports.
Проблемы, которые возникнут: Если вы назначите экспорту новый объект, такой как exports = {}, в это время соединение с module.exports будет прервано, что приведет к неудачному экспорту.
Что такое анти-шейк и троттлинг? Какая разница?
- Контролирует частоту вызова часто вызываемых событий
- Функции защиты от сотрясений и дросселирования заключаются в предотвращении многократного вызова функции.
- Отличие в том, что если пользователь запускает эту функцию все время, и интервал между каждой функцией срабатывания меньше ожидания, то в случае антишейка она будет вызываться только один раз, а в случае троттлинга функция будет вызываться через определенное время (параметр ожидания).
Какую проблему решает глубокая копия? Как добиться
Как отличить глубокую копию от мелкой, говоря простым языком, предполагается, что Б скопировал А, при модификации А посмотреть, изменится ли Б, если Б тоже изменится, значит, это поверхностная копия, если Б не изменился изменено, это глубокая копия.
Поскольку js делится на два типа переменных, базовые типы данных и ссылочные типы данных, базовые типы данных включают число, строку, логическое значение, нуль, неопределенный и символ.
Ссылочный тип данных (класс объекта) неупорядоченный объект с обычными парами имя-значение{a:1}, множество[1,2,3]и функции и т.д.
Два типа хранения данных следующие:
-
Базовый тип - значение имени хранится в памяти стека, например пусть a=1;
Когда вы копируете b=a, память стека создаст новую память, например:
Таким образом, когда вы измените a=2 в это время, это не повлияет на b, потому что адрес памяти b был изменен в это время, и на него не влияет a.
-
Справочный тип данных - имя Существует запас инвентаризации, значение хранится в памяти кучи, но память стека обеспечит ссылку на значение в памяти кучи.
Когда b=a копируется, он фактически копирует ссылочный адрес a, а не значение в куче.
Когда мы изменяем массив, когда a[0]=1, поскольку a и b указывают на один и тот же адрес, естественно, b также затрагивается, что называется поверхностной копией.
Затем, если нам нужно добиться эффекта глубокого копирования, нам нужно открыть новое пространство памяти в памяти кучи для хранения значения b, как показано на рисунке:
Реализация глубокой копии:
-
json.parse & json.stringify
Сначала преобразуйте объект в объект json. Затем этот объект json анализируется, но у этого подхода есть несколько недостатков:
- Если в obj есть объект времени, то после сериализации время будет только в виде строки, а не объекта времени
- Если в obj есть объекты RegExp и Error, результатом сериализации будут только пустые объекты
- Если в obj есть функция undefined, то результат сериализации потеряет функцию или undefined
- Если у obj есть NaN, Infinity и -Infinity, сериализованный результат станет нулевым
- Только перечисляемые собственные свойства объекта могут быть сериализованы.Если объект в obj генерируется конструктором, после сериализации конструктор объекта будет отброшен
- Глубокое копирование не может быть реализовано правильно, если в объекте есть циклические ссылки.
-
Рекурсивный способ достижения глубокого копирования (ps: это всего лишь упрощенная версия, полную версию рекомендуется посмотреть в исходном коде метода cloneDeep lodash)
Адрес источника:GitHub.com/клак/клак…
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
let toString = Object.prototype.toString;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
//判断ojb子元素是否为对象,如果是,递归复制
if ( toString.call(obj[key]) === "[object Object]" || toString.call(obj[key]) === "[object Array]" ) {
objClone[key] = deepClone(obj[key]);
} else {
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
return objClone;
}
что такое куча и что такое стек
Стек (стек): стек автоматически выделяет и освобождает место в памяти, хранит базовые типы, простые сегменты данных и занимает место фиксированного размера. Куча: динамически выделяемая память, размер которой не фиксирован и не будет автоматически освобождаться для хранения ссылочных типов.
Почему существует разница между памятью стека и памятью кучи?
Обычно связано с механизмом сборки мусора. Для того, чтобы минимизировать объем памяти, занимаемой программой при ее работе.
Когда метод выполняется, каждый метод устанавливает свой собственный стек памяти, и переменные, определенные в этом методе, будут помещаться в эту память стека одна за другой.По мере завершения выполнения метода стек памяти этого метода также будет уничтожается естественным путем. Поэтому все переменные, определенные в методе, помещаются в память стека;
Когда мы создаем объект в программе, этот объект будет сохранен в области данных времени выполнения для повторного использования (поскольку стоимость создания объекта обычно велика), эта область данных времени выполнения является памятью кучи. Объект в памяти кучи не будет уничтожен с окончанием метода.Даже после завершения метода на объект может ссылаться другая ссылочная переменная (общая при передаче параметра метода), тогда объект не будет уничтожен, only Когда у объекта нет ссылочных переменных, ссылающихся на него, системный механизм сборки мусора соберет его, когда он будет проверен.
Вставьте десятки тысяч DOM, а не как достичь страницы Caton?
Вариант первый:
分页,懒加载,把数据分页,然后每次接受一定的数据,避免一次性接收太多
Вариант 2:
setInterval,setTimeout,requestAnimationFrame 分批渲染,让数据在不同帧内去做渲染
третье решение:
Используйте виртуальную прокрутку, виртуальную прокрутку.
Этот метод относится к отображению определенной части данных длинного списка в соответствии с высотой элемента контейнера и высотой элемента элемента списка вместо полного рендеринга длинного списка, чтобы улучшить производительность бесконечной прокрутки.
Принцип виртуальной прокрутки:
Изменение отображаемой части списка в видимой области по мере прокрутки пользователем
- Вычислить startIndex начальных данных текущей видимой области
- Вычислить endIndex конечных данных текущей видимой области
- Рассчитать данные текущей видимой области и отобразить их на странице
- Вычислить позицию смещения startOffset данных, соответствующих startIndex во всем списке, и установить его в список
- Вычислите позицию смещения endOffset данных, соответствующих endIndex, относительно нижней части прокручиваемой области и установите ее в список
Как показано ниже:
startOffset и endOffset будут растягивать содержимое элемента-контейнера по высоте, позволяя ему непрерывно прокручиваться; кроме того, они будут удерживать полосу прокрутки в правильном положении.
Какие методы оптимизации вы знаете?
- Уменьшите HTTP-запросы: используйте значки шрифта iconfont, используйте спрайты, слейте js, слейте css
- Уменьшить DNS-запросы
- Поместите css вверху страницы, а js внизу страницы.
- Сжимайте js и css: уменьшайте размер файла, удаляйте ненужные пробелы, форматируйте символы, комментарии, удаляйте дублирование, бесполезный код, используйте gzip
- Использовать кеш браузера
- Избегайте слишком глубокого вложения селекторов css
- Высокочастотные триггерные события с использованием подавления дребезга и регулирования
- сделать кеширование ajax
- использовать cdn
- Продолжайте добавлять...
браузер
Введите URL-адрес в адресную строку браузера и нажмите Enter, чтобы выполнить следующий процесс:
- Анализ URL-адресов на DNS-сервер
- DNS-сервер возвращает IP-адрес браузеру
- Следуйте протоколу, чтобы отправить ip в сеть
- Доступ к серверу через локальную сеть
- Войдите в контроллер архитектуры MVC сервера.
- После логической обработки запросите распределение, вызовите уровень модели.
- Модель взаимодействует с данными, читает базу данных и возвращает окончательный результат в сеть через уровень представления и обратно в браузер.
- Браузерный рендеринг обратно по запросу html и сопутствующих css, js
- В процессе рендеринга браузер генерирует дерево dom на основе html и дерево css на основе css.
- Интегрируйте дерево dom и дерево css, наконец узнайте стиль узла dom и отобразите стиль на странице.
- Браузер для выполнения js-скрипта
- последняя отображаемая страница
Процесс рендеринга в браузере можно условно разделить на пять этапов:
- Преобразование html-кода в dom
- Преобразование кода css в cssom
- Объедините dom и cssom для создания дерева рендеринга
- Сгенерировать макет, то есть выполнить плоскую композицию всех узлов дерева рендера
- нарисовать макет на экране
кеш браузера
Когда браузер снова посещает уже посещенный ресурс, он делает это:
- Посмотрите, не попал ли в сильный кеш, и если да, используйте кеш напрямую.
- Если сильный кеш не срабатывает, на сервер отправляется запрос, чтобы проверить, сработал ли согласованный кеш.
- При попадании в согласованный кеш сервер вернет 304, сообщая браузеру, что нужно использовать локальный кеш.
- В противном случае запросите у сети возврат последнего ресурса.
Расположение кеша браузера:
- Service Worker: он позволяет нам свободно контролировать, какие файлы кешируются, как сопоставлять кеш, как читать кеш, и кеш является постоянным.
- Кэш памяти: Кэш памяти, чтение данных в памяти определенно быстрее, чем с диска. Однако, несмотря на то, что кеш памяти эффективен для чтения, сохраняемость кеша очень короткая и будет освобождена по мере освобождения процесса. Как только мы закрываем вкладку, кэш в памяти освобождается.
- Кэш диска: Кэш диска - это кеш, хранящийся на жестком диске. Скорость чтения ниже, но все может храниться на диске. По сравнению с кешем памяти, он лучше по емкости и своевременности хранения.
Реализация кэша: Сильное согласование и кеш-буфер реализованы в соответствии с заголовком HTTP.
Что такое перерисовка и перекомпоновка
Перекомпоновка: Необходимость изменить компоновку или геометрические свойства называется перекомпоновкой. Перерисовка: когда узлу необходимо изменить внешний вид, не влияя на макет, например, изменение цвета называется перерисовкой.
разница:
Оплавление неизбежно вызовет перерисовку, а перерисовка не обязательно приведет к оплавлению. Например: только при изменении цвета будет происходить только перерисовка, не вызывая оплавления Перекомпоновка требуется при изменении макета страницы и свойств геометрии.
Например: добавление или удаление видимых элементов DOM, изменение положения элемента, изменение размера элемента — поля, отступы, границы, ширина и высота, изменение содержимого.
vue&react
Разговор о МВВМ
MVVM - двусторонняя передача данных
- M: слой данных модели
- V: просмотр слоя просмотра
- ВМ: мост между уровнем представления ViewModel и уровнем данных, мост между уровнем представления и уровнем данных.
Слой представления связывает слой модели через события, а слой модели связывает слой представления через данные.
Что такое виртуальный DOM Зачем использовать виртуальный DOM
Раньше при рендеринге данных все элементы в DOM напрямую заменялись новыми данными.Чтобы отрисовать потерю производительности, вызванную бесполезным DOM, появился виртуальный DOM.Виртуальный DOM — это виртуальный DOM, который представлен js-объектами. , Древовидная структура DOM сопоставляет атрибуты в DOM с атрибутами объекта js. Его основное определение — это не что иное, как несколько ключевых атрибутов, таких как имя тега, данные, дочерний узел, значение ключа и т. д. Когда данные изменяются, повторно визуализируйте структуру объекта этого js, найдите узлы DOM, которые действительно нуждаются в обновлении, а затем визуализируйте настоящий DOM. Суть Virtual DOM в том, чтобы делать кэш между JS и DOM
Почему манипулирование реальным домом имеет проблемы с производительностью
Потому что DOM — это то, что принадлежит движку рендеринга, а JS — это то, что принадлежит движку JS. Когда мы работаем с DOM через JS, фактически эта операция включает в себя связь между двумя потоками, что неизбежно приведет к некоторым потерям производительности. Работа с DOM более одного раза эквивалентна постоянной связи между потоками, а работа с DOM может также привести к перерисовке и перекомпоновке, что также приводит к проблемам с производительностью.
Принципы отзывчивости Vue
Vue используется внутриObject.defineProperty()Чтобы добиться оперативности данных, с помощью этой функции вы можете слушатьsetа такжеgetмероприятие.
- первое использование
Object.defineProperty()Установите атрибуты в данныхset,getмероприятие - Рекурсивно зарегистрировать каждое свойство в данных в качестве наблюдателя
- При разборе шаблона в атрибуте
getСбор зависимостей наблюдателя в событиях - При изменении значения свойства в
setУведомить каждого наблюдателя в событии, чтобы обновить все
Как шаблоны Vue преобразуются в HTML и процесс рендеринга
- Суть шаблона vue — это строка, с помощью различных закономерностей атрибуты в шаблоне превращаются в переменные в js, а такие инструкции, как vif, vshow и vfor, становятся в js логикой.
- Шаблон в конечном итоге будет преобразован в функцию рендеринга.
- выполнение функции рендеринга возвращает vNode
- Рендеринг vNode в реальный DOM с использованием метода пути vNode
Весь процесс внедрения Vue
- Сначала разберите шаблон в функцию рендеринга, измените атрибуты в шаблоне на переменные в js и преобразуйте команды, такие как vif, vshow, vfor, в логику в js.
- Выполните функцию рендеринга, привяжите мониторинг свойств, соберите зависимости и, наконец, получите vNode во время первоначального рендеринга и выполните функцию рендеринга, а также используйте метод пути vNode для рендеринга vNode в реальный DOM.
- После обновления атрибута повторно выполните функцию рендеринга, но на этот раз нет необходимости привязывать атрибут и собирать зависимости, и, наконец, сгенерировать новый vNode.
- Сравните новый vNode со старым vNode, найдите DOM, который действительно нуждается в обновлении, визуализируйте
Что такое алгоритм diff или для чего используется алгоритм diff
- diff — это основная команда в Linux, которую можно использовать для сравнения файлов и содержимого.
- Алгоритм сравнения, используемый в vNode, заключается в том, чтобы найти узлы, которые необходимо обновить, и избежать ненужных обновлений.
Что такое Вьюекс
Vuex подобен глобальному складу, и мы будем извлекать общедоступное состояние или состояние сложного взаимодействия компонентов и помещать его в него.
Ядро vuex в основном включает следующие части:
- состояние: состояние — это сохраненное состояние, которое нам нужно использовать.Это односторонний поток данных. Его нельзя изменять напрямую в vue, но можно использовать мутации для его изменения.
- мутации: мутации — это некоторые способы хранения того, как изменить состояние
- действия: действия предназначены для асинхронной модификации, он может дождаться окончания асинхронности, прежде чем использовать ее
commit mutationsизменить состояние - геттеры: эквивалентно вычисляемым свойствам состояния
использовать:
- Получить состояние Используйте this.$store.state в вычислении внутри компонента, чтобы получить желаемое состояние
- Если вы измените его, вы можете использовать метод this.$store.commit в компоненте для изменения состояния.
- Если в одном компоненте, методе, состоянии используется слишком много. Вы можете использовать вспомогательные функции mapState, mapMutations
Связь между компонентами в Vue
Компоненты сыновей: подсборка родительского элемента передается через реквизиты, уведомляет подсборку родительского компонента с помощью $ EMIT Компоненты Brother: вы можете использовать глобальное общее состояние vuex или eventBus.
Как решить проблему потери данных Vuex после обновления страницы
Это можно решить с помощью плагина vuex-persistedstate. Принцип подключаемого модуля: используйте метод локального хранилища HTML5 + Vuex.Store для синхронизации данных в локальном хранилище и хранилище и достижения синхронного обновления.
Использование слотов в Vue
Быть добавленным...
Функция Life Hook в Vue, что она делает, когда вызывается каждый крючок
- beforeCreate: Экземпляр компонента только что создан, в настоящее время свойства внутри компонента не могут быть использованы.
- Создано: был создан экземпляр компонента, и свойства были связаны, но DOM не был создан. Обычно используется для запроса интерфейса, а Дом не может быть манипулируется.
- beforeMount: до монтирования шаблона
- смонтирован: после того, как шаблон смонтирован, в этом хуке шаблон смонтирован, и DOM можно манипулировать
- beforeUpdate: Перед обновлением компонента
- update: после обновления компонента
- активировано: функция ловушки доступна только при использовании проверки активности, вызывается при активации компонента
- деактивировано: функция ловушки доступна только при использовании keep-alive, вызывается при удалении компонента
- beforeDestory: вызывается перед удалением компонента
- уничтожено: вызывается после удаления компонента, обычно используется для очистки таймера
- Если есть дочерние компоненты, последовательность вызова будет следующей: родитель beforeCreate -> создан родитель -> родитель beforeMount -> дочерний beforeCreate -> создан дочерний элемент -> дочерний beforeMount -> смонтирован дочерний элемент -> смонтирован родительский
Два принципа реализации интерфейсной маршрутизации
Два режима маршрутизации делятся на режим хеширования и режим истории.
хэш-режим:
В основе режима хеширования лежит событие onhashchange, которое можно отслеживать в объекте окна. Когда хеш изменяется, браузер записывает историю и запускает обратный вызов события. В хэш-режиме адресная строка будет иметь # #
режим истории:
В предыдущем hashchange можно было изменить только фрагмент url после #, тогда как history api дает интерфейсу полную свободу
Историю API можно разделить на две части: переключение и модификацию, см. MDN.
Использование истории требует поддержки сервера.В режиме хеширования фронтенд-роутинг модифицирует информацию в #, а браузер при запросе ее не несет, так что проблем нет.Но под историей можно свободно модифицировать путь При обновлении, если на сервере нет соответствующего ответа или ресурса, будет отображаться ошибка 404.
Что такое ssr, чем отличается ssr от предыдущего фонового шаблона
Быть добавленным...
Что обеспечивает в Vue?
Быть добавленным...
Для чего обычно используются миксины?
Быть добавленным...
Что такое NextTick?
Быть добавленным...
алгоритм
Алгоритмы сортировки (быстрая сортировка, пузырьковая)
Быть добавленным...
Как реализовать обход в глубину и обход в ширину?
Быть добавленным...
Вопросы по алгоритму письменного теста
已知如下数组:
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
方法一:
function handleArr(arr) {
let flatten = (arr) => arr.push ? arr.reduce((pre, current) => [...pre, ...flatten(current)], []) : [arr];
return [...new Set(flatten(arr))].sort((a, b) => a - b);
}
方法二:
[...new Set(arr.toString().split(",").map(Number))].sort((a,b)=> a - b)
方法三:
[...new Set(arr.flat(Infinity))].sort((a,b)=>{ return a - b})
Письменные экзаменационные вопросы
let test = (function (a) {
this.a = a;
return function (b) {
console.log(this.a + b);
}
})((function(a){
return a;
})(1,2))
test(4)
Ответ: 5
Анализ: ставим(function (a) { this.a = a; return function (b) { console.log(this.a + b); } })()Тело самовыполняющейся функции называетсяz1
Пучок(function(a){ return a; })(1,2)называетсяz2
Пучокfunction (b) { console.log(this.a + b); }называетсяn1
Тестовая функция — это анонимная самовыполняющаяся функция.z1Возвращаемое значение тестовой функции на самом делеn1, функцияz1Получите a в качестве параметра, где a на самом деле является самовыполняющейся функциейz2Возвращаемое значение равно 1, тогдаn1Параметр a в функции равен 1, в функцииz1серединаthis.a = aЗдесь имеется в видуwindowтак вwindowНа него монтируется свойство a со значением 1
Когда text(4) выполняется, b передается как 4, и функцияn1в этом говорится оwindow, ранее смонтированный атрибут a в окне равен 1, поэтому результат выполнения функции равен 5