【Интервью】Социальный рекрутинг Письменный тест Intermediate Intermediate Вопросы для собеседования - ответы и дополнения

внешний интерфейс JavaScript браузер Promise

Недавно я увидел статью, в которой резюмируются некоторые вопросы для фронтенд-интервью. Целью должен быть фронтенд среднего и среднего уровня социального рекрутинга. Я чувствую, что это имеет определенную справочную ценность. Поэтому я открыл пост, чтобы попробовать чтобы ответить на эти вопросы и, кстати, использовать их в качестве моих собственных вопросов для интервью.

Оригинальная ссылка нажмите здесь

Основы JavaScript

1. Заявить заранее о проблемах

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

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

// 请写出以下输出结果:
Foo.getName();
getName(); // 声明提前
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

Ответ на этот вопрос: 2, 4, 1, 1, 2, 3, 3.

Субъект оператора инспекции заранее отмечен в коде, и вот два оператора метода getName:

var getName = function () { alert (4) };
function getName() { alert (5) }

На самом деле именно в таком порядке при разборе:

function getName() { alert (5) }
var getName;
getName = function () { alert (4) };

Если мы добавим еще две точки останова в середине кода:

getName(); // 5
var getName = function () { alert (4) };
getName(); // 4
function getName() { alert (5) }

В первом getName и объявление функции, и объявление var помещаются перед первым getName, и операция присваивания getName не будет расширена. Простое использование объявления var не перезапишет переменную, определенную функцией. Поэтому , первым выводом getName является 5 объявления функции; Второй getName происходит после оператора присваивания, поэтому выходной результат равен 4, поэтому фактический порядок выполнения кода следующий:

function getName() { alert (5) }
var getName;
getName(); // 5
getName = function () { alert (4) };
getName(); // 4

2. Хранилище браузера

Разница между localStorage, sessionStorage и куки

Общий момент: все они хранятся на стороне браузера и доступны только из одного и того же источника.

  1. хранилище данных
  • Данные файлов cookie всегда передаются (даже если они не нужны) в HTTP-запросах одного и того же источника, т. е. файлы cookie передаются туда и обратно между браузером и сервером. Данные cookie также имеют концепцию пути, которая может ограничить принадлежность cookie определенному пути.
  • sessionStorage и localStorage не отправляют данные на сервер автоматически, а только сохраняют их локально.
  1. размер данных хранилища
  • Ограничение размера хранилища также отличается.Данные cookie не могут превышать 4 КБ.В то же время, поскольку каждый http-запрос будет содержать cookie, cookie подходит только для хранения небольших данных, таких как идентификатор сеанса.
  • Хотя sessionStorage и localStorage также имеют ограничения на размер хранилища, они намного больше файлов cookie и могут достигать 5 МБ и более.
  1. Срок действия хранения данных
  • sessionStorage: действует только до закрытия текущего окна браузера;
  • LocalStorage: всегда действителен, окно или выключение браузера также сохранено, локально сохраняется, поэтому он используется в качестве длительных данных;
  • cookie: действителен только до установленного времени истечения срока действия cookie, даже если окно закрыто или браузер закрыт
  1. разная сфера
  • sessionStorage не распределяется между разными окнами браузера, даже на одной и той же странице;
  • localstorage используется во всех окнах одного и того же источника, то есть пока браузер не закрыт, данные все еще существуют.
  • Файл cookie: он также используется всеми окнами одного и того же происхождения, то есть, пока браузер не закрыт, данные все еще существуют.

3. Междоменный

Вскоре я написал пост, в котором резюмировал политику единого источника и различные междоменные методы:Что такое междоменный доступ, почему браузеры запрещают междоменный доступ и к чему это приводит

4. Использование и принцип Обещания

Promise — это новая функция, добавленная в ES6, которая используется для более разумного решения проблем асинхронного программирования.Начало работы с ECMAScript 6Подробное описание сделано в , и здесь повторяться не будет.

30 минут, чтобы вы полностью поняли принцип Promise

Вышеупомянутая статья представляет собой подробное описание принципа промиса.Здесь я извлеку простейшую реализацию промиса, чтобы объяснить принцип промиса:

function Promise(fn) {
    var value = null,
        callbacks = [];  // callbacks为数组,因为可能同时有很多个回调

    this.then = function (onFulfilled) {
        callbacks.push(onFulfilled);
    };

    function resolve(value) {
        callbacks.forEach(function (callback) {
            callback(value);
        });
    }

    fn(resolve);
}

первый,thenодна или несколько функций, объявленных внутри, будут помещены вcallbacksСписок, вызываемый экземпляром PromiseresolveКогда метод проходится и вызывается, и передается вresolveЗначение параметра, переданное в метод.

Ниже используйте простой пример для анализа процесса выполнения Promise:

functionm func () {
	return new Promise(function (resolve) {
		setTimeout(function () {
			resolve('complete')
		}, 3000);
	})
}

func().then(function (res) {
	console.log(res); // complete
})

funcОпределение функции состоит в том, чтобы возвращать экземпляр Promise, а функция обратного вызова, передаваемая при объявлении экземпляра, добавляетresolveпараметры (этоresolveПараметры в промисеfn(resolve)получить определениеresolveфункциональная сущность), асинхронная операция выполняется в обратном вызове, а асинхронная операция выполняется в обратном вызове завершения асинхронной операцииresolveфункция.

Посмотрите на шаги выполнения,funcФункция возвращает экземпляр Promise, и этот экземпляр может выполнить обещание, определенное в конструкторе Promise.thenметод,thenОбратный вызов, переданный в методе, будет вresolve(то есть после завершения асинхронной операции), тем самым реализуяthenМетод выполняет функцию обратного вызова после завершения асинхронной операции.

5. Механизм цикла событий JavaScript

Статьи, размещенные в оригинальном тексте, имеют большую справочную ценность.Во-первых, разместите ссылку:Подробно объясните механизм цикла событий в JavaScript..

JavaScript — это однопоточный неблокирующий язык, поскольку изначально он был разработан для взаимодействия с браузерами:

  • Один поток:JavaScriptПричина, по которой он спроектирован как единый поток, заключается в том, что его основная роль в начале заключается в общении сDOMвзаимодействовать, представьте, еслиJavaScriptявляется многопоточным, то когда два потока одновременноDOMВыполните действие, например добавьте к нему событие, а другое удалите этоDOM, как бороться с этим в это время? Поэтому для того, чтобы ситуация, подобная этому примеру, не возникла,JavaScriptВыберите использование только одного основного потока для выполнения кода, чтобы обеспечить согласованность выполнения программы.
  • Неблокирующий: когда коду необходимо выполнить асинхронную задачу (задачу, которая не может немедленно вернуть результат и требует определенного времени для возврата, например, событие ввода-вывода), основной поток приостанавливается (pending) эту задачу, а затем выполнить соответствующий обратный вызов по определенным правилам, когда асинхронная задача вернет результат. а такжеJavaScriptСпособ добиться асинхронной работы — использовать цикл событий.
setTimeout(function () {
    console.log(1);
});

new Promise(function(resolve,reject){
    console.log(2)
    resolve(3)
}).then(function(val){
    console.log(val);
})

Давайте разберем эту проблему через кусок кода, прежде всегоsetTimeoutа такжеPromiseсерединаthenВсе обратные вызовы являются асинхронными методами, в то время какnew Promiseявляется синхронной операцией, поэтому этот код должен сначала немедленно вывести2;JavaScriptАсинхронные методы делятся наmarco task(Макрозадачи: включитьsetTimeoutа такжеsetIntervalи т.д.) иmicro task(Микрозадачи: включитьnew Promiseд.), вJavaScriptВ стеке выполнения, если одновременно есть макрозадачи и микрозадачи с истекшим сроком действия, сначала будут выполняться все микрозадачи, а затем будет выполняться первая макрозадача Таким образом, в двух асинхронных операцияхthenОбратный вызов будет выполнен первым, затемsetTimeoutОбратный вызов, поэтому он будет выводить 3, 1 по очереди, поэтому окончательный результат вывода будет 2, 3, 1.

6. ES6 Сфера действия и разница между пусть и var

Учитель в учителеНачало работы с ECMAScript 6серединаlet 和 const 命令В этой главе дается подробное описание этого вопроса, а ниже извлекаются некоторые из ключевых моментов, которые, как мне кажется, объясняются.

ES6 представил использование{}Обернутая область кода используется как метод объявления блочной области видимости, и ее действие такое же, как и в ES5.functionОбласть действия функции, сгенерированная объявленной функцией, имеет тот же эффект. Функции или переменные, объявленные внутри области, не могут быть доступны за ее пределами. Такие объявления используются в ES6 для включенияfor () {},if () {}Это вступит в силу в блоках кода, заключенных в фигурные скобки, что приведет к отдельной области действия.

Новое в ES6letПо сравнению с тем, как вы объявляете переменныеvarИмеет следующие важные особенности:

  • letОбъявленная переменная действительна только в пределах области действия, как показано в следующем коде:ifОбъявление создает область на уровне блока, и переменные, объявленные в этой области, не могут быть доступны за пределами области, и при доступе произойдет ошибка:
if (true) {
	let me = 'handsome boy';
}
console.log(me); // ReferenceError
  • letобъявленная переменная сvarДругое дело, никакого подъема переменной не произойдет.Следующий код, выводящий код перед объявлением, выдаст ошибку:
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // ReferenceError
let bar = 2;
  • letМетод объявления не допускает повторных объявлений, таких как повторные объявления, будет сообщено об ошибке, иvarПри объявлении переменной оператор, объявленный позже, переопределяет оператор, объявленный ранее:
// 报错
function func() {
  let a = 10;
  var a = 1;
}
// 报错
function func() {
  let a = 10;
  let a = 1;
}
  • Пока существует область действия блокаletкоманда, переменные, которые она объявляет, являются "связанными" (binding) эту область, уже не подверженную внешним воздействиям, эта особенность называется暂时性死区.
var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

7. Закрытие

Быть добавленным

8. Прототип и цепочка прототипов

Быть добавленным

9. Reflow & Repaint браузера

Ссылаться на:nuggets.capable/post/684490…

Браузер получаетhtmlа такжеcssПосле этого этапы рендеринга следующие:htmlСоздано путем рендерингаDOMДерево,cssСоздано путем рендерингаcssДерево рендеринга, они объединяются для созданияrender tree, браузер можетrender treeВыполнение экранного рисунка.

Если браузер получает новыйcss, что нужно сделать, когда страницу нужно обновить? это обратный потокreflowс перекраскойrepaint. Поскольку браузер сначала повторно отображает страницуreflowсделай это сноваrepaint, поэтому перекомпоновка обязательно вызовет перерисовку, а перерисовка не обязательно приведет к перекомпоновке.

Перерисовка: при изменении стиля текущего элемента (цвет фона, цвет шрифта и т. д.) нам нужно только повторно отобразить измененный элемент, и перерисовка мало влияет на производительность браузера. При перерисовке: изменить стиль внешнего вида контейнера и т. д., напримерbackground:blackЖдать. Измените внешний вид, не меняйте раскладку, не влияйте на другиеDOM.    Reflow: относится к процессу, с помощью которого браузер пересчитывает положение и геометрию элементов в документе, чтобы повторно отобразить часть или весь документ.

Поскольку обратный поток может привести кDOMРеструктуризация дерева, так что это большой убийца производительности, перекомпоновка элемента вызывает все его дочерние элементы иDOMПоследующие перекомпоновки непосредственно следующего за ним элемента-предка в . Опубликовано ниже вызовет браузерreflowИзменение:

  • первый рендер страницы
  • Изменился размер окна браузера
  • Изменение размера или положения элемента
  • Изменения содержимого элемента (количество текста или размер изображения и т. д.)
  • Изменение размера шрифта элемента
  • Добавить или удалить видимые элементы DOM
  • Активировать псевдоклассы CSS (например: :hover )
  • запрашивать определенные свойства или вызывать определенные методы

Оптимизация:

CSS

  • избегать использованияtableмакет.
  • как можно большеDOMКонец дерева измененийclass.
  • Избегайте установки нескольких слоев встроенных стилей.
  • Применение анимационных эффектов кpositionсобственностьabsoluteилиfixedна элементе.
  • избегать использованияCSSвыражения (например:calc()).

JavaScript

  • Избегайте частых манипуляций со стилями, лучше всего переписать их все сразуstyleили определите список стилей какclassи поменять все сразуclassАтрибуты.
  • Избегайте частых операцийDOM,СоздаватьdocumentFragment, на него распространяются всеDOMоперацию и, наконец, добавьте ее в документ.
  • Вы также можете сначала установить элементdisplay: none, и отображать его после завершения операции. Потому чтоdisplayсобственностьnoneвыполняется на элементахDOMОперации не вызывают перекомпоновки и перерисовки.
  • Избегайте частого чтения свойств, которые вызовут перекомпоновку/перерисовку, и если вам действительно нужно использовать их несколько раз, кэшируйте их в переменной.
  • Используйте абсолютное позиционирование для элементов со сложной анимацией, чтобы они не попадали в поток документа, иначе это вызовет частые перекомпоновки родительских и последующих элементов.

10. Глубокое копирование объектов JS

Общая идея состоит в том, чтобы решить ее рекурсивно и выполнить различную обработку для разных типов данных:

function deepCopy (obj) {
  let result = {}
  for (let key in obj) {
    if (obj[key] instanceof Object || obj[key] instanceof Array) {
      result[key] = deepCopy(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  return result
}

Это может только копировать объекты с массивами, объектами или другими базовыми типами данных внутри, если есть такие объекты, какRegExp,DateРезультатом такой сложной копии объекта является{}, не могут быть правильно скопированы, потому что для этих специальных объектов не предусмотрена отдельная обработка. Чтобы обратиться к копированию сложных объектов, вы можете обратиться кlodashМетод глубокого копирования среднего массива_.cloneDeep()В следующей статье представлен подробный анализ метода глубокого копирования массивов, который имеет определенное справочное значение:Джерри go.com/posts/dive-…

Кроме того, если структура данных копируемого объекта относительно проста и отсутствуют данные сложных объектов, то можно использовать самый простой способ:

let cloneResult = JSON.parse(JSON.stringify(targetObj))

11. Теряется точность работы JS

Ранее я перепечатывал статью, в которой есть более подробное описание причин и решений потери точности работы JavaScript:blog.CSDN.net/QQ_35271556…

Связанные с браузером

1. Процесс браузера от загрузки до рендеринга, например, процесс ввода URL-адреса для отображения страницы.

Процесс загрузки:

  • Браузер получает IP-адрес доменного имени в соответствии с разрешением DNS-сервера.
  • Отправьте HTTP-запрос на машину с этим IP-адресом
  • Сервер получает, обрабатывает и возвращает HTTP-запрос
  • Браузер получает возвращаемый контент

Процесс рендеринга:

  • Сгенерировать дерево DOM из структуры HTML
  • Создание CSSOM из CSS
  • Интегрируйте DOM и CSSOM для формирования RenderTree
  • Начать рендеринг и отображение в соответствии с RenderTree
  • встретить<script>, выполнит и заблокирует рендеринг

2. Механизм кэширования браузера

Справочная статья:сегмент fault.com/ah/119000001…

3. Оптимизация производительности

Справочная статья:blog.CSDN.net/that_sama/art…

Vue

1. Связь между компонентами

Официальная документация Vue содержит подробное описание метода связи между компонентами:cn.vuejs.org

родительский компонент в дочерний компонент

  • Самый распространенный способ — передать данные в теге подкомпонента и использовать их внутри подкомпонента.propsперенимать:
// 父组件
<template>
  <children name="boy"></children>
</template>
<script>
// 子组件:children
export default {
  props: {
    name: String
  }
}
</script>
  • также может использоваться в подкомпонентахthis.$parentДоступ к экземпляру родительского компонента, но в официальном документе есть такой абзац, что является хорошим объяснением$parentЗначение: использовать экономно$parentа также$children- Их основная цель - обходной путь для доступа к компонентам. больше рекомендуетсяpropsа такжеeventsРеализовать связь между родительскими и дочерними компонентами.

дочерний компонент к родительскому компоненту

  • Обычно используется в подкомпонентахthis.$emit('eventName', 'data'), а затем прослушайте тег дочернего компонента в родительском компонентеeventNameсобытие и получить переданное значение в параметре.
// 子组件
export default {
  mounted () {
    this.$emit('mounted', 'Children is mounted.')
  }
}
<template>
  <children @mounted="mountedHandle"></children>
</template>
<script>
// 父组件
export default {
  methods: {
    mountedHandle (data) {
      console.log(data) // Children is mounted.
    }
  }
}
</script>
  • а также$parentНапример, в родительском компоненте можно получить доступ кthis.$childrenдля доступа ко всем экземплярам дочерних компонентов компонента.

Передача данных между неродительскими и дочерними компонентами

  • Для компонентов, не являющихся родительскими и дочерними, со сложной иерархией компонентов вы можете использоватьVuexПередача данных между компонентами:vuex.vuejs.org/zh/

  • существуетVue 1.0обычно используется вevent busглобальная передача данных с помощьюVue 2.0был удален в официальной документации, как указано в официальной документации:$dispatchа также$broadcastустарело. Пожалуйста, используйте более лаконичную и четкую межкомпонентную коммуникацию и лучшие схемы управления состоянием, такие как:Vuex.

2, двусторонний принцип привязки

blog.seosiwei.com/detail/35 blog.seosiwei.com/detail/36 blog.seosiwei.com/detail/37

3, навигационный крючок маршрутизации

router.v ue js.org/this-capable/advpress…

Информация об авторе

Другие статьи автора