Эта статья была предоставлена дамой с фронт-энда——Сюй Пяо Пяо,Эта статьяТонны сухих продуктов, высокая энергия на протяжении всего процесса. Надеюсь, вы дадите больше лайков, комментариев и внимания, чтобы дать барышне мотивацию продолжать писать статьи!
Github фронтальной младшей сестры
Кроме того, мисс Сестра недавно присматривалась к базе Opportunity Base в Пекине, и ее электронная почта была прикреплена к GitHub. Приветствуйте студентов с пит-позициями, чтобы порекомендовать.
1. Алгоритм
1. Полная аранжировка
微信公众号:世界上有意思的事
function permutate(str) {
var array = str.split('');
function loop(array, pre = []) {
if (array.length == 1) {
return [pre.concat(array).join('')];
}
let res = [];
for (let index = 0; index < array.length; index++) {
var first = array.pop();
res = res.concat(loop(array, [...pre, first]));
array.unshift(first);
}
return res;
}
return Array.from(new Set(loop(array)))
}
2. Бинарный поиск
微信公众号:世界上有意思的事
function BinarySearch1 (arr, target) {
return search(arr, target, 0, arr.length - 1)
function search (arr, target, from, to) {
if (from > to) {
return -1
}
const mid = Math.floor((from + to)/2)
if (arr[mid] > target) {
return search(arr, target, from, mid - 1)
} else if (arr[mid] < target) {
return search(arr, target, mid + 1, to)
} else {
return mid
}
}
}
function BinarySearch2 (arr, target) {
let from = 0
let to = arr.length - 1
let mid = Math.floor((from + to)/2)
while (from <= to) {
mid = Math.floor((from + to)/2)
if (arr[mid] > target) {
to = mid - 1
} else if (arr[mid] < target) {
from = mid + 1
} else {
return mid
}
}
return -1
}
3. Сортировать
(1) Пузырьковая сортировка
微信公众号:世界上有意思的事
/*
第1次循环确定最大的
第n次循环确定第n大的
*/
function BubbleSort (arr) {
const length = arr.length
for (let i = 0; i < length; i++) {
for (let j = 1; j < length-i; j++) {
if (arr[j] < arr[j - 1]) {
const temp = arr[j]
arr[j] = arr[j - 1]
arr[j - 1] = temp
}
}
}
return arr
}
(2) Быстрая сортировка
微信公众号:世界上有意思的事
/*
在左边找大数,在右边找小数
交换
*/
function QuickSort(arr, low, high) {
let left = low
let right = high
let basic = arr[low]
while (left < right) {
while (left < right && arr[right] > basic) {
right--
}
while (left < right && arr[left] <= basic) {
left++
}
if (left < right) {
const temp = arr[left]
arr[left] = arr[right]
arr[right] = temp
} else {
const temp = arr[low]
arr[low] = arr[left]
arr[left] = temp
QuickSort(arr, low, left - 1)
QuickSort(arr, right + 1, high)
}
}
return arr
}
(3) Сортировка выбором
微信公众号:世界上有意思的事
/*
寻找第i小的数的位置,放到i位置上
*/
function SelectionSort (arr) {
const length = arr.length
for (let i = 0; i < length; i++ ) {
let minIndex= i
for (let j = i + 1; j < length; j++) {
minIndex = arr[minIndex] <= arr[j] ? minIndex : j
}
if (minIndex !== i) {
const temp = arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = temp
}
}
return arr
}
(4) Сортировка вставками
微信公众号:世界上有意思的事
function InsertionSort (arr) {
const length = arr.length
for (let i = 1; i < length; i++) {
const temp = arr[i]
let j
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j+1] = arr[j]
}
arr[j+1] = temp
}
return arr
}
(5) Сортировка по холму
Улучшенная версия сортировки вставками. Сортировка вставками для набора пробелов
微信公众号:世界上有意思的事
function ShellSort (arr) {
const length = arr.length
let gap = Math.floor(length)
while (gap) {
for (let i = gap; i < length; i++) {
const temp = arr[i]
let j
for (j = i - gap; j >= 0 && temp < arr[j]; j = j - gap) {
arr[j + gap] = arr[j]
}
arr[j + gap] = temp
}
gap = Math.floor(gap / 2)
}
return arr
}
(6) Сортировка слиянием
微信公众号:世界上有意思的事
function MergeSort (arr, low, high) {
const length = arr.length
if (low === high) {
return arr[low]
}
const mid = Math.floor((low + high)/2)
MergeSort(arr, low, mid)
MergeSort(arr, mid + 1, high)
merge(arr, low, high)
return arr
}
function merge (arr, low, high) {
const mid = Math.floor((low + high)/2)
let left = low
let right = mid + 1
const result = []
while (left <= mid && right <= high) {
if (arr[left] <= arr[right]) {
result.push(arr[left++])
} else {
result.push(arr[right++])
}
}
while (left <= mid) {
result.push(arr[left++])
}
while (right <= high) {
result.push(arr[right++])
}
arr.splice(low, high-low+1, ...result)
}
const test = [2, 34, 452,3,5, 785, 32, 345, 567, 322,5]
console.log(MergeSort(test, 0, test.length - 1))
(7) Куча сортировки
微信公众号:世界上有意思的事
function HeapSort (arr) {
const length = arr.length
// 调整初始堆,调整完其实也确定了最大值
// 但此时最大值是在 arr[0] 中
for (let i = Math.floor(length/2) - 1; i >= 0; i--) {
adjustHeap(arr, i, length)
}
// 把 arr[0](最大值)换到后面
for (let i = length - 1; i >=0; i--) {
const temp = arr[0]
arr[0] = arr[i]
arr[i] = temp
adjustHeap(arr, 0, i)
}
return arr
}
// size 是还需要调整的堆的大小
// 随着一个个最大值的确定,size 会越来越小
function adjustHeap (arr, position, size) {
const left = position * 2 + 1
const right = left + 1
let maxIndex = position
if (left < size && arr[left] > arr[maxIndex]) {
maxIndex = left
}
if (right < size && arr[right] > arr[maxIndex]) {
maxIndex = right
}
if (maxIndex !== position) {
const temp = arr[position]
arr[position] = arr[maxIndex]
arr[maxIndex] = temp
adjustHeap(arr, maxIndex, size)
}
return arr
}
Два, JS основа
1. Наследование
-
1. Цепное наследование прототипов, использующее экземпляр родительского класса в качестве прототипа подкласса, его характеристика заключается в том, что экземпляр является экземпляром подкласса и экземпляром родительского класса, а новый метод/свойство прототипа родителя класс может быть доступен подклассу, а цепочка наследования прототипа проста и легка в реализации. Недостаток заключается в том, что все свойства объекта-прототипа являются общими для всех экземпляров, поэтому множественное наследование не может быть достигнуто, и параметры не могут быть переданы родителю конструктор класса.
-
2. Создание наследования, использование конструктора родительского класса для улучшения экземпляра подкласса, то есть копирование атрибутов экземпляра родительского класса в подкласс, и создание наследования может передавать параметры родительскому классу, реализовывать множественное наследование и вызывать несколько объектов родительского класса. Однако структурное наследование может наследовать только свойства и методы экземпляра родительского класса, а не свойства и методы прототипа, и не может реализовывать функции.Каждый подкласс имеет копию функции экземпляра родительского класса, что влияет на производительность.
-
3. Наследование экземпляра, добавление новых функций к экземпляру родительского класса и возврат его в качестве экземпляра подкласса, особенность наследования экземпляра в том, что оно не ограничивает вызывающий метод, будь то новый подкласс() или подкласс() Возвращаемый объект имеет тот же эффект, недостаток Экземпляр является экземпляром родительского класса, а не экземпляром подкласса, и множественное наследование не поддерживается.
-
4. Копирование наследования: Возможности: Поддержка множественного наследования. Недостатки: Низкая эффективность, большое использование памяти (поскольку необходимо копировать свойства родительского класса). доступ с помощью for in )
-
5. Комбинированное наследование: путем вызова структуры родительского класса, наследования свойств родительского класса и сохранения преимуществ передачи параметров, а затем использования экземпляра родительского класса в качестве прототипа дочернего класса для повторного использования функции.
-
6. Паразитическое комбинированное наследование: отключите атрибуты экземпляра родительского класса с помощью паразитного метода, чтобы при двойном вызове конструкции родительского класса метод/свойство экземпляра не инициализировался дважды, что позволяет избежать недостатков комбинированного наследования.
2. это указывает на
(1). На какие точки это указывает?
-
1. Привязка по умолчанию: в глобальной среде это по умолчанию привязано к окну.
-
2. Неявная привязка. Как правило, когда вызывается функция, содержащаяся в прямом объекте, также называемая вызовом метода, она неявно привязывается к прямому объекту.
-
3. Неявная потеря. Неявная потеря означает, что неявно связанная функция теряет объект привязки, поэтому по умолчанию она привязывается к окну. Явная привязка: привязка объекта к this с помощью методов call(), apply() и bind() называется явной привязкой.
-
4. новая привязка: если вызову функции или метода предшествует ключевое слово new, он представляет собой вызов конструктора. Для этой привязки она называется новой привязкой.
- Конструкторы обычно не используют ключевое слово return, они обычно инициализируют новые объекты, которые явно возвращаются после завершения выполнения тела функции конструктора. В этом случае выражение вызова конструктора оценивается как значение этого нового объекта.
- Если конструктор использует оператор return без указания возвращаемого значения или возвращает примитивное значение, то возвращаемое значение игнорируется, а в качестве результата вызова используется новый объект.
- Если конструктор явно возвращает объект с помощью оператора return, то значением вызывающего выражения является этот объект.
(2) Измените указатель this внутри функции, чтобы он указывал на функцию (разница между связыванием, применением и вызовом).
-
1.apply: вызвать метод объекта, заменив текущий объект другим объектом. Например: B.apply(A, arguments), то есть метод, с помощью которого объект A применяет объект B.
-
2.call: вызвать метод объекта, заменив текущий объект другим объектом. Например: B.call(A, args1, args2), то есть метод объекта A для вызова объекта B.
-
3.bind имеет те же параметры, что и вызов, за исключением того, что возврат является функцией.
(3) Функция стрелки
- 1. Стрелочные функции не имеют this, поэтому значение this необходимо определить, просматривая цепочку областей видимости, что означает, что если стрелочная функция содержится в нестрелочной функции, это связано с this ближайшего нестрелочная функция.
- 2. Стрелочные функции не имеют собственного объекта аргументов, но могут обращаться к объекту аргументов окружающей функции.
- 3. Его нельзя вызвать через ключевое слово new, а также нет значения и прототипа new.target.
3. Тип данных
(1) Основные типы данных
Undefined, Null, Boolean, Number, String, Symbol
(2).symbol
-
1. Синтаксис:
// 不能用 new let s = Symbol() // 可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。 let s1 = Symbol('foo'); let s2 = Symbol('bar'); s1 // Symbol(foo) s2 // Symbol(bar) s1.toString() // "Symbol(foo)" s2.toString() // "Symbol(bar)" -
2. Роль: определить уникальное значение
-
1. Используется как имя свойства объекта
- 1. не появится в
for...in,for...ofцикла и не будетObject.keys(),Object.getOwnPropertyNames(),JSON.stringify()вернуть. - 2.
Object.getOwnPropertySymbols()чтобы получить все имена свойств Symbol указанного объекта. Этот метод возвращает массив всех значений Symbol, используемых в качестве имен свойств для текущего объекта. - 3.
Reflect.ownKeys()Метод может возвращать все типы имен ключей, включая имена обычных ключей и имена ключей символов.
- 1. не появится в
-
2. Используется для определения набора констант
log.levels = { DEBUG: Symbol('debug'), INFO: Symbol('info'), WARN: Symbol('warn') };
-
-
3. Преобразование типов:
-
1. Преобразовать в строку
String(sym) // 'Symbol(My symbol)' sym.toString() // 'Symbol(My symbol)' -
2. Преобразуется в логический
Boolean(sym) !sym -
3. Невозможно передать номерам
-
4. Не может работать с другими типами значений
let sym = Symbol('My symbol'); "your symbol is " + sym // TypeError: can't convert symbol to string `your symbol is ${sym}` // TypeError: can't convert symbol to string
-
-
4. Свойства: Symbol.prototype.description
-
5.Символ.для(), Символ.keyFor()
- 1. Зарегистрируйте значение Symbol в глобальной среде. не восстанавливается после
(3) Как определить тип
typeof(), instanceof, Object.prototype.toString.call()
-
1.
typeofоператор- 1. "не определено" - если значение не определено;
- 2. "boolean" - если значение логическое;
- 3. "строка" - если значение является строкой;
- 4. "число" - если значение является числовым значением;
- 5. "объект" - если значение является объектом или нулем;
- 6. "функция" - если значение является функцией.
- 7. "символ" - новый тип символа es6
-
2.
instanceof: Используется для определения того, является ли объект экземпляром конструктора. будут найдены по цепочке прототипов -
3.
Object.prototype.toString.call()var toString = Object.prototype.toString; toString.call(new Date); // [object Date] toString.call(new String); // [object String] toString.call(Math); // [object Math] toString.call([]); // [Object Array] toString.call(new Number) // [object Number] toString.call(true) // [object Boolean] toString.call(function(){}) // [object Function] toString.call({}) // [object Object] toString.call(new Promise(() => {})) // [object Promise] toString.call(new Map) // [object Map] toString.call(new RegExp) // [object RegExp] toString.call(Symbol()) // [object Symbol] toString.call(function *a(){}) // [object GeneratorFunction] toString.call(new DOMException()) // [object DOMException] toString.call(new Error) // [object Error] toString.call(undefined); // [object Undefined] toString.call(null); // [object Null] // 还有 WeakMap、 WeakSet、Proxy 等
(4) Определить, является ли это массивом
- 1.
Array.isArray(arr) - 2.
Object.prototype.toString.call(arr) === '[Object Array]' - 3.
arr instanceof Array - 4.
array.constructor === Array
(5).Строка к номеру
parseInt(string, radix)
4.CallBack Hell
То, как мозг планирует вещи, имеет линейную, блокирующую, однопоточную семантику, но то, как обратные вызовы выражают асинхронный поток, нелинейно и непоследовательно, что очень затрудняет правильное получение такого кода. Трудный для понимания код — это плохой код, который приводит к серьезным ошибкам. Нам нужен более синхронный, последовательный, блокирующий способ выражения асинхронности, как это делает наш мозг.
Также, что более важно, обратные вызовы подлежат инверсии управления, потому что обратные вызовы неявно передают управление третьей стороне (обычно стороннему инструменту, который не находится под вашим контролем!) для вызова продолжения в вашем коде. Можно придумать некоторую конкретную логику для решения этих проблем с доверием, но это сложнее, чем должно быть, и может привести к более тяжелому, сложному в сопровождении коду, которому не хватает адекватной защиты, где ущерб не наступит, пока вы не подвергнетесь воздействию ошибка будет обнаружена.
Нам нужно общее решение для решения этих проблем с доверием. Независимо от того, сколько коллбэков мы создали, эта программа должна использоваться повторно, и нет накладных расходов на код.
(1). Почему и как обещания используются для решения инверсии контрольной задачи доверия
Реализация промисов может бытьСмотри сюда
Обещание — это шаблон, который передает обратные вызовы как параметры с заслуживающей доверия семантикой, что делает такое поведение более надежным и разумным. Инвертируя инверсию управления обратным вызовом обратно, мы передаем управление в доверенную систему (Promises), предназначенную для того, чтобы сделать асинхронное кодирование более чистым. Промисы не устраняют обратные вызовы, они просто передают планирование обратных вызовов доверенному посреднику между нами и другими инструментами.
-
Обратный вызов вызывается слишком рано;
-
Этот вопрос в основном связан с тем, будет ли код вводить побочные эффекты, подобные Zalgo (см. главу 2). В этом типе проблемы задача иногда выполняется синхронно, а иногда асинхронно, что может привести к условиям гонки.
По определению промисы не должны беспокоиться об этом, потому что даже промисы, которые завершаются немедленно (что-то вроде new Promise(function(resolve){ resolve(42); })) не могут наблюдаться синхронно.
То есть при вызове then(..) для промиса обратный вызов, предоставляемый then(..), всегда будет вызываться асинхронно, даже если промис разрешен (подробнее см. раздел 1.5).
-
-
Обратный вызов вызывается слишком поздно (или не вызывается);
- Как и в предыдущем пункте, когда промис создает объект и вызывает resolve(..) или reject(..) , наблюдаемый обратный вызов, зарегистрированный промисом then(..), будет отправлен автоматически. Вы можете быть уверены, что эти запланированные обратные вызовы будут запущены в следующей точке асинхронного события (см. Раздел 1.5).
-
обратный звонок не вызывается
- Во-первых, ничто (даже ошибка JavaScript) не может помешать промису уведомить вас о своем разрешении (если оно разрешится). Если вы зарегистрируете обратный вызов выполнения и обратный вызов отклонения с промисом, то промис всегда будет вызывать один или другой, когда он разрешается.
- Но что, если сами промисы никогда не разрешаются?Даже в этом случае промисы предоставляют решение, используя высокоуровневый механизм абстракции, называемый расами:
-
Обратный вызов вызывается слишком много раз;
- Обещание определено таким образом, что оно может быть разрешено только один раз. Если по какой-то причине код создания промиса попытается вызвать resolve(..) или reject(..) несколько раз, или и то, и другое, промис примет только первое разрешение и молча проигнорирует все последующие вызовы.
- Поскольку обещания могут быть разрешены только один раз, любой (каждый) обратный вызов, зарегистрированный с помощью then(..), будет вызываться только один раз.
-
Не удалось передать требуемую среду и параметры;
-
Промисы могут иметь не более одного значения разрешения (завершить или отклонить).
Если вы явно не разрешаете какое-либо значение, то значение не определено, что является обычным способом работы в JavaScript. Но независимо от того, какое это значение, текущее или будущее, оно будет передано всем зарегистрированным (и завершенным или отклоненным в зависимости от ситуации) обратным вызовам.
-
-
Проглотить возможные ошибки и исключения.
- Если обещание отклонено по причине (например, сообщение об ошибке), это значение передается обратному вызову отклонения.
(2).обещание, генератор, асинхронное/ожидание
-
promise
- Преимущество: решает проблему callback hell
- Недостатки: Обещание нельзя отменить, ошибки должны быть перехвачены функцией обратного вызова.
-
generator
- Код внутри генератора представляет собой серию шагов, которые выражают задачу естественным синхронным/последовательным образом.
-
async/await
-
Достоинства: Код понятен, не нужно писать много потом цепочек типа промисов, решена проблема callback hell
-
Недостатки: await трансформирует асинхронный код в синхронный, если несколько асинхронных операций не имеют зависимостей, использование await приведет к падению производительности.
-
5. Загрузка
(1) Метод асинхронной загрузки js
-
defer: поддерживает только IE Если ваш скрипт не изменяет содержимое документа, вы можете добавить атрибут defer в
<script>теги для ускорения обработки документов. Поскольку браузер знает, что он сможет безопасно прочитать остальную часть документа без выполнения сценария, он отложит интерпретацию сценария до тех пор, пока документ не будет показан пользователю. -
async: атрибут HTML5, применимый только к внешним скриптам; и если в IE одновременно существуют defer и async, то defer имеет более высокий приоритет; скрипт будет выполнен, когда страница будет завершена.
(2) Ленивая загрузка и предварительная загрузка картинок
- Предварительная загрузка: загружайте изображения заранее и визуализируйте их непосредственно из локального кеша, когда пользователю нужно их просмотреть.
- Ленивая загрузка. Основная цель ленивой загрузки — оптимизировать внешний интерфейс сервера и уменьшить количество запросов или отложенных запросов.
Суть двух технологий: поведение двух противоположное, одна ранняя загрузка, одна ленивая или вообще без загрузки. Ленивая загрузка имеет определенный эффект снижения нагрузки на внешний интерфейс сервера, в то время как предварительная загрузка увеличивает нагрузку на внешний интерфейс сервера.
6. События
(1) Поток событий
Взаимодействие с javascript в HTML реализуется на основе событий, таких как событие щелчка мыши при щелчке, событие прокрутки страницы при прокрутке и т. д. Вы можете добавить прослушиватели событий в документ или элементы в документе для подписки на события. Чтобы знать, когда вызываются эти события, необходимо понимать концепцию «потока событий».
Что такое поток событий: поток событий описывает порядок получения событий со страницы.Поток событий уровня DOM2 включает следующие этапы.
- этап захвата событий
- на целевой стадии
- фаза всплытия события
IE поддерживает только всплывающие окна событий.
(2) Что такое мониторинг событий
addEventListener()Метод, используемый для добавления дескриптора события к указанному элементу, он может более просто управлять событиями, синтаксис
element.addEventListener(event, function, useCapture);
-
Первый параметр — это тип события (например, «щелчок» или «нажатие мыши»).
-
Второй параметр — это функция, которая будет вызываться после возникновения события.
-
Третий параметр — это логическое значение, описывающее, является ли событие всплывающим или перехватываемым. Этот параметр является необязательным.
target.addEventListener(type, listener, options: EventListenerOptions);
target.addEventListener(type, listener, useCapture: boolean);
target.addEventListener(type, listener, useCapture: boolean, wantsUntrusted: boolean ); // Gecko/Mozilla only
interface EventListenerOptions {
capture?: boolean // 表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发
once?: boolean // 表示 listener 在添加之后最多只调用一次。如果是 true, listener 会在其被调用之后自动移除
passive?: boolean // 设置为true时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告
}
(3) Разница между mouseover и mouseenter
- mouseover: когда мышь перемещается в элемент или его дочерние элементы, событие будет запущено, поэтому существует процесс повторного запуска и всплытия. Соответствующее событие удаления — mouseout
- mouseenter: когда мышь удаляет сам элемент (подэлементы, не содержащие элемент), будет запущено событие, то есть он не будет всплывать, а соответствующее событие удаления — mouseleave
(4) Делегирование событий и принцип всплытия
Введение: делегирование события означает не установку функции прослушивания в месте, где происходит событие (прямой DOM), а установку функции прослушивания в его родительском элементе. дочерний элемент Различные ответы делаются путем оценки типа DOM элемента, в котором происходит событие.
Например: самый классический — это мониторинг событий тегов ul и li.Например, когда мы добавляем события, мы используем механизм делегирования событий, который будет добавляться не непосредственно на тег li, а на родительский элемент ul.
Преимущества: он более подходит для связывания динамических элементов. Вновь добавленные подэлементы также будут иметь функции слушателя и механизмы запуска событий.
(5) Практическое применение прокси события на этапе захвата
Вы можете запретить распространение событий на дочерние элементы на уровне родительского элемента или выполнить определенные действия от имени дочерних элементов.
7. Перекрестный домен
(1).CORS
Основная идея CORS (Cross-Origin Resource Sharing) заключается в использовании настраиваемых заголовков HTTP, позволяющих браузеру взаимодействовать с сервером.
Например, простой запрос, отправленный с помощью GET или POST, не имеет пользовательского заголовка, а содержимое тела является текстовым/обычным. При отправке запроса необходимо прикрепить к нему дополнительный заголовок Origin, который содержит исходную информацию (протокол, доменное имя и порт) запрашиваемой страницы, чтобы сервер мог решить, давать ли ответ по этой информации заголовка . Вот пример заголовка Origin:
Origin: http://www.nczonline.netЕсли сервер считает запрос приемлемым, он возвращает тот же источник в заголовке Access-Control-Allow-Origin.
Информация (если это публичный ресурс, можно постить обратно "*"). Например:
Access-Control-Allow-Origin: http://www.nczonline.net
Если такого заголовка нет или если этот заголовок есть, но исходная информация не совпадает, браузер отклонит запрос. Обычно браузер обрабатывает запрос. Обратите внимание, что ни запрос, ни ответ не содержат информации о файлах cookie.
(2).IE
Microsoft представила тип XDR (XDomainRequest) в IE8. Ниже приведены некоторые различия между XDR и XHR.
- Файл cookie не отправляется с запросом и не возвращается с ответом.
- Можно установить только поле Content-Type в информации заголовка запроса.
- Информация заголовка ответа недоступна.
- Поддерживаются только запросы GET и POST.
(3) Другие браузеры
Встроенная поддержка CORS через объект XMLHttpRequest.
- Пользовательские заголовки нельзя установить с помощью setRequestHeader().
- Невозможно отправлять и получать файлы cookie.
- Вызов метода getAllResponseHeaders() всегда возвращает пустую строку.
(4).JSONP
微信公众号:世界上有意思的事
function handleResponse(response){
alert("You’re at IP address " + response.ip + ", which is in " +
response.city + ", " + response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse"; document.body.insertBefore(script, document.body.firstChild);
- JSON поддерживает только получение, потому что теги сценария могут использовать только запросы на получение;
- JSONP требует, чтобы серверная часть взаимодействовала для возврата данных в указанном формате.
(5).Агентство
Запустите прокси-сервер для пересылки данных
(6). Использование iframe
- window.postMessage
- Cross Frame(aba)
- window.name
lovelock.coding.what/JavaScript/…
(7).window.postMessage
Поддерживает только браузеры IE8 и выше, другие современные браузеры, конечно, не проблема.
(8) Ребенок общается с родителем
не подлежитТа же политика происхожденияпределы
-
Добавьте привязки событий к стороне, получающей данные:
addEventListener('message', receiveMessage); -
Сторона, отправляющая данные, получает окно стороны, получающей данные:
targetWindow.postMessage("Welcome to unixera.com", "http://iframe1.unixera.com");
(9).Чилид общается с ребенком
Существует междоменная проблема, которая подходит только для связи между разными поддоменами на сайте (установите document.domain на доменное имя одного уровня)
(10).Cross Frame
Это общий метод.Короче говоря, iframe A содержит iframe B, и связанный интерфейс вызывается в iframe B, а результат получается после завершения вызова.location.hrefПерейдите к iframe C в том же домене, что и iframe A, вызовите метод, определенный в iframe A в iframe C, передайте результат, полученный в iframe B, в качестве параметра URL-адресу, на который нужно перейти, и передайтеlocation.searchпеременная, чтобы получить переменную.
(11).window.name
windowобъектnameАтрибут — это особый атрибут, после установкиwindow.nameПосле этого выполнитеlocation.hrefПрыгать,window.nameСвойство по-прежнему не меняется, и таким образом можно добиться передачи переменных.
8.Ajax
(1) Внедрение Ajax
微信公众号:世界上有意思的事
var xhr = new XMLHttpRequest()
// 必须在调用 open()之前指定 onreadystatechange 事件处理程序才能确保跨浏览器兼容性
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status ==== 304) {
console.log(xhr.responseText)
} else {
console.log('Error:' + xhr.status)
}
}
}
// 第三个参数表示异步发送请求
xhr.open('get', '/api/getSth', true)
// 参数为作为请求主体发送的数据
xhr.send(null)
(2). Состояние Ajax
- Неинициализированный. Метод open() не был вызван.
- запускать. Метод open() был вызван, но метод send() не был вызван.
- Отправить. Был вызван метод send(), но ответа не получено.
- перенимать. Получены частичные данные ответа.
- Заканчивать. Все данные ответа получены и готовы к использованию на стороне клиента.
(3) Инкапсулируйте нативный ajax в промис.
微信公众号:世界上有意思的事
const ajax = (url, method, async, data) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
// 已经接收到全部响应数据,而且已经可以在客户端使用了
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText))
} else if (xhr.status > 400) {
reject('发生错误')
}
}
}
xhr.open(url, method, async)
xhr.send(data || null)
})
}
9. Сбор мусора
Найдите те переменные, которые больше не используются, и освободите память, которую они занимают. Для этого сборщик мусора выполняет эту операцию периодически через равные промежутки времени (или по расписанию во время выполнения кода).
(1).Отметить как очищенный
Сначала помечаются все, а затем не помечаются переменные, на которые есть ссылки в среде. Остальное бесполезно
(2) Подсчет ссылок
Отслеживайте, сколько раз упоминается каждое значение. Очистить переменные, счетчик ссылок которых равен 0 ⚠️Будет проблема циклической ссылки. Большое количество циклических ссылок может привести к утечке памяти.
10.Что такое оценка
Метод eval подобен полному синтаксическому анализатору ECMAScript, он принимает только один параметр, строку ECMAScript (или JavaScript) для выполнения.
- 1. Низкая производительность: движок не может оптимизировать поиск области действия во время компиляции.
- 1. Движок JavaScript выполнит несколько оптимизаций производительности на этапе компиляции. Некоторые из этих оптимизаций полагаются на возможность статического анализа кода лексически и заранее определяют, где определены все переменные и функции, чтобы быстро находить идентификаторы во время выполнения.
- 2. Невозможно точно знать, какой код получит eval(..) на этапе лексического анализа, как эти коды изменят область видимости, и невозможно узнать содержимое объекта, переданного с помощью для создания нового лексический объем что. Самый пессимистичный случай заключается в том, что при наличии eval(..) или with все оптимизации могут оказаться бессмысленными, поэтому проще всего вообще не проводить никаких оптимизаций.
- 2. Подмена области действия: Но в программах строгого режима eval(..) имеет собственную лексическую область действия во время выполнения, что означает, что объявления в ней не могут изменять область, в которой она находится.
11. Слушайте изменения свойств объекта
(1).ES5
微信公众号:世界上有意思的事
Object.defineProperty(user,'name',{
set:function(key,value){
// 这也是 Vue 的原理
}
})
(2) ЭС6
微信公众号:世界上有意思的事
var user = new Proxy({}, {
set:function(target,key,value,receiver){
}
})
Может отслеживать динамически добавляемые свойства. Напримерuser.id = 1
12. Реализуйте приватную переменную
-
1. Свойства конфигурации
obj={ name: 'xujiahui', getName:function(){ return this.name } } object.defineProperty(obj,"name",{ //不可枚举不可配置 }); -
2. Код
微信公众号:世界上有意思的事
function product(){
var name='xujiahui';
this.getName=function(){
return name;
}
}
var obj=new product();
13. Операторы
(1).==а также===,так же какObject.isразница
-
1.
==-
1. Будет выполнено приведение (!= также)
-
2. Операторы равенства и неравенства следуют следующим основным правилам при преобразовании различных типов данных:
-
3. Если один из операндов является логическим значением, преобразовать его в числовое значение перед сравнением на равенство — false преобразуется в 0, а true — в 1.
-
4. Если один операнд является строкой, а другой операнд является числом, перед сравнением на равенство преобразуйте строку в число;
-
5. Если один операнд является объектом, а другой нет, вызовите метод valueOf() объекта и используйте полученное значение базового типа для сравнения в соответствии с предыдущими правилами; эти два оператора должны следовать следующему правилу сравнения.
-
6.null и undefined равны.
-
7. Вы не можете преобразовать null и undefined в любое другое значение перед сравнением на равенство.
-
8. Если один из операндов равен NaN, оператор равенства возвращает false, а оператор неравенства возвращает true. Важно ⚠️: оператор равенства возвращает false, даже если оба операнда имеют значение NaN, потому что по правилам NaN не равно NaN.
-
9. Если оба операнда являются объектами, сравните, являются ли они одним и тем же объектом. Оператор равенства возвращает истину, если оба операнда указывают на один и тот же объект, иначе возвращает ложь.
-
-
-
2.
===: все равны, без преобразования -
3.
Object.is- 1. Он не делает обязательный преобразование типа.
- 2. с
===Есть несколько отличий:- 1.
+0===-0,Object.is(+0, -0)ложно - 2.
NaN !== NaN,Object.is(NaN, NaN)правда
- 1.
(2) Что делает новый оператор?
Вызов конструктора с оператором new на самом деле проходит через следующие 4 шага:
- 1. Создайте новый объект;
- 2. Назначьте область действия конструктора новому объекту (чтобы это указывало на новый объект);
- 3. Выполните код в конструкторе (добавьте свойства для этого нового объекта);
- 4. Верните новый объект.
- 5. Свяжите прототип конструктора с __proto__ экземпляра
14. Массивы
(1) Общие методы массивов
push(), pop(), shift(), unshift(), splice(), sort(), reverse(), map() и т. д.
(2) Дедупликация массива
На что следует обратить внимание, так это на то, как утяжелить объект
-
1. Двойная петля
Каждый раз, когда элемент вставляется, он сравнивается с каждым предыдущим элементом.
var array = [1, 1, '1', '1']; function unique(array) { // res用来存储结果 var res = []; for (var i = 0, arrayLen = array.length; i < arrayLen; i++) { for (var j = 0, resLen = res.length; j < resLen; j++ ) { if (array[i] === res[j]) { break; } } // 如果array[i]是唯一的,那么执行完循环,j等于resLen if (j === resLen) { res.push(array[i]) } } return res; } console.log(unique(array)); // [1, "1"] -
2.
indexOfПринцип тот же, что и у двойной петли.
var array = [1, 1, '1']; function unique(array) { var res = []; for (var i = 0, len = array.length; i < len; i++) { var current = array[i]; if (res.indexOf(current) === -1) { res.push(current) } } return res; } console.log(unique(array)); -
3. Дедупликация после сортировки
Для отсортированных массивов каждый элемент можно сравнить с предыдущим.
var array = [1, 1, '1']; function unique(array) { var res = []; var sortedArray = array.concat().sort(); var seen; for (var i = 0, len = sortedArray.length; i < len; i++) { // 如果是第一个元素或者相邻的元素不相同 if (!i || seen !== sortedArray[i]) { res.push(sortedArray[i]) } seen = sortedArray[i]; } return res; } console.log(unique(array)); -
4. Пара ключ-значение объекта
Сохраните каждый элемент как ключ объекта. Например
['a'], сохранить как{'a': true}var array = [1, 2, 1, 1, '1']; function unique(array) { var obj = {}; return array.filter(function(item, index, array){ return obj.hasOwnProperty(item) ? false : (obj[item] = true) }) } console.log(unique(array)); // [1, 2]Мы можем обнаружить, что есть проблема, потому что 1 и '1' разные, но этот метод будет оценивать одно и то же значение, потому что ключевое значение объекта может быть только строкой, поэтому мы можем использовать
typeof item + itemУкажите строку в качестве значения ключа, чтобы избежать этой проблемы:var array = [1, 2, 1, 1, '1']; function unique(array) { var obj = {}; return array.filter(function(item, index, array){ return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true) }) } console.log(unique(array)); // [1, 2, "1"]Однако даже в этом случае мы все равно не можем правильно различать два объекта, например {value: 1} и {value: 2}, потому что
typeof item + itemрезультат будетobject[object Object], но мы можем использовать JSON.stringify для сериализации объекта:var array = [{value: 1}, {value: 1}, {value: 2}]; function unique(array) { var obj = {}; return array.filter(function(item, index, array){ console.log(typeof item + JSON.stringify(item)) return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)] = true) }) } console.log(unique(array)); // [{value: 1}, {value: 2}] -
5.ES6 Установить дедупликацию
function unique(array) { return Array.from(new Set(array)); }function unique(array) { return [...new Set(array)]; } -
6.ES6 Map
function unique (arr) { const seen = new Map() return arr.filter((a) => !seen.has(a) && seen.set(a, 1)) }
3. Продвинутые навыки
1. Дроссельная защита от сотрясений
(1).
Выполняется только один раз в n секунд, поэтому регулирование снижает частоту выполнения функции.
(2).
Последний счет. Например, «Остановить ввод на 5 с перед отправкой запроса».
3. Расширение массива
- 1. Рекурсия
微信公众号:世界上有意思的事
function flat1 (arr) {
let result = []
arr.forEach(element => {
if (Array.isArray(element)) {
result = result.concat(flat1(element))
} else {
result.push(element)
}
});
return result
}
- 2.toString
function flat2 (arr) {
// 有缺陷,toString 后无法保持之前的类型
return arr.toString().split(',')
}
- 3.reduce
微信公众号:世界上有意思的事
function flat3 (arr) {
// 本质和 flat1 一样的,都是递归
return arr.reduce((pre, next) => {
return pre.concat(Array.isArray(next) ? flat3(next) : next)
}, [])
}
- 4. оператор отдыха
微信公众号:世界上有意思的事
function flat4 (arr) {
while (arr.some(item => Array.isArray(item))) {
// 相当于 [].concat('1', 2, [3, 4])
// concat 方法本身就会把参数中的数组展开
arr = [].concat(...arr);
}
return arr;
}
- 5.ES6 flat
微信公众号:世界上有意思的事
function flat5 (arr: any[]) {
// flat() 方法会移除数组中的空项
return arr.flat(Infinity)
}
4. Перетащите
微信公众号:世界上有意思的事
var DragDrop = function(){
var dragging = null;
function handleEvent(event){
//获取事件和目标
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//确定事件类型
switch(event.type){
case "mousedown":
if (target.className.indexOf("draggable") > -1){
dragging = target;
}
break;
case "mousemove":
if (dragging !== null){
//指定位置
dragging.style.left = event.clientX + "px";
dragging.style.top = event.clientY + "px";
}
break;
case "mouseup":
dragging = null;
break;
}
};
//公共接口
return {
enable: function(){
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
},
disable: function(){
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
}
}
}();
-
1. Объект DragDrop инкапсулирует все основные функции перетаскивания. Это одноэлементный объект и использует шаблон модуля, чтобы скрыть некоторые детали реализации. Переменная перетаскивания изначально равна нулю и будет содержать перетаскиваемый элемент, поэтому, когда переменная не равна нулю, вы знаете, что что-то перетаскивается. Функция handleEvent() обрабатывает все три события мыши в функции перетаскивания. Сначала он получает ссылку на объект события и цель события. После этого используйте оператор switch, чтобы определить, какой стиль события запускать. Когда происходит событие mousedown, оно проверяет, содержит ли класс цели «перетаскиваемый» класс, и если да, то сохраняет цель в перетаскивании. Этот трюк упрощает идентификацию перетаскиваемых элементов с помощью языка разметки вместо скриптов JavaScript.
-
2. Движение мыши в handleEvent() такое же, как и в предыдущем коде, но проверьте, является ли перетаскивание нулевым. Когда он не нулевой, вы знаете, что перетаскивание — это элемент, который нужно перетаскивать, и это поместит его в правильное положение. Случай mouseup просто сбрасывает перетаскивание до нуля, делая недействительным суждение в событии mousemove.
-
3.DragDrop также имеет два общедоступных метода: enable() и disable(), которые просто добавляют и удаляют все обработчики событий соответственно. Эти две функции обеспечивают дополнительный контроль над функцией перетаскивания.
-
4. Чтобы использовать объект DragDrop, просто добавьте этот код на страницу и вызовите enable(). Перетаскивание автоматически включается для всех элементов, содержащих класс «перетаскиваемый», как показано в следующем примере:
<div class="draggable" style="position:absolute; background:red"> </div>Обратите внимание, что для того, чтобы элемент можно было перетаскивать, он должен быть абсолютно позиционирован.
5.once
微信公众号:世界上有意思的事
function once (func) {
var done;
return function () {
if (!done) {
func.apply(null, arguments)
done = true
}
}
}
微信公众号:世界上有意思的事
function onlyDoOne = once(function() {
console.log('1')
})
6.promise
Promiseэто объект, который содержит события, которые закончатся в будущем. У нее есть две характеристики:
-
1. Состояние объекта не зависит от внешних воздействий,
PromiseОбъект представляет собой асинхронную операцию и имеет три состояния: ожидание, выполнено успешно и отклонено не удалось.Только результат асинхронной операции может определить, в каком состоянии он находится в данный момент, и никакая другая операция не может изменить это состояние, являющееся источником обещание имени -
2. Как только состояние изменится, оно больше не изменится,
PromiseЕсть только две возможности изменить состояние объекта, с ожидания на выполнено или с ожидания на отклонение Пока эти две ситуации происходят, состояние замораживается и больше не изменится Это время называется преодолением стереотипа.
7.sleep
использоватьPromise
-
function sleep (ms) { return new Promise((resolve) => { window.setTimeout(resolve, ms) }) } sleep(1000).then(()=>{ console.log('已经 sleep 1000ms') }) -
function sleep (ms) { return new Promise((resolve) => { window.setTimeout(resolve, ms) }) } // 使用async/await调用 async function test () { var example = await sleep(1000) console.log('已经 sleep 1000ms') } -
// 使用 generator 定义 sleep 函数 function *sleep (ms) { yield new Promise((resolve) => { window.setTimeout(resolve, ms) }) } sleep(1000).next().value.then(()=>{ console.log('已经 sleep 1000ms') })
4. Браузер
1. Кэш
(1) Разделено по расположению кеша
- 1.Service Worker
- 1. Есть две ситуации, которые могут привести к очистке ресурсов в этом кэше: Вызов API вручную.
cache.delete(resource)Или емкость превышает лимит и полностью опустошается браузером. - 2. Если сервис-воркеру не удается попасть в кеш, он обычно используется
fetch()Метод продолжает извлекать ресурс. В это время браузер переходит к кешу памяти или кешу диска для следующего поиска кеша. Примечание. После обслуживания работникfetch()Ресурс, полученный методом, будет помечен какfrom ServiceWorker.
- 1. Есть две ситуации, которые могут привести к очистке ресурсов в этом кэше: Вызов API вручную.
- 2. Кэш памяти: если вкладка закрыта, она будет недействительной.
- 1. Механизм кэширования памяти гарантирует, что при наличии на странице двух одинаковых запросов (например, двух
srcидентичныйimage,дваhrefидентичныйlink) на самом деле запрашиваются не более одного раза, чтобы избежать потерь. - 2. При извлечении кэшированного содержимого из кеша памяти браузеры игнорируют, например.
max-age=0,no-cacheи другие конфигурации заголовка. Например, есть несколько одинаковыхsrc, даже если для них установлено значение «не кэшировать», они все равно будут считываться из кэша памяти. Это связано с тем, что кэш памяти используется только в течение короткого периода времени, и в большинстве случаев жизненный цикл состоит только из одного просмотра. а такжеmax-age=0Обычно это семантически интерпретируется как «не использовать его в следующий раз при просмотре», поэтому он не конфликтует с кешем памяти. - 3. Но если вебмастер очень не хочет пускать ресурс в кеш даже в краткосрочной перспективе, его нужно использовать
no-store. Если есть такая конфигурация заголовка, то даже кеш памяти его не сохранит, и естественно не прочитает из него.
- 1. Механизм кэширования памяти гарантирует, что при наличии на странице двух одинаковых запросов (например, двух
- 3. Дисковый кэш: дисковый кэш будет строго определять, какие ресурсы можно кэшировать, а какие нельзя кэшировать в соответствии с различными полями в информации заголовка HTTP, какие ресурсы все еще доступны, а какие ресурсы устарели и требуют повторного запроса. При попадании в кеш браузер будет читать ресурсы с жесткого диска, хотя это медленнее, чем чтение из памяти, но все же намного быстрее, чем сетевые запросы.Большая часть кеша поступает из кеша диска.
- 4. Сетевой запрос: если запрос не находит кеш в трех указанных выше местах, браузер официально отправит сетевой запрос для получения содержимого. Позже нетрудно подумать, что для улучшения скорости попадания в кеш последующих запросов естественно добавить этот ресурс в кеш. Конкретно:
- 1. Определите, следует ли сохранять в хранилище кэша (дополнительное расположение кэша) в соответствии с обработчиком в Service Worker.
- 2. По соответствующим полям HTTP-заголовка (
Cache-control,Pragmaи т. д.), чтобы решить, следует ли хранить в дисковом кеше - 3.кэш памяти экономит ресурсцитаты, для следующего использования.
(2) Согласно стратегии отказа
Кэш памяти — это собственная оптимизация браузера для увеличения скорости чтения кеша, она не контролируется разработчиком и не привязана к заголовку протокола HTTP, это черный ящик. Service Worker — это дополнительный скрипт, написанный разработчиком, и расположение кеша не зависит от него, он также появился поздно и не получил широкого распространения. Итак, то, с чем мы больше всего знакомы, на самом делеdisk cache,Также известен какHTTP cache(Потому что, в отличие от кеша памяти, он учитывает поля в заголовках HTTP). обычно говорятПринудительный кеш (сильный кеш), контрастный кеш (согласованный кеш),так же как
Cache-Controlд., также попадают в эту категорию.
Принудительное кэширование (также называемое сильным кэшированием)
Принудительное кэширование для непосредственного уменьшения количества запросов — это стратегия кэширования, которая улучшается больше всего.Его оптимизация охватывает три этапа запроса, обработки и ответа.
Поля, которые могут привести к принудительному кэшированию:Cache-controlа такжеExpires.
-
Истекает:
- HTTP1.0
- Поскольку это абсолютное время, пользователь может изменить локальное время клиента, в результате чего браузер решит, что кеш недействителен, и снова запросит ресурс. Кроме того, даже если достоверная модификация не рассматривается, такие факторы, как разница во времени или ошибка, могут привести к тому, что время между клиентом и сервером будет несогласованным, что приведет к аннулированию кэша.
- Писать слишком сложно. Несколько пробелов и меньшее количество букв в строке, представляющей время, приведут к недопустимым атрибутам и неверным настройкам.
-
Cache-control
-
HTTP1.1
-
высокий приоритет
-
max-age: максимально допустимое времяmust-revalidate: если большеmax-ageвремя браузер должен отправить запрос на сервер, чтобы убедиться, что ресурс все еще действителен.no-cache: хотя это буквально означает «не кэшировать», на самом деле это требует, чтобы клиент кэшировал содержимое, но использование содержимого определяется последующими сравнениями.no-store: Настоящее "не кешировать". Весь контент не кэшируется, включая приведение и сравнение.public: Весь контент может быть кэширован (как клиенты, так и прокси, такие как CDN).private: весь контент может кэшироваться только клиентом, а не прокси-сервером. По умолчанию.
-
Кэш сравнения (кэш согласования)
Сравнение количества кешированных запросов согласуется с отсутствием кеша, но если это 304, он возвращает только код состояния, а фактического содержимого файла нет, поэтомуЭкономия объема тела отклика является точкой его оптимизации..
- Last-Modified & If-Modified-Since
- сервер через
Last-ModifiedПоле сообщает клиенту, когда ресурс был в последний раз изменен. - Браузер записывает это значение в базу данных кеша вместе с содержимым.
- В следующий раз, когда запрашивается тот же ресурс, браузер ищет кеш с неопределенным сроком действия в своем собственном кеше. Поэтому в заголовке запроса последний
Last-ModifiedЗначение записывается в заголовок запросаIf-Modified-Sinceполе - Сервер будет
If-Modified-Sinceзначение сLast-Modifiedполя для сравнения. Если они равны, это означает, что он не был изменен и отвечает кодом 304; в противном случае это означает, что он был изменен, и он отвечает кодом состояния 200 и возвращает данные. - Если частота обновления ресурса составляет доли секунды, то кэш нельзя использовать, поскольку его минимальная единица времени — секунды.
- Если файл динамически генерируется сервером, время обновления этого метода всегда является временем генерации, хотя файл может и не изменяться, поэтому он не играет роли в кэшировании.
- сервер через
- Etag & If-None-Match
- Etag имеет приоритет над Last-Modified
-
EtagСохраняется специальный идентификатор файла (обычно генерируемый хэшем), а сервер хранит идентификатор файла.Etagполе. - последующий процесс и
Last-Modifiedпоследовательный, простоLast-ModifiedПоле и время обновления, которое оно представляет, изменены наEtagполе и хэш файла, который он представляет, поместитеIf-Modified-SinceсталIf-None-Match. - Сервер выполняет такое же сравнение, возвращая 304 для попаданий и 200 для нового ресурса при промахах.
(3).Ajax решает проблему кэширования браузера
-
1. Добавьте anyAjaxObj.setRequestHeader("If-Modified-Since","0") перед отправкой запроса ajax.
-
2. Добавьте anyAjaxObj.setRequestHeader("Cache-Control","no-cache") перед отправкой запроса ajax.
-
3. Добавьте случайное число после URL: "fresh=" + Math.random().
-
4. Добавьте время после URL-адреса: "nowtime=" + new Date().getTime().
-
5. Если вы используете jQuery, просто выполните $.ajaxSetup({cache:false}). Таким образом, все ajax страницы будут выполнять этот оператор, поэтому нет необходимости сохранять запись в кеше.
2. Браузерный принцип рендеринга
(1).Render Tree
- Не показывай(
display: none) Элемент не создается - имеют
RenderTree, мы знаем стили всех узлов, затем вычисляем их размер и положение на странице (layout) и, наконец, рисуем узлы на странице (draw). - Поскольку браузеры используют плавные макеты,
Render TreeВычисление , как правило, нужно пройти только один раз,ноtableза исключением их внутренних элементов, которые могут потребовать нескольких вычислений, обычно занимающих в 3 раза больше времени, чем эквивалентные элементы, поэтому вам следует избегать использованияtableОдна из причин макета.
(2).Перерисовать
Макет не затрагивается из-за изменения геометрических свойств узла или из-за изменения стиля, называемого перерисовкой, напримерoutline, visibility, color,background-colorи т. д., перерисовка стоит дорого, потому что браузер должен проверять видимость других элементов узла в дереве DOM.
(3) Обратный поток
Перекомпоновка — это когда необходимо изменить макет или геометрические свойства, и это называется перекомпоновкой. Перекомпоновка — это ключевой фактор, влияющий на производительность браузера, поскольку его изменения связаны с обновлением макета для частей страницы (или всей страницы). Перекомпоновка элемента может привести к последующей перекомпоновке всех его дочерних элементов, а также непосредственно следующих узлов и элементов-предков в DOM.
(4) Оптимизация браузера
Большинство современных браузеров обновляют макет пакетами с помощью механизма очереди.Браузер поставит операцию модификации в очередь, и по крайней мере одно обновление браузера (т.е. 16,6 мс) очистит очередь, но когда выПри получении информации о макете в очереди могут быть операции, влияющие на возвращаемое значение этих свойств или методов. Даже если нет, браузер принудительно очистит очередь, запустив перекомпоновку и перерисовку, чтобы гарантировать, что возвращается правильное значение..
В основном он включает следующие свойства или методы:
-
offsetTop,offsetLeft,offsetWidth,offsetHeight -
scrollTop,scrollLeft,scrollWidth,scrollHeight -
clientTop,clientLeft,clientWidth,clientHeight -
width,height getComputedStyle()getBoundingClientRect()
Поэтому нам следует избегать частого использования вышеуказанных свойств, все они заставляют рендеринг обновлять очередь.
(5) Уменьшите перерисовку и перекомпоновку
-
1.CSS
-
2.использовать
transformзаменятьtop -
3.использовать
visibilityзаменятьdisplay: none, потому что первое вызовет только перерисовку, второе вызовет перекомпоновку (изменит макет -
4.избегать использования
tableмакет, небольшое изменение может привести к полнойtableперестановка. -
5.как можно больше
DOMКонец дерева измененийclass, рефлюкс неизбежен, но его эффект можно уменьшить. Изменение класса, насколько это возможно, в самом конце дерева DOM ограничивает область перекомпоновки, чтобы затронуть как можно меньше узлов. -
6.Избегайте установки нескольких слоев встроенных стилей., CSS-селекторсправа налевоПоиск соответствий, чтобы избежать слишком большого количества уровней узлов.
<div> <a> <span></span> </a> </div> <style> span { color: red; } div > a > span { color: red; } </style>Для первой настройки стиля браузеру просто нужно найти все
spanметку, а затем установить цвет, но для второго способа установки стиля браузеру сначала нужно найти всеspanметка, затем найтиspanна этикеткеaметка и, наконец, найтиdivярлык, а затем дайтеspanМетка задает цвет, поэтому рекурсивный процесс очень сложен. Поэтому мы должны избегать написания как можно большеслишком конкретныйселекторы CSS, а затем добавьте в HTML как можно меньше бессмысленных тегов, чтобы убедиться, чтоИерархия квартира. -
7.Применение анимационных эффектов к
positionсобственностьabsoluteилиfixedна элементе, чтобы не влиять на компоновку других элементов, это просто перерисовка, а не перекомпоновка, при этом скорость анимации управления можно выбиратьrequestAnimationFrame, видетьИсследуйте запросAnimationFrame. -
8.избегать использования
CSSвыражение, может вызвать обратный поток. -
9.Установите часто перерисовываемые или перекомпоновываемые узлы в качестве слоев, слой может предотвратить влияние рендеринга этого узла на другие узлы, например
will-change,video,iframeи другие теги, браузер автоматически превратит узел в слой. -
10.Аппаратное ускорение CSS3 (ускорение GPU), с помощью аппаратного ускорения css3 можно сделать
transform,opacity,filtersЭти анимации не вызывают перерисовки перерисовки. Но для других свойств анимации, таких какbackground-colorОни по-прежнему будут вызывать перекомпоновку и перерисовку, но все же могут повысить производительность этих анимаций.
-
-
2.JavaScript
- 1.Избегайте частых стилей манипулирования, желательно разовую перезапись
styleили определите список стилей какclassи поменять все сразуclassАтрибуты. - 2.Избегайте частых операций
DOM,СоздаватьdocumentFragment, на него распространяются всеDOM操作и, наконец, добавьте его в документ. - 3.Избегайте частого чтения свойств, которые вызывают перекомпоновку/перерисовку, если вам действительно нужно использовать его несколько раз, используйте переменную для его кэширования.
- 4.Используйте абсолютное позиционирование для элементов со сложной анимацией, вынося его из потока документа, иначе это вызовет частую перекомпоновку родительского элемента и последующих элементов.
- 1.Избегайте частых стилей манипулирования, желательно разовую перезапись
(6) Когда анализируется JS?
-
<script>-
В процессе рендеринга, если встречается JS, рендеринг останавливается и выполняется код JS.
-
Если JS необходимо управлять CSSOM, он сначала позволит построить CSSOM, затем выполнить JS и, наконец, построить DOM.
-
-
<script async>- Выполнить импортированный JavaScript асинхронно, выполнить JS после завершения загрузки и заблокировать DOM
-
<script defer>- Отсрочка исполнения.Синтаксический анализ HTML не блокируется при загрузке файла JavaScript, а фаза выполнения размещается после завершения синтаксического анализа тега HTML.
5. Основы работы с компьютером
1. Компьютерная сеть
(1).Трехстороннее рукопожатие TCP
-
1. Первое рукопожатие: сначала оба конца находятся в закрытом закрытом состоянии, клиент устанавливает флаг SYN в 1, случайным образом генерирует значение seq=x и отправляет пакет данных на сервер, клиент входит в состояние SYN-SENT состояние и ждет подтверждения сервера;
-
2. Второе рукопожатие: после того, как сервер получил пакет данных, бит флага SYN=1 знает, что клиент запрашивает установление соединения, и сервер устанавливает биты флага SYN и ACK в 1, ack=x+1 и случайным образом генерирует значение seq= y и отправляет пакет данных Клиенту для подтверждения запроса на соединение, Сервер переходит в состояние SYN-RCVD, а операционная система выделяет TCP-буферы и переменные для TCP-соединения;
-
3. Третье рукопожатие: после того, как клиент получил подтверждение, он проверяет, равен ли ACK x+1 и ACK равен 1. Если все верно, бит флага ACK устанавливается в 1, ack=y+1 и операционная система TCP-соединение выделяет TCP-буферы и переменные и отправляет пакет данных на сервер.Сервер проверяет, является ли подтверждение y+1 и ACK равным 1. Если это правильно, соединение установлено успешно. Клиент и Сервер переходят в состояние ESTABLISHED, завершают трехстороннее рукопожатие, после чего Клиент и Сервер могут начать передачу данных.
(2) Принцип CDN
Полное название CDN — Content Delivery Network, то есть Content Delivery Network. Основной принцип CDN заключается в широком использовании различных кэш-серверов и распределении этих кэш-серверов по регионам или сетям, где доступ пользователей относительно сконцентрирован.Когда пользователи посещают веб-сайт, используется технология глобальной загрузки, чтобы направить доступ пользователя к ближайшему рабочему серверу. обычный кеш.На сервере кеш-сервер отвечает напрямую
(4).Разрешение DNS
- Кэширование браузера: браузеры кэшируют DNS-записи с определенной периодичностью.
- Кэш операционной системы: если вы не можете найти нужную DNS-запись в кеше браузера, поищите в операционной системе.
- Кэш маршрутов: Маршрутизаторы также имеют кэши DNS.
- DNS-сервер интернет-провайдера: ISP — это аббревиатура от Internet Service Provider (Интернет-провайдер), и у ISP есть специальный DNS-сервер для обработки запросов DNS-запросов.
- Корневой сервер: если DNS-сервер провайдера по-прежнему не найден, он отправит запрос на корневой сервер для выполнения рекурсивного запроса (DNS-сервер сначала запрашивает у корневого сервера доменных имен IP-адрес сервера доменных имен .com, а потом спрашивает сервер доменных имен .baidu, по очереди аналогия)
(5) Общие заголовки запросов HTTP
HTTP-заголовки можно разделить на общие заголовки, запрашивать заголовки, заголовки ответа и заголовки сущностей
| Заголовок протокола | иллюстрировать |
|---|---|
| Accept | Допустимые типы содержимого ответа (Content-Types). |
| Accept-Charset | приемлемый набор символов |
| Accept-Encoding | Приемлемая кодировка содержимого ответа. |
| Accept-Language | Список допустимых языков содержимого ответа. |
| Accept-Datetime | приемлемые версии содержания ответа с точки зрения времени |
| Authorization | Информация аутентификации, используемая для указания ресурса аутентификации, необходимого в протоколе HTTP. |
| Cache-Control | Используется для указания, следует ли использовать механизм кэширования в текущем запросе/ответе. |
| Connection | Тип соединения, которое клиент (браузер) хочет использовать в первую очередь |
| Cookie | Файл cookie протокола HTTP, установленный предыдущим сервером с помощью Set-Cookie (см. ниже). |
| Content-Length | Длина тела запроса в восьмеричном формате |
| Content-MD5 | Двоичный хэш MD5 (цифровая подпись) содержимого тела запроса, закодированный в Base64. |
| Content-Type | MIME-тип тела запроса (используется в запросах POST и PUT) |
| Date | Дата и время отправки сообщения (вRFC 7231для отправки в формате «Дата HTTP», определенном в) |
| Expect | Указывает, что клиент просит сервер выполнить определенное действие |
| From | Адрес электронной почты пользователя, который инициировал этот запрос |
| Host | Указывает доменное имя сервера и номер порта, который прослушивает сервер. Если запрошенный порт является стандартным портом (80) соответствующей службы, номер порта можно не указывать. |
| If-Match | Соответствующая операция выполняется только в том случае, если объект, предоставленный клиентом, соответствует соответствующему объекту на сервере. В основном используется в таких методах, как PUT, для обновления ресурса, только если он не был изменен с момента последнего обновления пользователем. |
| If-Modified-Since | Разрешить возвращать 304 Not Modified, если соответствующий ресурс не был изменен |
| If-None-Match | Допускается возвращать 304 Not Modified (304 Not Modified), если соответствующий контент не был изменен, см. тег сущности протокола передачи гипертекста. |
| If-Range | Если объект не был изменен, верните отсутствующую часть или части. В противном случае вернуть всю новую сущность |
| If-Unmodified-Since | Отправлять ответ только в том случае, если сущность не изменялась с определенного времени. |
| Max-Forwards | Ограничивает количество раз, которое это сообщение может быть перенаправлено прокси-серверами и шлюзами. |
| Origin | инициироватьСовместное использование ресурсов между источникамиЗапрос (запрос требует сервера Joins-Control-Control-Tower-Preectore заголовок происхождения в ответном сообщении указывает источник разрешенного контроля доступа). |
| Pragma | В зависимости от конкретной реализации эти поля могут создаваться в любой точке цепочки запроса/ответа. |
| Proxy-Authorization | Информация об аутентификации, используемая для аутентификации на прокси. |
| Range | Указывает, что запрашивается часть объекта, а смещение в байтах начинается с 0. |
| Referer | Указывает на предыдущую страницу, посещенную браузером, которую можно рассматривать как ссылку на ранее посещенную страницу, которая привела браузер на текущую страницу. Referer на самом деле является словом Referrer, но RFC неправильно написал его при создании стандарта, а позже по ошибке использовал Referer. |
| TE | Кодировка, которую браузер ожидает получить при передаче: значение в заголовке ответа Transfer-Encoding (можно также использовать «трейлеры» для указания метода фрагментации передачи данных) может использоваться для указания того, что браузер ожидает последнюю размер, равный 0, также получает некоторые дополнительные поля после блока. |
| User-Agent | Идентификационная строка браузера |
| Upgrade | Требуется обновление сервера до более высокой версии протокола. |
| Via | Сообщите серверу, какие прокси сделали этот запрос. |
| Warning | Общее предупреждение о том, что в теле содержимого объекта может быть ошибка. |
(5). Семиуровневая модель OSI
Прикладной уровень: передача файлов, распространенные протоколы HTTP, snmp, FTP,
Уровень представления: форматирование данных, транскодирование, шифрование данных,
Сеансовый уровень: устанавливать и освобождать сеансы
Транспортный уровень: обеспечить сквозной интерфейс, tcp, udp
Сетевой уровень: маршрутизация пакетов, IP, icmp
Уровень канала передачи данных: транспортирует адресованные кадры
Физический уровень: данные в двоичной форме передаются на физическом носителе.
(5) Разница между TCP и UDP
- 1.UDP
- 1. Нет связи
- 2. Ориентация на сообщение, просто переносчик сообщения
- 3. Ненадежность, отсутствие контроля перегрузок
- 4. Эффективный, заголовок занимает всего 8 байт.
- 5. Поддержка «один к одному», «один ко многим», «многие ко многим» и «многие к одному».
- 6. Подходит для высоких требований в реальном времени, таких как прямая трансляция, видео, голос, конференция и т. Д.
- 2.TCP
- 1. Ориентированность на подключение: вам необходимо подключиться перед передачей
- 2. Надежная передача
- 3. Управление потоком: отправитель не будет отправлять слишком быстро, превышая пропускную способность получателя.
- 4. Контроль перегрузки: когда сеть перегружена, она может ограничить скорость отправки отправителя.
- 5. Не предусматривайте временную задержку
- 6. Нет гарантии минимальной пропускной способности
(6). Почему три рукопожатия и четыре волны
- 1. Четыре волны
- 1. Поскольку обе стороны установили соединения друг с другом, обе стороны должны разорвать свои соединения.А отправляет запрос на разрыв соединения Б. Он хочет освободить связь, чтобы указать, что он больше не будет отправлять данные В. В это время, B получает сообщение, отправленное A. После выпуска запроса на соединение отправьте подтверждение A, A больше не может отправлять данные B, он находится в состоянии FIN-WAIT-2, но B все еще может передавать данные A в этот раз. В это время B отправляет запрос на отключение к A, а A отправляет подтверждение к B после его получения. В этот момент B закрывает соединение. A также закрывает соединение.
- 2. Почему существует состояние TIME-WAIT? Это связано с тем, что последнее подтверждение может быть потеряно. Если B продолжает отправлять запрос A на отключение в это время, ожидая, пока A отправит подтверждение, но A закрыл соединение в это время. , то В никогда не может быть выключено, поэтому мы имеем состояние ВРЕМЯ-ОЖИДАНИЕ.
- Конечно, TCP не на 100% надежен.
- 1. Трехстороннее рукопожатие:Чтобы предотвратить повторную передачу сегмента неудачного запроса на соединение на сервер, что приведет к ошибке
(7) В чем разница между websocket и ajax и каковы сценарии применения websocket
Рождение WebSocket, по сути, должно решить одностороннюю проблему самого протокола HTTP: запрос должен быть инициирован клиентом к серверу, и тогда сервер ответит. Это отношение «запрос-ответ» не может быть изменено. Для общего просмотра веб-страниц и доступа, конечно, нет проблем.Как только нам понадобится сервер для активной отправки сообщений клиенту, это будет проблематично, потому что предыдущее TCP-соединение было разорвано, и клиент вообще не может быть найден. . Чтобы вовремя получать данные с сервера, различные решения, которые кропотливо исследовали программисты, на самом деле являются компромиссами, сделанными в рамках HTTP-фреймворка. Так что все либо опрашивают регулярно, либо полагаются на долгое соединение - клиент инициирует запрос, сервер держит соединение в руке и не отвечает, и ждет возврата сообщения, и если оно истекло, клиент снова запрашивает - На самом деле все знают, что это всего лишь опрос, который уменьшает количество запросов и имеет лучшую производительность в реальном времени Суть не изменилась.
WebSocket принципиально решает эту проблему технически: как видно из названия, он заимствует порт и заголовок сообщения из Сети для создания соединения, а последующая передача данных почти точно такая же, как у Socket на основе TCP, но инкапсулирует много оригинальных Socket.Функций, которые нам нужно делать вручную во время разработки. Например, нативная поддержка безопасного доступа wss (общий порт и сертификат с https), проверка при создании соединения, автоматическое разделение пакетов сообщений из фреймов данных и т. д.
Другими словами, изначально мы могли использовать только HTTP-протокол в браузере, но теперь у нас есть Socket, который лучше Socket.
Разобравшись в предыстории и характеристиках WebSocket, вы можете ответить на вопрос, сможет ли он заменить AJAX:
Для двунаправленной связи между сервером и клиентом лучше всего подходит WebSocket. Если бы не несколько старых браузеров, все еще находящихся в эксплуатации, все опросы, постоянные соединения и т. д. были бы давно заброшены. Самым большим преимуществом тех библиотек, которые интегрируют несколько методов двустороннего push-сообщения (таких как http://Socket.IO, SignalR), была их совместимость со всеми версиями браузеров, автоматическое распознавание старых браузеров и использование других методов подключения. Сейчас они постепенно утрачиваются.Плюсы - Все новые браузеры совместимы с WebSocket, только используйте родной. В качестве отступления, это очень похоже на jQuery, который быстро развивался, когда нативный js было сложно использовать, а когда другие библиотеки и нативный js поглотили многие из его преимуществ, он постепенно стал менее важным. Тем не менее, большая часть сценариев использования AJAX по-прежнему представляет собой традиционные формы запроса-ответа, такие как получение json-данных, почтовые формы и т. д. Хотя эти функции также могут быть реализованы с помощью WebSocket, точно так же, как HTTP-протокол на основе запросов определяется поверх TCP, который изначально передает потоки данных, нам также необходимо переопределить новый протокол поверх WebSocket, по крайней мере, добавить идентификатор запроса используется для различения запроса, соответствующего каждому ответу данных.
... но зачем создавать новое колесо слой за слоем? Разве не проще и зрелее использовать AJAX напрямую?
Есть и другая ситуация, то есть при передаче больших файлов, картинок и медиапотоков лучше всего использовать для передачи HTTP. Если вы должны использовать WebSocket, по крайней мере, откройте новый канал специально для этих данных, вместо того, чтобы занимать соединение, которое используется для отправки сообщений и требует высокой производительности в реальном времени. В противном случае последовательный WebSocket будет полностью заблокирован.
Поэтому WebSocket может быть гибким, простым и эффективным в двунаправленной передаче и проталкивании сообщений, но он не очень полезен в обычном процессе Запрос-Ответ, и доставляет гораздо больше хлопот, чем обычные HTTP-запросы, или даже более неэффективен.
У каждой технологии есть свои преимущества и недостатки, и она может проявлять свои сильные стороны там, где она уместна, и, видя ее несколько преимуществ и продвигая ее во всех направлениях независимо от случая, может быть контрпродуктивно.
Мы сами использовали WebSocket при разработке интернет-ботов, которые могут общаться с мобильными телефонами, и это работает хорошо. Но вместо того, чтобы использовать его для замены HTTP, он заменяет сокет на основе TCP, который изначально использовался для связи.
Преимущество:
Первоначально после соединения Socket требовалась сложная аутентификация, и в то же время было необходимо предотвратить отправку управляющих команд неаутентифицированными соединениями. Теперь нет необходимости, параметры аутентификации могут быть переданы в URL-адресе для установления соединения WebSocket.Если аутентификация не удалась, она может быть отклонена напрямую без установки статуса;
Я изначально реализовал набор механизмов асимметричного шифрования, похожих на SSL, но сейчас он мне вообще не нужен, я напрямую шифрую через wss, и он кстати тоже может обеспечить достоверность сертификата;
Если изначально нужно было определить формат данных Socket, установить длину и флаги, а также решить такие проблемы, как залипание пакетов и подпакетов, то теперь WebSocket напрямую получает полный пакет данных, и ему вообще не нужно с ним разбираться ;
Внешний nginx может напрямую выполнять пересылку и балансировку нагрузки, а развертывание намного проще.
(8) Сетевая модель TCP/IP
-
1. Модель TCP/IP — это общий термин для серии сетевых протоколов, предназначенных для обеспечения обмена информацией между компьютерами.
-
2. Архитектура четырехуровневой модели TCP / IP снизу вверх - это канальный уровень, сетевой уровень, транспортный уровень, прикладной уровень.
-
3. Роль канального уровня заключается в установлении цепных соединений и является физической основой всей сети.Типичные протоколы включают Ethernet, ADSL и т. д.
-
4. Сетевой уровень отвечает за выделение адресов и передачу бинарных данных.Основным протоколом является протокол IP.
-
5. За передачу текстовых данных отвечает транспортный уровень, основной протокол — TCP
-
7. Прикладной уровень отвечает за передачу различных конечных форм данных и является уровнем, который непосредственно имеет дело с пользовательской информацией.Основные протоколы — http, ftp и т. д.
2. HTTP-протокол
(1) Общие методы запроса
HTTP 1.0
- 1.GET: запросить данные из указанного ресурса
- 2.POST: отправьте данные для обработки на указанный ресурс, например
- 1. Отправьте форму
- 2. Размещать сообщения на досках объявлений, в группах новостей, списках рассылки, блогах или подобных группах статей;
- 3.HEAD
- 1. Аналогичен запросу на получение, за исключением того, что в возвращаемом ответе нет конкретного содержимого, только заголовок
- 2. Запрашивать только заголовок ресурса
- 3. Проверьте действительность гиперссылок
- 4. Проверьте, была ли изменена веб-страница.
HTTP1.1
- 1.PUT: заменить или создать указанный ресурс
- 2. УДАЛИТЬ: удалить указанный ресурс
HTTP2.0
-
1. ОПЦИИ: используется для получения параметров связи, поддерживаемых целевым ресурсом, таких как метод запроса, поддерживаемый сервером, и т. д.
-
2. TRACE: реализует обратную проверку сообщений на пути к целевому ресурсу, предоставляя практичный механизм отладки.
-
3.CONNECT
-
1. Подготовлено для прокси-сервера
-
2. В протоколе HTTP
CONNECTМетод открывает двусторонний канал связи между клиентом и запрашиваемым ресурсом. Его можно использовать для создания туннелей. Например,CONNECTможно использовать для доступа кSSL (HTTPS) сайт протокола. Клиент просит прокси-сервер туннелировать TCP-соединение с хостом назначения. После этого сервер установит соединение с хостом назначения вместо клиента. После установления соединения прокси-сервер отправляет или получает поток TCP-сообщений клиенту.
-
Все универсальные серверы должны поддерживать методы GET и HEAD. Все остальные методы являются необязательными.
- 1. Безопасность: вэта спецификацияСреди определенных методов запроса методы GET, HEAD, OPTIONS и TRACE определены как безопасные.
- 2. идемпотентность: PUT, DELETE и метод безопасности являются идемпотентными.
- 3. Кэшируемость: GET, HEAD и POST. Но большинство из них реализуют только кэширование GET и HEAD.
- 1. Указывает, что браузер автоматически кэширует его для последующих запросов. Если в ответе нет соответствующей политики
(2) Разница между GET и POST
-
1. Параметр get передается через URL-адрес, а пост помещается в тело запроса.
-
2. Параметры, передаваемые в URL-адресе запроса на получение, ограничены по длине, а сообщение — нет.
-
3. Get менее безопасен, чем post, потому что параметры напрямую отображаются в URL-адресе, поэтому их нельзя использовать для передачи конфиденциальной информации.
-
4. Запрос на получение может быть закодирован только в URL, в то время как сообщение поддерживает различные методы кодирования.
-
5. Запрос на получение будет активно кэшироваться браузером, а сообщение поддерживает различные методы кодирования.
-
6. Параметры запроса на получение полностью сохранятся в истории посещений, а параметры в посте не сохранятся.
-
7. GET и POST по сути являются ссылками TCP, и между ними нет никакой разницы. Однако из-за правил HTTP и ограничений браузера/сервера они показывают некоторые различия в процессе подачи заявки.
(3). Код состояния HTTP
- 1xx (информационное): запрос получен, обработка
- 2xx (успешно): запрос успешно получен, понят и принят
- 3xx (перенаправление): перенаправление
- 4xx (ошибка клиента): запрос содержит неправильный синтаксис или не может быть выполнен
- 5xx (ошибка сервера): ошибка сервера
(4) В чем конкретная разница между 301 и 302
-
301: перемещено навсегда, запрошенная веб-страница была окончательно перемещена в новое место, сервер возвращает этот ответ, и запросчик будет автоматически перемещен в новое место.
-
302: Историческое перемещение, сервер в настоящее время отвечает на запросы с веб-страниц в разных местах, но запрашивающая сторона должна продолжать использовать исходное местоположение для продолжения последующих запросов.
3. Операционная система
(1) Разница между процессом и потоком
-
1. Процесс — основная единица распределения ресурсов и управления ими при выполнении параллельно выполняемых программ, динамическая концепция, конкурирующая с компьютерными системами.ресурсбазовая единица.
-
2. Потоки являются частью процесса, процесс без потоков можно рассматривать как однопоточный. Потоки иногда называют облегченными процессами или облегченными процессами, а такжеПланирование ЦПосновная единица .
В программе есть хотя бы один процесс, в процессе есть хотя бы один поток, этому процессу выделяются ресурсы, и все потоки одного и того же процесса совместно используют ресурсы процесса.
(2) Какие ресурсы потока являются общими, а какие нет.
-
1. Общие ресурсы
- 1. Куча: так как куча открывается в пространстве процесса, она разделяется как само собой разумеющееся, поэтому новые разделяются (глобальная куча и локальная куча разделены на 16-битной платформе, а локальная куча является исключительно общей))
- 2. Глобальная переменная: она не связана с конкретной функцией, поэтому она не связана с конкретным потоком, поэтому она также является общей
- 3. Статическая переменная: хотя для локальной переменной она "помещается" в функцию в коде, но место ее хранения такое же, как и у глобальной переменной, она хранится в открытых секциях .bss и .data в куче.
- 4. Общие ресурсы, такие как файлы: они являются общими, и потоки, использующие эти общие ресурсы, должны быть синхронизированы. Win32 предоставляет несколько способов синхронизации ресурсов, включая сигналы, критические секции, события и мьютексы.
-
2. Эксклюзивные ресурсы включают
- 1. Стек: стек является эксклюзивным
- 2 Регистр: Это может быть неправильно понято, поскольку регистр компьютера является физическим, различается ли значение для каждого потока? Фактически поток хранится в копии, в том числе счетчика программ ПК
(3) Каковы методы связи между процессами
- 1. Анонимный канал: метод полудуплексной связи, данные могут передаваться только в одном направлении и могут использоваться только между родственными процессами.
- 2. Расширенный конвейер: запустить другую программу как новый процесс в текущем программном процессе, тогда этот процесс рассматривается как дочерний процесс текущей программы,
- 3. Известный канал: это также полудуплексный метод связи, но он позволяет обмениваться данными между процессами без родственников.
- 4. Очередь сообщений: очередь сообщений представляет собой связанный список с сообщениями, хранящимися в ядре и идентифицируемыми идентификатором очереди сообщений.Очередь сообщений преодолевает недостаток информации о передаче сигнала, конвейер может передавать только неформатированные потоки байтов и размер буфера. ограничено Недостатки
- 5. Семафор: семафор — это счетчик, который можно использовать для управления доступом нескольких процессов к общим ресурсам.Он часто используется в качестве механизма блокировки, чтобы предотвратить доступ других процессов к общему ресурсу, когда процесс обращается к нему.
- 6. Сигнал: используется для уведомления принимающего процесса о том, что произошло событие.
- 7. Общая память. Общая память предназначена для отображения раздела памяти, к которому могут обращаться другие процессы. Эта разделяемая память создается одним процессом, но к ней могут обращаться несколько процессов.Общая память является самым быстрым методом IPC и часто используется в сочетании с другими механизмами связи.
- 8. Сокеты: могут использоваться для обмена данными между различными машинами.
6. Расширенный интерфейс
1.VUE
(1) Жизненный цикл vue
Экземпляр VUE имеет полный жизненный цикл, то есть с начала создания, данные инициализации, скомпилированные шаблоны, монтаж DOM, рендеринг серии процессов → Обновление → Рендеринг, разрушение и т. Д. Мы назвали это Vue жизненным циклом. Популярный экземпляр Vue, то есть обрабатывать от создания к разрушению, это жизненный цикл.
У каждого компонента или экземпляра будет полный жизненный цикл, разделенный на три фазы: инициализация, запуск, уничтожение.
-
1. После того, как экземпляр и компонент будут созданы через новый Vue(), событие и жизненный цикл будут инициализированы, а затем будет выполнена функция ловушки beforeCreate.В это время данные не были смонтированы, просто пустая оболочка, не могут получить доступ к данным и реальному дому, как правило, не работают
-
2. Смонтируйте данные, привяжите события и т. д., а затем выполните созданную функцию. В это время данные могут быть использованы или изменены. Изменение данных здесь не вызовет обновленную функцию. Здесь можно использовать предпоследнее время перед рендеринг.Возможность изменить данные не будет запускать другие функции хука.Как правило, первоначальный сбор данных можно сделать здесь.
-
3. Затем начните находить шаблон, соответствующий экземпляру или компоненту, скомпилируйте шаблон в виртуальный дом и поместите его в функцию рендеринга для подготовки к рендерингу, а затем выполните функцию ловушки beforeMount, В этой функции виртуальный дом был создан и скоро будет отрендерен, здесь Вы также можете изменить данные, не запуская обновление. Здесь вы можете получить последний шанс изменить данные перед рендерингом, не запуская другие функции хука. Как правило, вы можете получить исходные данные здесь.
-
4. Далее запускаем рендеринг, рендерим реальный DOM, а затем выполняем функцию монтируемого хука.В это время компонент появился на странице, данные и реальный DOM обработаны, события смонтированы.Вы здесь может работать реальный дом и т. д...
-
5. Когда данные компонента или экземпляра изменяются, beforeUpdate будет выполнен немедленно, а затем механизм виртуального дома vue перестроит виртуальный дом и последнее дерево виртуального дома, используя алгоритм diff для сравнения и повторного рендеринга, как правило. ничего не делай
-
6. Когда обновление будет завершено, выполните Updated, данные были изменены, а также завершено повторное преобразование DOM, и можно работать с обновленным виртуальным DOM.
-
7. Когда метод $destroy вызывается определенным образом, метод beforeDestroy выполняется немедленно.Как правило, здесь выполняется некоторая последующая работа, такая как очистка таймеров, очистка событий, не связанных с инструкциями, и т. д.
-
8. Привязка данных и мониторинг компонентов... После удаления остается только оболочка dom.В это время выполнить destroy, здесь же можно сделать и последствия.
(2) Принцип двусторонней привязки Vue
Двусторонняя привязка данных Vue достигается за счет перехвата данных в сочетании с шаблоном издатель-подписчик. Использование Object.defineProperty() Этот метод переопределяет объект, чтобы получить значение свойства (get) и установить значение свойства (set).
2.Webpack
webpack — это сборщик статических модулей для современных приложений JavaScript. Когда webpack обрабатывает приложение, он рекурсивно строит граф зависимостей, содержащий каждый модуль, необходимый приложению, а затем объединяет все эти модули в один или несколько пакетов.
(1) Разница между webpack и gulp
Gulp делает упор на рабочий процесс фронтенд-разработки.Мы можем настроить ряд задач, определить транзакции, обрабатываемые задачами (такие как сжатие и слияние файлов, карта спрайтов, запуск сервера, контроль версий и т. д.), а затем определить порядок выполнения, позволяющий gulp выполнять эти задачи, тем самым выстраивая весь процесс разработки интерфейса проекта.
Webpack — это интерфейсное модульное решение, которое больше ориентировано на упаковку модулей.Мы можем рассматривать все ресурсы в разработке (изображения, файлы js, файлы css и т. д.) как модули и использовать загрузчик (загрузчик) и плагины (плагин) для обработки ресурсов.Обработка, упаковка во внешние ресурсы, соответствующие развертыванию в производственной среде.
3. Модульный
(1) Как понять модульность интерфейса
Модульность интерфейса — это сложное программирование файлов один за другим независимыми модулями, такими как файлы js и т. Д., Разделение на независимые модули способствует повторному использованию (повторному использованию) и обслуживанию (итерации версий), что приведет к проблеме взаимозависимости между модулями. , так что есть общие спецификации JS, спецификации AMD, CMD и т. д., а также webpack, инструмент для упаковки js (компиляции и т. д.)
(2) Расскажите о Commonjs, AMD и CMD.
Модуль - это файл, который может реализовать определенную функцию. С модулем вы можете легко использовать код других людей, и вы можете загрузить любой модуль, который вы хотите, с любой функцией, которую вы хотите.
-
1.Commonjs: начиная с модуляризации серверной части, модульности синхронного определения, каждый модуль представляет собой отдельную область, вывод модуля, модули.экспорт, загрузка модуля, модуль импорта require().
-
2.AMD: Значение определения асинхронного модуля китайского имени.
-
1.require JS реализует спецификацию AMD
-
1. В основном используется для решения следующих двух проблем.
- 1. Несколько файлов имеют зависимости, и зависимый файл должен быть загружен в браузер раньше, чем файл, который зависит от него.
- 2. При загрузке браузер останавливает отрисовку страницы, чем больше загружается файлов, тем дольше страница теряет время отклика.
-
2. Синтаксис: requireJS определяет функцию define, которая представляет собой глобальную переменную, используемую для определения модулей.
//定义模块 define(['dependency'], function(){ var name = 'Byron'; function printName(){ console.log(name); } return { printName: printName }; });//加载模块 require(['myModule'], function (my){ my.printName(); } -
-
2. Резюмируем спецификацию AMD: функция require() загружается асинхронно при загрузке зависимых функций, так что браузер не потеряет свой ответ, указанная ею функция обратного вызова будет выполняться только при успешной загрузке предыдущего модуля. Потому что веб-страница прекратит рендеринг при загрузке js, поэтому мы можем загружать js асинхронно, а если нам нужно от чего-то зависеть, мы также будем зависеть от этого асинхронно, а затем выполнять некоторые методы после зависимости.
-
4. Простая реализация модуля Node Events
Введение: режим наблюдателя или режим подписки, который определяет отношение «один ко многим» между объектами, позволяя нескольким объектам-наблюдателям одновременно отслеживать определенный предметный объект, когда объект изменяется, все объекты, которые зависят от него, будут уведомлены.
Модуль Events в узле реализован через шаблон Observer:
微信公众号:世界上有意思的事
var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');
Таким образом, eventEmitter генерирует событие say, получает его через On и выводит результат.Это реализация режима подписки.Давайте просто реализуем EventEmitter модуля Events.
-
1. Реализуйте методы emit и on простого модуля Event.
function Events(){ this.on=function(eventName,callBack){ if(!this.handles){ this.handles={}; } if(!this.handles[eventName]){ this.handles[eventName]=[]; } this.handles[eventName].push(callBack); } this.emit=function(eventName,obj){ if(this.handles[eventName]){ for(var i=0;o<this.handles[eventName].length;i++){ this.handles[eventName][i](obj); } } } return this; } -
2. Итак, мы определили Events, теперь мы можем начать вызывать:
var events=new Events(); events.on('say',function(name){ console.log('Hello',nama) }); //结果就是通过emit调用之后,输出了Jony yu events.emit('say','Jony yu'); -
3. Каждый объект независим
Поскольку используется новый метод, каждый раз создаются разные объекты, поэтому:
var event1=new Events(); var event2=new Events(); event1.on('say',function(){ console.log('Jony event1'); }); event2.on('say',function(){ console.log('Jony event2'); }) //event1、event2之间的事件监听互相不影响 //输出结果为'Jony event1' 'Jony event2' event1.emit('say'); event2.emit('say');
5. Оптимизация производительности
-
1. Уменьшите количество запросов: слейте ресурсы, уменьшите количество HTTP-запросов, сжатие minify/gzip, webP, lazyLoad изображений.
-
2. Ускорить запросы: пре-разрешить DNS, уменьшить количество доменных имен, параллельная загрузка, раздача CDN.
-
3. Кэш: запрос кэша протокола HTTP, манифест автономного кэша, локальное хранилище автономного кэша данных.
-
4. Рендеринг: оптимизация JS/CSS (избегайте использования выражений CSS), порядок загрузки (поместите таблицы стилей CSS вверху, javascript внизу), рендеринг на стороне сервера, конвейер.
7. Хвост
Видя это, вы удивляетесь силе юной леди? Спешите ставить лайки, комментировать, подписываться и делиться! !