Предварительное собеседование на работу в 2021 году

опрос
Предварительное собеседование на работу в 2021 году

связанные с JS

JS прототип и цепочка прототипов

function Person() {}
Person.prototype.name = 'Zaxlct';
Person.prototype.sayName = function() {
  alert(this.name);
}
var person1 = new Person();
//JS 在创建对象的时候,都有一个__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。
// 对象 person1 有一个 __proto__属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype
console.log(person1.__proto__ == Person.prototype) //true
//所有函数对象的__proto__都指向Function.prototype
String.__proto__ === Function.prototype  // true
String.constructor == Function //true

prototype.jpg

Несколько способов наследования JS

Детальное объяснение

  1. прототипное наследование

    function Parent () {
      this.name = 'Parent'
      this.sex = 'boy'
    }
    function Child () {
      this.name = 'child'
    }
    // 将子类的原型对象指向父类的实例
    Child.prototype = new Parent()
    //优:继承了父类的模板,又继承了父类的原型对象
    //缺:1.无法实现多继承(因为已经指定了原型对象了)
    //   2.创建子类时,无法向父类构造函数传参数
    
  2. Наследование конструктора

    Использовать внутри конструктора подклассаcall或applyЧтобы вызвать конструктор родительского класса, скопируйте свойства экземпляра родительского класса в дочерний класс.

    function Parent (name) {
      this.name = name
    }
    function Child () {
      //用.call 来改变 Parent 构造函数内的指向
      Parent.call(this, 'child')
    }
    //优:解决了原型链继承中子类实例共享父类引用对象的问题,实现多继承,创建子类实例时,可以向父类传递参数
    //缺:构造继承只能继承父类的实例属性和方法,不能继承父类原型的属性和方法
    
  3. наследование композиции

    Композиционное наследование представляет собой комбинацию наследования цепочки прототипов и наследования конструктора.

    • использоватьНаследование цепочки прототиповЧтобы подклассы могли наследовать свойства и методы в прототипе родительского класса
    • использоватьКонструктивное наследованиеЧтобы гарантировать, что подкласс может наследовать свойства экземпляра и методы суперкласса
  4. Наследование паразитарного состава

  5. наследование классов

    существуетclassНаследование в основном зависит от двух вещей:

    • extends

    • super

      class Parent {
        constructor (name) {
          this.name = name
        }
        getName () {
          console.log(this.name)
        }
      }
      class Child extends Parent {
        constructor (name) {
          super(name)
          this.sex = 'boy'
        }
      }
      

Цикл событий Цикл событий

Синхронные и асинхронные, макрозадачи и микрозадачи — это описания двух разных измерений функций.

Синхронная задача относится к задаче, поставленной в очередь для выполнения в основном потоке, и следующая задача может быть выполнена только после завершения выполнения предыдущей задачи;асинхронная задачаЭто означает, что вместо входа в основной поток входочередь задач(task queue) задача, только после выполнения задачи основного потока очередь задач начинает уведомлять основной поток и запрашивать выполнение задачи, задача войдет в основной поток для выполнения.

Когда макрозадача выполняется, она проверяет, существует ли очередь микрозадач. Если это так, сначала выполните все задачи в очереди микрозадач; В противном случае верхняя задача в очереди задач макроса будет прочитана в стеке среды выполнения; В процессе выполнения макрозадач при встрече с микрозадачами они по очереди добавляются в очередь микрозадач. После того, как стек опустеет, снова прочитайте задачи в очереди микрозадач и так далее.

Синхронный (Promise) > Асинхронный (Микрозадача (process.nextTick, Promises.then, Promise.catch, разрешить, отклонить, MutationObserver) > Макрозадача (setTimeout, setInterval, setImmediate))

блоки ожиданияКод позади выполняется, поэтомуВыйти из асинхронной функцииВыполнить следующую микрозадачу

Обещания иAsync/Awaitразница

async/await реализован на основе Promise и больше похож на синхронный код,

  • Нет необходимости писать анонимные функции для обработки значения разрешения Promise.
  • обработка ошибок: Async/Await позволяет try/catch обрабатывать как синхронные, так и асинхронные ошибки.
  • Условные операторы так же лаконичны, как и обработка ошибок.
  • Обработка промежуточных значений (возвращаемое значение первого метода, используемое в качестве параметра второго метода) для решения проблем вложенности
  • Легко отлаживать
   const makeRequest = () => {
        try {
            getJSON().then(result => {
                // JSON.parse可能会出错
                const data = JSON.parse(result)
                console.log(data)
            })
            // 取消注释,处理异步代码的错误
            // .catch((err) => {
            //   console.log(err)
            // })
        } catch (err) {
            console.log(err)
        }
    }

использоватьaync/awaitЕсли это так, поймать может справитьсяJSON.parseошибка:

    const makeRequest = async () => {
        try {
            // this parse may fail
            const data = JSON.parse(await getJSON())
            console.log(data)
        } catch (err) {
            console.log(err)
        }
    }

Как промисы реализуют связанные вызовы и возвращают разные состояния

Чтобы реализовать цепочку: используйте.then()или.catch()Затем метод вернетpromiseобъект, вы можете продолжать использовать.then()Вызов метода, параметр, полученный при повторном вызове, является предыдущимthenметодreturnСодержание

  1. Три состояния обещанияfulfilled(удалось)/pengding(в ходе выполнения)/rejected(отклоненный)

  2. Статус можно изменить только с помощью "Ожидание --> Выполнено" или "Ожидание --> Отклонено", и после изменения его нельзя изменить дважды;

  3. Используется в обещанияхresolveа такжеrejectДве функции для изменения состояния;

  4. Что метод then делает внутренне, так это суждение о состоянии:

  • Если статус успешен, вызовите функцию обратного вызова успеха
  • Если статус не выполнен, вызовите функцию обратного вызова ошибки

каррирование функций

柯里化(Currying)Он преобразует исходную функцию, которая принимает несколько параметров, в функцию, которая принимает один параметр (первый параметр исходной функции) и возвращает новую функцию, которая принимает остальные параметры и возвращает тот же результат, что и исходная функция.

  1. мультиплексирование пар параметров
  2. Улучшить удобство использования
  3. отложенное исполнение

Вызовите его, передав функции только подмножество аргументов, и пусть она вернет функцию для обработки остальных аргументов. Каррированные функции могут задерживать получение параметров, то есть, например, функции нужно получить два параметра, и она должна получить два параметра при выполнении, иначе она не может быть выполнена. Но каррированная функция может сначала получить параметр

// 普通的add函数
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

Глубокий клон объекта JS

Рекурсивно перемещайтесь по объектам и решайте проблемы с круговыми ссылками

Чтобы решить проблему циклической ссылки, нам нужен контейнер хранения для хранения соответствующей связи между текущим объектом и копируемым объектом (подходит для хранения в структуре данных ключ-значение, то есть карта).При копировании текущего объекта, мы сначала проверяем, является ли контейнер хранения Текущий объект скопирован.Если он был скопирован, то возвращаем его напрямую.Если нет, продолжаем копирование.

function deepClone(target) {
    const map = new Map()
    function clone (target) {
        if (isObject(target)) {
            let cloneTarget = isArray(target) ? [] : {};
            if (map.get(target)) {
                return map.get(target)
            }
            map.set(target,cloneTarget)
            for (const key in target) {
                cloneTarget[key] = clone(target[key]);
            }
            return cloneTarget;
        } else {
            return target;
        }
    }
    return clone(target)
};

Модульный JS

nodeJSМодули внутри основаны наcommonJSСтандартная реализация, принцип чтения и записи файлов, экспорт файлов для использованияexports,module.exports, импортировать файлы сrequire. Каждый файл представляет собой модуль; код в каждом файле по умолчанию будет записан в функции закрытия.AMDСпецификация заключается в асинхронной загрузке модулей, что позволяет указывать функции обратного вызова,AMDдаRequireJSНормализованный вывод определения модуля в процессе продвижения.

AMDуважаемыйЗависит от фронта, CMDуважаемыйзависит от ближайшего. Для зависимых модулей AMD выполняется заранее, CMD выполняется с задержкой.

существуетES6, мы можем использоватьimportмодуль импорта ключевых слов черезexprotМодуль экспорта ключевых слов, но поскольку ES6 в настоящее время не может быть выполнен в браузере, мы можем передать толькоbabelне будет поддерживатьсяimportКомпилируется в широко поддерживаемый в настоящее времяrequire.

Различия между модульностью CommonJs и ES6:

  1. Модули CommonJS выводят копию значения, модули ES6 выводят ссылку на значение.
  2. Модули CommonJS загружаются во время выполнения, а модули ES6 представляют собой скомпилированные интерфейсы.

Модульность интерфейса: CommonJS, AMD, CMD, ES6.

Разница между import и require import

импортировать стандартный модуль ES6, требуется метод введения спецификации AMD;

import вызывается во время компиляции, поэтому он должен быть помещен в начало файла; это процесс деструктурирования require — это вызов среды выполнения, поэтому теоретически require может использоваться в любом месте кода; это процесс присваивания. На самом деле результатом require является объект, число, строка, функция и т. д., а затем присваивать результат require переменной

Асинхронная загрузка JS

  1. Самонастраивающаяся анонимная функция динамически создает теги сценария для загрузки js
(function(){
    var scriptEle = document.createElement("script");
    scriptEle.type = "text/javasctipt";
    scriptEle.async = true;
    scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
    var x = document.getElementsByTagName("head")[0];
    x.insertBefore(scriptEle, x.firstChild);		
 })();
  1. асинхронное свойство
// async属性规定一旦加载脚本可用,则会异步执行
<script type="text/javascript" src="xxx.js" async="async"></script>
  1. атрибут отсрочки
// defer属性规定是否对脚本执行进行延迟,直到页面加载为止
<script type="text/javascript" src="xxx.js" defer="defer"></script>

Набор, Карта, WeakSet, WeakMap

Setобъекты могут хранитьсялюбой типДанные. значение уникально,нет повторенияценность .

Mapсохранение объектапара ключ-значение, любое значение может быть его ключом или значением.

WeakSetструктура иSetТочно так же это также набор уникальных значений.WeakMapобъект представляет собой наборпара ключ-значениеколлекция

разные:WeakSetчлены могут быть толькообъект, а не любой другой тип значения.WeakSet не проходим.

WeakMapпринимать толькообъект как имя ключа(nullкроме), другие типы значений не принимаются в качестве имен ключей.

WeakMapобъект, на который указывает имя ключа,не в счетМеханизм сбора мусора.

звоните, обращайтесь

call( this,a,b,c )После первого параметра все последующие параметры являются значениями, передаваемыми в функцию.

apply( this,[a,b,c] )Параметров всего два, первый — объект, а второй — массив, являющийся параметром функции.

Что у них общего: оба могут использоваться для вызова метода вместо другого объекта, изменяя контекст объекта функции с начального контекста на новый объект, указанный thisObj.

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

addEventListenerЧто делает третий параметр?

Object.prototype.toString.call()Оценка типа объекта

// new Set是实现数组去重,
// Array.from()把去重之后转换成数组
let arr2 = Array.from(new Set(arr));

Лексическая область видимости и цепочка областей видимости

Область действия указывает, как найти переменную, то есть определить права доступа исполняемого в данный момент кода к переменной.

ES5 имеет только глобальную область действия и область действия функции, ES6 добавляет область действия на уровне блоков.

Временная мертвая зона: внутри блока кода используйтеletа такжеconstПеременная недоступна до тех пор, пока команда не объявит ее, что синтаксически называется временной мертвой зоной.

JavaScript использует лексическую область видимости, также известную как статическая область видимости.

Объем функции определяется при определении функции.

При поиске переменной сначала будет выполняться поиск в переменном объекте текущего контекста, а если не будет найдено, то поиск будет производиться в родительском (родительском на лексическом уровне).контекст выполненияИщется переменный объект, и всегда находится переменный объект глобального контекста, то есть глобальный объект. Таким образом, связанный список, состоящий из переменных объектов нескольких контекстов выполнения, называетсяцепочка прицелов.

Новое ключевое слово делает 4 вещи:

    function _new(constructor, ...arg) {
	  // 创建一个空对象
      var obj = {};
      // 空对象的`__proto__`指向构造函数的`prototype`, 为这个新对象添加属性 
      obj.__proto__ = constructor.prototype; 
      // 构造函数的作用域赋给新对象
      var res = constructor.apply(obj, arg); 
      // 返回新对象.如果没有显式return语句,则返回this
      return Object.prototype.toString.call(res) === '[object Object]' ? res : obj; 
    }

Некоторые ситуации, когда стрелочные функции не следует использовать:

  • Когда вы хотите, чтобы функция была поднята (функции стрелок анонимны)
  • для использования в функцииthis/arguments, поскольку сама стрелочная функция не имеетthis/arguments, поэтому они зависят от внешнего контекста
  • Используйте именованные функции (стрелочные функции анонимны)
  • При использовании функции в качестве конструктора (стрелочная функциянет конструктора)
  • Когда вы хотите использовать объект литерала как функциюАтрибутыПри добавлении и использовании объектов в нем, потому что у нас нет доступа кthisТо есть сам объект.

Четыре способа оценить массив

  1. Array.isArray()судить

  2. instanceofОпределение: Проверяет, появляется ли свойство прототипа конструктора в цепочке прототипов объекта, возвращая логическое значение.

let a = []; a instanceof Array; //true

  1. constructorСуждение: конструктор атрибута конструктора экземпляра указывает на конструктор

let a = [1,3,4]; a.constructor === Array;//true

  1. Object.prototype.toString.call()судить

let a = [1,2,3]; Object.prototype.toString.call(a) === '[object Array]';//true

В чем преимущества ТС

  1. Статическая типизация. Статическая типизация — это функция, обнаруживающая ошибки при написании скриптов разработчиками.

  2. Крупные проекты разработки: используйте инструменты TypeScript, чтобы сделать изменения рефакторинга простыми и быстрыми.

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

  4. Повышение производительности: такие факторы, как чистый код ECMAScript 6, автозаполнение и динамическая типизация, помогают повысить производительность разработчиков.

Разница между интерфейсом и типом

  • interfaceМогут быть определены только типы объектов.typeОбъявление может объявлять любой тип.

  • interfaceВозможность объявить слияние, два одинаковых интерфейса будут объединены.TypeОбъявление слияния вызовет ошибку

  • typeможет ввести вывод

  • interfaceнаследуемый иtypeНе наследует

Фрейм VUE | Реагировать

Новые функции Vue3.0

Двусторонняя привязка данных Прокси

Прокси можно понимать как установку «перехвата» перед объектом, когда к объекту обращаются, он должен пройти через этот уровень перехвата. Это означает, что вы можете выполнять различные операции в этом слое перехвата. Например, вы можете обработать исходный объект на этом уровне перехвата и вернуть нужную структуру данных.

Изначально предоставлено ES6ProxyКонструктор, объяснение на MDN: прокси-объекты используются для определения настраиваемого поведения для основных операций (таких как поиск свойств, присвоение, перечисление, вызовы функций и т. д.).

const p = new Proxy(target, handler);
//target: 所要拦截的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
//handler:一个对象,定义要拦截的行为

const p = new Proxy({}, {
    get(target, propKey) {
        return '哈哈,你被我拦截了';
    }
});

console.log(p.name);

Новые свойства не требуют повторного добавления адаптивной обработки, потому чтоProxyЭто операция над объектом, пока вы получаете доступ к объекту, вы перейдете кProxy в логике.

Vue3 Composition API

Vue3.xвыпускатьComposition API.setupЭто точка входа для использования Composition API внутри компонента.setupвремя выполненияbeforeCreateвыполнял раньше.

реактивный, ref и toRefs, isRef

Vue3.x может использовать reactive и ref для определения данных.

  // props 传入组件对属性
  // context 一个上下文对象,包含了一些有用的属性:attrs,parent,refs
  setup(props, context) {
    // ref 定义数据
    const year = ref(0);
    // reactive 处理对象的双向绑定
    const user = reactive({ nickname: "xiaofan", age: 26, gender: "女" });
    setInterval(() => {
      year.value++;
      user.age++;
    }, 1000);
    return {
      year,
      // 使用toRefs,结构解构
      ...toRefs(user),
    };
  },
  // 提供isRef,用于检查一个对象是否是ref对象

Функция слушателя watchEffect

  • watchEffect не нужно вручную передавать зависимости
  • watchEffect будет выполняться один раз для автоматического сбора зависимостей
  • watchEffect не может получить значение до изменения, только значение после изменения

вычисленный может быть передан в get и set

Используется для определения изменяемых вычисляемых свойств.

const plusOne = computed({
 get: () => count.value + 1,
 set: val => { count.value = val - 1 }
});

Использование TypeScript и JSX

setupТеперь поддерживает возврат функции рендеринга, которая возвращаетJSX,JSXможно объявить напрямую, используяsetupРеактивное состояние прицела:

export default {
 setup() {
 const count = ref(0);
 return () => (<div>{count.value}</div>);
 },
};

Vue против React?

Тот же пункт:

  1. Оба имеют виртуальный DOM (виртуальный DOM — это объект JavaScript, который отображает реальный DOM)
  2. Оба предоставляют адаптивные и компонентные компоненты представления.

разница: Vue этоMVVMframework, двусторонняя привязка данных, когдаViewModelправильноModelКогда обновление сделано, обновите доView.

React — это библиотека для одностороннего потока данных, представлений, управляемых состоянием.State --> View --> New State --> New View ui = render (data)

Шаблоны отображаются по-разному. React отображает шаблоны через JSX, а Vue — через расширенный HTML.

Формы компонентов разные, а файл Vue сочетает в себе HTML, JS и CSS. react предоставляет компоненты класса и группы функций

Vue инкапсулирует некоторые v-if, v-for, а React реализует все сам, с более высокой степенью свободы.

Процесс инициализации Vue, принцип двусторонней привязки данных

Vue.js использует перехват данных в сочетании с моделью издатель-подписчик.Object.defineProperty()захватить каждое имуществоsetter,getter,dep.addSubдля сбора подписных зависимостей,watcherОтслеживайте изменения данных, публикуйте сообщения подписчикам при изменении данных и запускайте соответствующие обратные вызовы мониторинга.

слушательObserver, используется для захвата и мониторинга всех свойств и уведомления подписчиков об изменениях. подписчикWatcher, вы можете получить уведомление об изменении атрибута и выполнить соответствующую функцию, чтобы вызвать соответствующее обновление для обновления представления.img

v-modelДирективы, упрощающие реализацию двусторонней привязки между входными данными формы и состоянием приложения.

computed:Поддерживает кэширование. Перерасчет будет выполняться только при изменении результата зависимых данных. Асинхронные операции не поддерживаются. Если атрибут зависит от других атрибутов, он равен «многие к одному». Как правило, используется вычисляемый.

watch:Когда данные изменяются, соответствующая операция запускается напрямую, и поддерживается асинхронность.Данные мониторинга должны бытьdataобъявленный или переданный из родительского компонентаprops中Данные, когда данные изменяются, вызывают другие операции, функция имеет два параметра

Принцип реализации Vue-маршрутизатора

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

hash模式: изменяя значение привязки в соответствии с разными значениями, отображать разные данные в указанной позиции DOM. каждое изменение#В более поздней части запись будет добавлена ​​в историю посещений браузера, для возврата на предыдущую позицию используйте кнопку «Назад».history模式:использоватьwindow.history.pushStateAPI для выполнения переходов по URL без перезагрузки страницы.

Принцип реализации Vuex:

Vue.use(vuex)Вызовет метод установки vuex

существуетbeforeCreateмиксин перед хукомvuexInitметод,vuexInitметод реализованstoreинъекцияvue组件实例, и зарегистрированvuex storeэталонное свойство$store.

VuexизstateСтатус отвечаетvueизdataотзывчивый, будетstateХранится в данных компонента экземпляра vue;

VuexизgettersЭто с помощью вычисляемых свойств Vue.computedМониторинг данных в режиме реального времени.

Принцип и механизм работы nextTick?

Анализ исходного кода nextTick

Vue также вызывает nextTick для внутреннего асинхронного управления очередью для обновления DOM. Как только будут обнаружены изменения данных, Vue откроет очередь и буферизует все изменения данных, которые происходят в том же цикле событий. Если один и тот же наблюдатель запускается несколько раз, он будет помещен в очередь только один раз.

DOM будет, по крайней мере, равномерно обновлять представление после того, как все изменения данных в текущем цикле событий будут завершены. и когда мы самиПри вызове nextTick, это сразу после обновления микрозадачи DOM (очереди микрозадач)Добавлена ​​собственная функция обратного вызова,

Это гарантирует, что наш код будет выполнен после обновления DOM, а также позволит избежать проблем с множественным выполнением, которые могут возникнуть у setTimeout. Убедитесь, что микрозадачи в очереди выполняются до одного цикла событий.

Vue реализует компонент более высокого порядка

Компонент более высокого порядка — это функция, которая принимает компонент в качестве параметра и возвращает новый компонент.Динамически добавлять некоторые дополнительные свойства или поведение к объекту во время выполнения программы, не изменяя сам объект..

// 高阶组件(HOC)接收到的 props 应该透传给被包装组件即直接将原组件prop传给包装组件
// 高阶组件完全可以添加、删除、修改 props
export default function Console(BaseComponent) {
  return {
    props: BaseComponent.props,
    mounted() {
      console.log("高阶组件");
    },
    render(h) {
      console.log(this);
      // 将 this.$slots 格式化为数组,因为 h 函数第三个参数是子节点,是一个数组
      const slots = Object.keys(this.$slots)
        .reduce((arr, key) => arr.concat(this.$slots[key]), [])
        .map((vnode) => {
          vnode.context = this._self; // 绑定到高阶组件上,vm:解决具名插槽被作为默认插槽进行渲染
          return vnode;
        });
 
      // 透传props、透传事件、透传slots
      return h(
        BaseComponent,
        {
          on: this.$listeners,
          attrs: this.$attrs, // attrs 指的是那些没有被声明为 props 的属性
          props: this.$props,
        },
        slots
      );
    },
  };
}

Vue.component (), vue.use (), это. $ Xxx ()

Метод Vue.component() регистрирует глобальные компоненты.

  • Первый параметр — это имя пользовательского элемента, которое представляет собой имя метки этого компонента, которое будет использоваться в других компонентах в будущем.
  • Второй параметр — это компонент Vue, который будет зарегистрирован.
import Vue from 'vue';
// 引入loading组件 
import Loading from './loading.vue';
// 将loading注册为全局组件,在别的组件中通过<loading>标签使用Loading组件
Vue.component('loading', Loading);

Vue.use регистрирует плагины, для этого требуется один параметр. Этот параметр должен иметь метод установки. Метод установки параметра вызывается внутри функции Vue.use.

  • Если плагин не был зарегистрирован, то после успешной регистрации к плагину будет добавлено установленное значение атрибута true. Установленное свойство плагина обнаруживается внутри метода Vue.use, чтобы избежать повторной регистрации плагина.
  • Метод установки плагина получит два параметра, первый параметр — Vue, а второй параметр — параметры элемента конфигурации.
  • Вы можете добавить глобальные методы или свойства внутри метода установки.
import Vue from 'vue';

// 这个插件必须具有install方法
const plugin = {
  install (Vue, options) {
    // 添加全局方法或者属性
    Vue.myGlobMethod = function () {};
    // 添加全局指令
    Vue.directive();
    // 添加混入
    Vue.mixin();
    // 添加实例方法
    Vue.prototype.$xxx = function () {};
    // 注册全局组件
    Vue.component()
  }
}

// Vue.use内部会调用plugin的install方法
Vue.use(plugin);

Смонтируйте метод Hello на прототипе Vue.

import Vue from 'vue';
import Hello from './hello.js';
Vue.prototype.$hello = Hello;

Вы можете использовать this.$hello('hello world') в компоненте vue.

Родительский компонент Vue передает данные реквизита, а дочерний компонент изменяет параметры

  • Когда компонент родитель-потомок передает значения, параметры, массивы и объекты, переданные родительским компонентом, могут быть изменены напрямую после того, как дочерний компонент примет их, и соответствующее значение родительского компонента также будет изменено. В консоли выдается предупреждение.
  • Если переданное значение является строкой, его изменение напрямую приведет к ошибке.

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

Если дочерний компонент хочет изменить данные в реквизите:

  1. Определите локальную переменную и присвойте ей значение prop
  2. Определите вычисляемое свойство, которое обрабатывает значение реквизита и возвращает

Порядок выполнения жизненного цикла родительско-дочернего компонента Vue

Загрузить процесс рендеринга

родитель перед созданием -> родитель создан -> родитель перед монтированием-> дочерний перед созданием -> дочерний создан -> дочерний перед монтированием -> смонтирован дочерний элемент -> смонтирован родительский

Процесс обновления подкомпонента

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

Процесс обновления родительского компонента

родитель перед обновлением -> родитель обновлен

процесс разрушения

родитель перед уничтожением -> дочерний перед уничтожением -> дочерний уничтожен -> родитель уничтожен

Пользовательская директива Vue

Пользовательские директивы предоставляют несколько функций ловушек:bind: вызывается, когда директива впервые привязывается к элементуinserted: вызывается, когда связанный элемент вставляется в родительский узелupdate: вызывается при обновлении VNode компонента.

использоватьslotзатем может отображаться внутри дочернего компонентавставлена ​​новая вкладка

веб-пакет и инженерия

Жизненный цикл webpack и хуки

compiler(весь жизненный цикл [kəmpaɪlər]) крючокWebpack.doc — China.org/API/compile… compilation(скомпилировать [ˌkɑːmpɪˈleɪʃn]) крючок

compiler Объект содержит всю информацию о конфигурации для среды Webpack. Этот объект создается один раз при запуске webpack и настраивает все рабочие параметры, включая опции, загрузчики и плагины. При применении плагина в среде веб-пакета плагин получит ссылку на этот объект компилятора. Вы можете использовать его для доступа к основной среде веб-пакета.

compilationОбъект содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д. При запуске промежуточного программного обеспечения среды разработки webpack всякий раз, когда обнаруживается изменение файла, создается новая компиляция, в результате чего создается новый набор скомпилированных ресурсов. Объект компиляции также предоставляет ряд критических обратных вызовов времени, которые подключаемый модуль может выбрать для использования при выполнении пользовательской обработки.

compilerпредставляет весьwebpackот запуска до выключения生命周期,а такжеcompilationпросто представляет новый编译过程

процесс компиляции вебпака

Процесс компиляции Webpack представляет собой последовательный процесс, и следующие процессы выполняются последовательно от начала до конца:

  1. Параметры инициализации: чтение и объединение параметров из файлов конфигурации и операторов оболочки для получения окончательных параметров;
  2. Начать компиляцию: инициализировать с параметрами, полученными на предыдущем шагеCompilerобъекта, загружает все настроенные плагины, выполняетrun Метод начинает выполнять компиляцию;
  3. Определяем запись: по конфигурацииentryНайти все входные файлы;
  4. Модуль компиляции: Начиная с файла ввода, вызовите все настроенныеLoaderПереведите модуль, найдите модули, от которых зависит модуль, и повторите этот шаг, пока все файлы, от которых зависит запись, не будут обработаны на этом шаге;
  5. Полная компиляция модуля: использовать после шага 4LoaderПосле перевода всех модулей получается финальное содержимое каждого модуля и зависимости между ними;
  6. Выходные ресурсы: в соответствии с зависимостями между записью и модулем соберите их в несколько модулей один за другим. Chunk, затем поставьте каждыйChunkПреобразуйте его в отдельный файл и добавьте в список вывода.Этот шаг — последний шанс изменить содержимое вывода;
  7. Вывод завершен: после определения содержимого вывода определите путь вывода и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему.

Оптимизировать процесс упаковки и компиляции веб-пакета проекта

1. Создайте РБИ: В процессе сборки каждый Loaderа такжеPluginВремя выполнения тратится на загрузчик, который компилирует JS и CSS, и на плагин, который выполняет операции сжатия этих двух типов кода. Инструмент: speed-measure-webpack-plugin

2. Кэш: Большинство загрузчиков предоставляют cacheэлемент конфигурации.cache-loader, записать результат компиляции загрузчика в кеш жесткого диска

3. Многоядерная компиляция,happypackПроект подключен к многоядерной компиляции, под которой понимаетсяhappypackЗаполнить все темы компиляцией

4. Отстраниться,webpack-dll-pluginИзвлеките эти статические зависимости из каждой логики сборки и отдельно упакуйте статические зависимости.ExternalsУдалите из логики сборки статические ресурсы, которые не нужно упаковывать, используйте CDN 引用

5.tree-shaking, хотя он и зависит от модуля, на самом деле он использует только некоторые из его функций. пройти черезtree-shaking, чтобы удалить неиспользуемые модули для достижения цели удаления бесполезного кода.

Оптимизация загрузки выше сгиба

Отложенная загрузка маршрута: использовать вместоimportСсылка динамически импортируется в виде функции, и соответствующие файлы маршрутизации могут быть упакованы отдельно, а компонент маршрутизации будет загружен только при разборе данного маршрута;

element-uiнагрузка по требованию: относится к фактически используемому компоненту;

Компоненты упакованы многократно:CommonsChunkPluginНастройте распаковку, извлеките пакеты, которые использовались дважды или более, и поместите их в общедоступный файл зависимостей.Также на домашней странице есть повторно используемые компоненты, и этот общедоступный файл зависимостей также будет загружен;

gzip: После распаковки использовать сноваgzipСделайте некоторое сжатие и отключите исходную карту.

UglifyJsPlugin:Рабочая среда, сжатие запутанного кода, удаление кода консоли

Развертывание статических ресурсов CDN: при выполнении статического запроса к nginx адрес полученного статического ресурса будет перенаправлен в сеть распространения контента CDN.

Мобильный первый экранможно использовать загрузкуСкелетонный экран,настроитьloading, домашняя страница делает это самарендеринг на стороне сервера.

Как оптимизировать производительность внешнего интерфейса (21 вид оптимизации таргетинга +7 видов)

механизм горячего обновления webpack

Краткое описание процесса горячего обновления:

  • начать местныйserver, чтобы браузер мог запросить локальныйстатические ресурсы

  • После первого открытия страницы сервер и клиент устанавливают канал связи через веб-сокет и возвращают следующий хеш во внешний интерфейс.

  • Клиент получает хэш, и этот хэш будет использоваться в качестве хэша для следующего запроса к серверу hot-update.js и hot-update.json

  • После изменения кода страницы Webpack начинает компиляцию после отслеживания модификации файла и отправляет клиенту сообщение о сборке.

  • Клиент получает хэш, и после успеха клиент создает ссылку на скрипт hot-update.js, а затем вставляет основной документ.

  • После успешной вставки hot-update.js выполните методы createRecord и reload hotAPI, получите метод рендеринга компонента Vue, выполните повторный рендеринг компонента, а затем реализуйте обновление пользовательского интерфейса без обновления.

Знакомство с загрузчиком и плагином webpack, разница между css-loader и style-loader

loaderЭто конвертер, который компилирует файл A в файл B,

plugin, это экстендер, который работает с файлами.В течение всего процесса упаковки webpack после завершения загрузчика он не работает напрямую с файлами, а будет следить за определенными узлами в процессе упаковки webpack (run, build-module, program )

BabelОн может преобразовывать код ES6/ES7 в код, который может поддерживать указанный браузер.

css-loaderРоль заключается в перекодировании файла cssstyle-loader: использовать внутренние стили css-loader для вставки в нашу HTML-страницу

использовать сначалаcss-loader перекодировать перед использованиемstyle-loaderвставить в файл

Как написать плагин для веб-пакета?

сегмент fault.com/ah/119000003…

Состав плагина webpack:

  • Именованная функция JS или класс (вы можете себе представить, что мы обычно используем плагины в качествеnew XXXPlugin()Путь)
  • Определите метод применения для (прототипа) класса/функции плагина.
  • Передайте компилятор в функцию применения и вставьте указанный хук события, и получите объект компиляции в обратном вызове хука
  • Обработка данных экземпляра, специфичных для веб-пакета, посредством компиляции
  • Если плагин асинхронный, вызовите обратный вызов, предоставленный веб-пакетом, после того, как будет написана логика плагина.

Почему Vite запускается так быстро

Webpack будет先打包, а затем запустите сервер разработки и отдайте результат упаковки непосредственно при запросе сервера.

в то время как Вите直接启动Сервер разработки, какой модуль запрашивается, а затем модуль обрабатывается实时编译.

Vite рассматривает файлы модулей в среде разработки как файлы, которые должны выполняться браузером, а не как Webpack.打包合并.

Поскольку Vite запускается черезesbuildспособEsModelВведен в браузер изначально и обновляется по мере необходимости. это значит不需要分析模块的依赖,不需要编译. Так что запуск очень быстрый. Когда браузер запрашивает модуль, содержимое модуля компилируется по мере необходимости.

как сделаны ваши леса

использоватьdownload-git-repoСкачать демо код складаcommander:полныйnode.jsРешение командной строки. утверждениеprogram,использовать.option()метод определения опцийInquirer.js: набор пользовательских интерфейсов командной строки.

Интерфейсный мониторинг

Фронтенд-мониторинг обычно включает в себямониторинг поведения(PV/UV, статистика интерфейса скрытых точек),мониторинг исключений,мониторинг производительности.

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

Мониторинг ошибок

Методы предупреждения об ошибках, специфичные для VueVue.config.errorHandler, (Vue предоставляет функции, которые могут фиксировать только жизненный цикл страницы, например создание, подключение)

Vue.config.errorHandler = function (err) {
console.error(‘Vue.error’,err.stack)
// 逻辑处理
};

Рамка:betterjs,fundebug(потери) Сценарий, который перехватывает ошибку, должен быть размещен первым, чтобы обеспечить возможность сбора информации об ошибке. метод:

  1. window.onerror()Когда возникает ошибка времени выполнения js, onerror может принимать несколько параметров (сообщение, источник, линейное имя, столбец, ошибка).
  2. window.addEventListener('error'), function(e) {}, trueОн будет запущен до window.onerror и не может предотвратить выполнение обработчика событий по умолчанию, но может глобально перехватывать ошибку исключений загрузки ресурсов.

Фронтенд-фиксация ошибок JS --sourceMap

Как отслеживать сбои веб-страницы? ** В чем разница между сбоем и зависанием? **Отслеживание ошибок

  1. Service Worker имеет свой собственный независимый рабочий поток, который отделен от веб-страницы.В случае сбоя веб-страницы Service Worker не будет аварийно завершать работу при нормальных обстоятельствах;

  2. Жизненный цикл сервисного работника обычно длиннее, чем у веб-страницы, и его можно использовать для отслеживания состояния веб-страницы;

    Катон: Загрузка, рендеринг столкнулся с блокировкой

Мониторинг производительности и оптимизация производительности

Представление:

  • FP(первый розыгрыш)
  • FCP(Первая содержательная краска)
  • LCP(Самая большая содержательная краска)
  • FPS(кадров передается в секунду)
  • TTI(Время интерактивности страницы Время до интерактивности)
  • HTTPвремя ответа запроса
  • DNSвремя разбора
  • TCPвремя соединения

Сбор данных о производительности должен использоватьwindow.performance API, JS-библиотекаweb-vitals:import {getLCP} from 'web-vitals';

    // 重定向耗时
    redirect: timing.redirectEnd - timing.redirectStart,
    // DOM 渲染耗时
    dom: timing.domComplete - timing.domLoading,
    // 页面加载耗时
    load: timing.loadEventEnd - timing.navigationStart,
    // 页面卸载耗时
    unload: timing.unloadEventEnd - timing.unloadEventStart,
    // 请求耗时
    request: timing.responseEnd - timing.requestStart,
    // 获取性能信息时当前时间
    time: new Date().getTime(),
    // DNS查询耗时
    domainLookupEnd - domainLookupStart
	// TCP链接耗时
    connectEnd - connectStart
	// request请求耗时
    responseEnd - responseStart
	// 解析dom树耗时
    domComplete - domInteractive
	// 白屏时间
    domloadng - fetchStart
	// onload时间
    loadEventEnd - fetchStart

Общие средства оптимизации производительности: технология кэширования, технология предзагрузки, схема рендеринга.

  1. тайник: в основном включает cdn, кеш браузера, локальный кеш и автономный пакет приложения.

  2. Предварительная загрузка: Предварительная выборка ресурсов (prefetch) — еще один метод оптимизации производительности. Предварительная выборка сообщает браузеру, какие ресурсы пользователь может использовать в будущем.

  • prefetch поддерживает предварительную загрузку изображений, скриптов или любых ресурсов, которые могут кэшироваться браузером.

    добавить в голову <linkrel="prefetch"href="image.png">

  • prerender — это тяжеловесная опция, которая позволяет браузеру предварительно загружать все ресурсы указанной страницы.

  • subresource может использоваться для указания ресурса с наивысшим приоритетом. Текущая страница требует или скоро будет использоваться, когда.

  1. схема рендеринга:
    • Статическая визуализация (SR)
    • Внешний рендеринг (CSR)
    • Рендеринг на стороне сервера (SSR)
    • Рендеринг на стороне клиента (NSR): запрос данных NSR, запрос данных первого экрана и онлайн-данные распараллелены с инициализацией веб-просмотра и инициализацией фреймворка JS, что значительно сокращает время первого экрана.

640.png

Шесть распространенных шаблонов проектирования и сценариев приложений

Блог Woohoo.cn на.com/maintenance-2017/afraid/…

Концепция шаблона наблюдателя

Шаблон шаблона наблюдателя, который является своего рода шаблоном поведения, он определяет отношение зависимости «один ко многим»,Разрешить нескольким объектам-наблюдателям одновременно прослушивать объект темы. Этот подчиненный объект будет уведомлять все объекты-наблюдатели об изменении состояния.

Концепция шаблона публикации-подписки

В модели публикации-подписки отправитель сообщения называетсядиктор(издатели), сообщения не отправляются напрямую конкретным получателям, называемымподписчик. Это означает, что издатели и подписчики не знают о существовании друг друга. Требуется сторонний компонент, называемый брокером сообщений, который соединяет подписчиков и издателей, а также фильтрует и распределяет все входящие сообщения. Другими словами, модель публикации-подписки.Используется для управления обменом информацией между различными компонентами системы., даже если эти компоненты не знают о существовании друг друга.

требует стороннего компонента под названиеминформационный посредник, который объединяет подписчиков и издателей

заводской узорВ основном предоставляет интерфейс для создания объектов. Сценарий: при кодировании невозможно предугадать, какой экземпляр класса необходимо создать.

Режим агента Командный режим

одноэлементный шаблон

Гарантирует наличие только одного экземпляра класса и предоставляет к нему глобальную точку доступа. (окно)

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

Семиуровневая сетевая модель

Прикладной уровень, уровень представления, сеансовый уровень, транспортный уровень, сетевой уровень, канальный уровень, физический уровень

TCP: ориентированная на соединение, надежная передача (гарантия правильности данных, обеспечение порядка данных), используемая для передачи большого объема данных (режим потока), медленная скорость и требующая больших накладных расходов (время, системные ресурсы) для установления соединения. (Сценарии применения: HTP, HTTP, почта)

UDP: Не ориентированная на соединение, ненадежная передача, используется для передачи небольшого количества данных (пакетный режим), высокая скорость, возможная потеря пакетов (сценарий применения: обмен мгновенными сообщениями)

是否连接     面向连接     面向非连接
传输可靠性   可靠        不可靠
应用场合    少量数据    传输大量数据

https процесс шифрования и дешифрования

HTTPSне новое соглашение, аHTTP + SSL

SSL(Secure Socket Layer): это безопасный протокол передачи, разработанный Netscape и используемый в основном для WEB. Он отвечает за реализацию упомянутого выше уровня шифрования в стеке протоколов https.

Клиент сначала запрашивает у сервера открытый ключ, затем шифрует информацию открытым ключом, а после получения зашифрованного текста сервер расшифровывает его своим закрытым ключом. Открытый ключ сервера помещается в цифровой сертификат.

  1. Сервер регистрирует свой собственный открытый ключ в цифровом центре сертификации.

  2. Центр цифровой сертификации использует свой собственный закрытый ключ для цифровой подписи открытого ключа сервера и выдачи сертификата открытого ключа.

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

  4. Сообщение шифруется открытым ключом сервера и отправляется.

  5. Сервер расшифровывает сообщение с помощью закрытого ключа.

Весь процесс от URL до загрузки и рендеринга

  1. Разрешение доменного имени DNS.
  2. Трехстороннее рукопожатие TCP для установления соединения.
  3. Отправить сообщение HTTP-запроса.
  4. Сервер обрабатывает запрос и возвращает ответное сообщение.
  5. Браузер Parses, рендеринг страницы.
  6. Четыре машут, отключены.

DNS-протоколпредоставлено域名查找 IP地址, или наоборот отIP地址反查域名оказание услуг. DNS — это сетевой сервер, разрешение нашего доменного имени — просто запись информационной записи в DNS.

Трехстороннее рукопожатие TCP, четыре волны: рукопожатие и волна инициируются клиентом и завершаются клиентом.Трехстороннее рукопожатие и четырехсторонняя волна

Балансировка нагрузки: прежде чем запрос попадет на реальный сервер приложений, он также может пройти через машину, отвечающую за балансировку нагрузки, ее функция заключается в передаче запроса合理地分配到多个服务器上, пересылая HTTP-запросы, в то же время он имеет такие функции, как защита от атак. Его можно разделить на балансировку нагрузки DNS, балансировку нагрузки HTTP, балансировку нагрузки IP, балансировку нагрузки канального уровня и т. д.

Web Server: после того, как запрос пройдет предыдущую балансировку нагрузки, он попадет на веб-сервер на соответствующем сервере, напримерApache,Tomcat

обратный проксиработает по HTTP, как правилоNginx. Доступ к baidu.com со всей страны должен осуществляться через прокси, а доступ к серверу Baidu невозможен. (VPN перенаправление прокси, прокси-клиент)

Процесс рендеринга парсинга браузера: После того, как возвращенный html будет передан в браузер, если есть gzip, он будет сначала распакован, чтобы узнать формат кодировки файла, и загрузить ресурсы внешней ссылки. HTML анализируется сверху вниз, когда встречается js, css останавливает синтаксический анализ и рендеринг до тех пор, пока js не будет выполнен. Разобрать HTML, построить DOM-дерево Разобрать CSS и создать дерево правил CSS Объедините дерево DOM и правила CSS для создания дерева рендеринга для рендеринга.

Не вызывает изменения дерева DOM, изменения макета страницы, а поведение изменения стилей элементов называетсяперерисовать

Поведение, которое приводит к изменению структуры дерева DOM и изменению макета страницы, называетсяпереплавка

GUI渲染线程Отвечает за отрисовку HTML-элементов интерфейса браузера, когда интерфейсу это необходимо.重绘(Repaint)или вызвано какой-либо операцией回流(reflow), поток будет выполнен.Когда движок Javascript запускает сценарий, поток рендеринга GUI находится в приостановленном состоянии, то есть «заморожен» до завершения выполнения JS-программы., затем будет выполнено. Поэтому, если время выполнения JS слишком велико, это приведет к непоследовательности рендеринга страницы, что приведет к ощущению рендеринга страницы и блокировки загрузки. JavaScript может манипулировать моделью DOM. Если интерфейс визуализируется при изменении атрибутов этих элементов, данные элемента могут быть несогласованными до и после визуализации.

рисунок графическим процессороммногопроцессный браузер: основной процесс, процесс подключаемого модуля, графический процессор, вкладка (ядро браузера)Многопоточное ядро ​​браузера: Каждую вкладку можно рассматривать как процесс ядра браузера, и тогда этот процесс является многопоточным.

Он имеет несколько основных категорий подпотоков:

  • Графический поток
  • Поток движка JS
  • поток триггера события
  • поток таймера
  • поток HTTP-запросов

http1 и HTTP2

http2

мультиплексирование: Несколько запросов для одного и того же доменного имени используют одно и то же TCP-соединение, что снижает задержку.

приоритет запроса: установить приоритет для каждого запроса

бинарная передача; ранее переданный в виде обычного текста

поток данных: Пакеты данных не отправляются последовательно, и пакеты данных помечены. Все пакеты каждого запроса или ответа становятся потоком данных,

Пуш сервера: Вы можете активно отправлять сообщения клиенту.

сжатие заголовка: уменьшить размер и количество пакетов

В конвейерной передаче в HTTP/1.1, если есть请求阻塞, то запросы после очереди блокируются. Множественные запросы HTTP/2 мультиплексируют TCP-соединение, в случае потери пакетов все HTTP-запросы будут заблокированы. HTTP/3 изменяет протокол TCP, лежащий в основе HTTP, наUDP! http1 сохранить последовательную передачу

Какова функция keep-alive в http

указать в заголовке ответаkeep-aliveможет быть отправлен через TCP-соединениенесколько httpпросить

Политика кэширования браузера

Strong cache: cache-control; no-cache max-age=; expires; Cache-Control имеет более высокий приоритет, чем Expires;

Полями, управляющими принудительным кэшированием, являются Expires и Cache-Control.Если время клиента меньше значения Expires, кэшированный результат используется напрямую.

Согласовать кеш:Last-Modified/If-Modified-Since и Etag/If-None-Match, где Etag/If-None-Match имеет приоритет над Last-Modified/ Для первого запроса сервер добавит поле Last-Modified в заголовок возвращаемого ответа, указывающее время последнего изменения ресурса.

При повторном запросе браузера поле If-Modified-Since будет включено в заголовок запроса, и если два поля сравниваются, это означает, что ресурс не был изменен, и возвращается 304; в противном случае возвращается ресурс с кодом состояния 200;

Механизм сбора мусора:

标记清除: переменные, которые входят в среду выполнения, помечаются, и после завершения выполнения эти метки и переменные очищаются. Посмотрите, есть ли ссылка на переменную.

引用计数: Количество ссылок на каждое значение будет записано.Когда количество ссылок станет равным 0, оно будет освобождено.

Фронтальная безопасность

Одинаковая политика происхождения: если два URL-адресаПротокол, доменное имя и портодинаковы, мы называем два URL-адреса одним и тем же источником. потому что в браузере естьcookies.

  • XSS: Межсайтовый скриптингinput, textareaПодождите, пока во все возможные области будет введена текстовая информация, введите<script src="http://恶意网站"></script>Подождите, информация будет сохранена на сервере после отправки.

  • CSRF: Подделка межсайтовых запросов. Заманивание пользователя на открытие веб-сайта хакера, на веб-сайте хакера межсайтовый запрос, инициированный статусом входа пользователя.

    Aсайтimgизsrc=BИнтерфейс запроса сайта доступен; решение:refererНести источник запроса

    После посещения страницы форма автоматически отправляется автоматически, имитация операции по почте и отправка почтового запроса

    решить: Бэкэнд вводит随机串прибытьCookie, внешний интерфейс запрашивает извлечение случайной строки и добавление ее в серверную часть.

  • http угон: Угон оператора связи

  • SQL-инъекция

  • Clickjing: побуждает пользователя щелкнуть кажущуюся безобидной кнопку (которая на самом деле щелкает прозрачнуюiframe кнопку), разрешите заголовок бэкэнд-запроса и добавьте полеX-Frame-Options

  • Уязвимость при загрузке файлов: Сервер не проверил загруженный файл

CSS и HTML

Что такое BFC (контекст форматирования на уровне блоков),IFC(контекст встроенного форматирования),FFC(модель гибкой коробки)

BFC(Block formatting context),Прямо сейчас块级格式化上下文, который действует как独立渲染区域, в рендеринге участвуют только элементы в области, и это не повлияет на ее внешние элементы. Проще говоря, БФК можно рассматривать как «осажденный город», элементы снаружи не могут попасть внутрь, а элементы внутри не могут выбраться наружу (не мешая друг другу).

Контейнер, который решает, как рендерить элементы, правила рендеринга:

  • 1. Внутренние элементы блочного уровня будут размещены один за другим в вертикальном направлении.

  • 2. Вертикальное расстояние блочных элементов определяется отступом. Поля двух соседних элементов блочного уровня, принадлежащих одному и тому же BFC, будут перекрываться.

  • 3. При форматировании слева направо левый край каждого элемента (блочного и встроенного элементов) касается левого края содержащего его блока (обратное верно для форматирования справа налево). Это верно, даже если элемент в содержащем блоке имеет числа с плавающей запятой, если только элемент в нем снова не генерирует BFC.

  • 4. Область БТЧ не будет перекрываться плавающими элементами.

  • 5. BFC — это изолированный и независимый контейнер, и дочерние элементы внутри контейнера и элементы снаружи не влияют друг на друга.

  • 6. При расчете высоты контейнера БТЭ в расчете также участвует плавающий элемент.

Условия формирования БФК:

1. Плавающие элементы, значения float отличные от none;

2. Элементы позиционирования, положение (абсолютное, фиксированное);

3. display — одно из следующих значений inline-block, table-cell, table-caption;

4. Значения переполнения, отличные от видимых (скрытые, авто, прокрутка);

BFC обычно используется для решения следующих проблем

  • Проблема с перекрытием полей
  • Устранение плавающих проблем
  • проблема с адаптивной версткой

flex: 0 1 auto;Что значит?

Элементы имеют размеры в соответствии с их собственной шириной и высотой. он укорачивается, чтобы соответствоватьflexконтейнер, но не растягивается и не впитываетflexДополнительное свободное место в контейнере для установкиflexконтейнер. горизонтальный шпиндель (main axis) и вертикальной поперечной оси (cross axisНесколько атрибутов решают, какое соглашение о оси

  • flex-grow: 0безразмерныйколичество(): это будет рассматриваться как<flex-grow>的值。
  • flex-shrink: 1допустимое значение ширины: оно будет рассматриваться как<flex-basis>的值。
  • flex-basis: autoключевые словаnone,autoилиinitial.

Основное пространство оси заняло до расширения, масштабирования и выделения избыточного пространства.

Избегайте глобального загрязнения CSS

  1. свойство с ограниченной областью действия
  2. css in js
const styles = {
  bar: {
    backgroundColor: '#000'
  }
}
const example = (props)=>{
  <div style={styles.bar} />
}
  1. CSS Modules
  2. Используйте меньше, экономно используйте глобальные селекторы пар
// 选择器上>要记得写,免得污染所有ul下面的li
ul{
  >li{
    color:red;
  }
}

CSS Modules

CSS-модули Руан Ифэн

Модули CSS — это процесс на этапе сборки. с помощью строительных инструментов指定classдостигатьscopeпроцесс.

CSS Modulesс разрешения::global(.className)синтаксис, объявляет глобальное правило. Все, что так заявленоclass, не будет компилироваться в哈希字符串.:local(className): выполнить обработку правила localIdentName, скомпилировать уникальное имя хеш-класса.

Характеристики модулей CSS:

  • Не используйте селекторы, просто используйте имена классов для определения стилей.
  • Вместо объединения нескольких классов используйте только один класс для определения всех стилей.
  • Не вкладывать классы

коробочная модель иbox-sizingАтрибуты

width: 160px; padding: 20px; border: 8px solid orange;Стандартный размер коробки:content-box;Общая ширина элемента = 160 + 202 + 82; IEborder-box: общая ширина160

margin/paddingВыбиратьпроцентстоимость , исходя изширина и высота родительского элементаиз.

css нарисовать треугольник

  1. Обработано границей
// border 处理
.class {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid red;
}
// 宽高+border
div {
    width: 50px;
    height: 50px;
    border: 2px solid orange;
}
  1. отсечение клипа для получения
div{
 clip-path: polygon(0 100%, 50% 0, 100% 100%);
}
  1. Градиентная линейно-градиентная реализация
div {
  width: 200px;
  height: 200px;
  background:linear-gradient(to bottom right, #fff 0%, #fff 49.9%, rgba(148,88,255,1) 50%,rgba(185,88,255,1) 100%);
}

Как добавить тени к треугольникам после их реализации в CSS

? ? ?

N реализаций двухколоночного макета CSS

Существует два типа макетов с двумя столбцами: один фиксированной ширины слева и адаптивный справа, а другой — адаптивный для обоих столбцов (то есть ширина слева определяется дочерними элементами, а остальные место справа заполнено).

  1. Как добиться фиксированной ширины слева и адаптивной справа
// 两个元素都设置dislpay:inline-block
    .left {
        display: inline-block;
        width: 100px;
        height: 200px;
        background-color: red;
        vertical-align: top;
    }
    .right {
        display: inline-block;
        width: calc(100% - 100px);
        height: 400px;
        background-color: blue;
        vertical-align: top;
    }
// 两个元素设置浮动,右侧自适应元素宽度使用calc函数计算
      .left{
          float: left;
          width: 100px;
          height: 200px;
          background-color: red;
      }
      .right{
          float: left;
          width: calc(100% - 100px);
          height: 400px;
          background-color: blue;
      }
// 父元素设置display:flex,自适应元素设置flex:1
    .box{
        height: 600px;
        width: 100%;
        display: flex;
    }
    .left{
        width: 100px;
        height: 200px;
        background-color: red;
    }
    .right{
        flex: 1;
        height: 400px;
        background-color: blue;
    }
    // 父元素相对定位,左侧元素绝对定位,右侧自适应元素设置margin-left的值大于定宽元素的宽度
        .left{
            position: absolute;
            width: 100px;
            height: 200px;
            background-color: red;
        }
        .right{
            margin-left: 100px;
            height: 400px;
            background-color: blue;
        }
  1. И левый, и правый элементы адаптивны
// flex布局 同上
// 父元素设置display:grid; grid-template-columns:auto 1fr;(这个属性定义列宽,auto关键字表示由浏览器自己决定长度。fr是一个相对尺寸单位,表示剩余空间做等分)grid-gap:20px(行间距)
    .parent{
        display:grid;
        grid-template-columns:auto 1fr;
        grid-gap:20px
    } 
    .left{
        background-color: red;
        height: 200px;
    }
    .right{
        height:300px;
        background-color: blue;
    }
    //浮动+BFC   父元素设置overflow:hidden,左侧定宽元素浮动,右侧自适应元素设置overflow:auto创建BFC
    .box{
        height: 600px;
        width: 100%;
        overflow: hidden;
    }
    .left{
        float: left;
        width: 100px;
        height: 200px;
        background-color: red;
    }
    .right{
        overflow: auto;
        height: 400px;
        background-color: blue;
    }

Трехколоночный макет CSS

  1. Плавающий макет: левый плавающий влево, правый плавающий вправо, среднее поле: 0 100 пикселей;

  2. Расположение макета: слева слева: 0, справа справа: 0, посередине слева: 100 пикселей, справа: 100 пикселей;

  3. макет таблицы: отображение родительского элемента: таблица, ширина слева и справа: 100 пикселей, отображение трех элементов: таблица-ячейка;

  4. Гибкая (гибкая) компоновка: отображение родительского элемента: flex, ширина слева и справа: 100px;

  5. Макет сетки:

// gird提供了 gird-template-columns、grid-template-rows属性让我们设置行和列的高、宽
    .div{
        width: 100%;
        display: grid;
        grid-template-rows: 100px;
        grid-template-columns: 300px auto 300px;
    }

Общие сценарии и проблемы

Как приложение общается и взаимодействует с H5?

// 兼容IOS和安卓
callMobile(parameters,messageHandlerName) {
  //handlerInterface由iOS addScriptMessageHandler与andorid addJavascriptInterface 代码注入而来。
  if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
    // alert('ios')
    window.webkit.messageHandlers[messageHandlerName].postMessage(JSON.stringify(parameters))
  } else {
    // alert('安卓')
    //安卓传输不了js json对象,只能传输string
    window.webkit[messageHandlerName](JSON.stringify(parameters))
  }
}

Собственный метод вводится в окно приложением для вызова js.

messageHandlerNameсогласованный способ связиparametersПараметры, которые необходимо передать

Решение для адаптации мобильного терминала

remотносится к корневому элементу HTMLemРазмер шрифта относительно родительского элемента.VW,VHОтношение ширины экрана к высоте

  //按照宽度375图算, 1rem = 100px;
(function (win, doc) {
   function changeSize() {
     doc.documentElement.style.fontSize = doc.documentElement.clientWidth / 3.75 + 'px';
    console.log(100 * doc.documentElement.clientWidht / 3.75)
   }
   changeSize();
   win.addEventListener('resize', changeSize, false);

})(window, document);

Программирование кода

Реализовать публикацию-подписку

   /* Pubsub */
      function Pubsub(){
        //存放事件和对应的处理方法
        this.handles = {};
      }

      Pubsub.prototype = {
        //传入事件类型type和事件处理handle
        on: function (type, handle) {
          if(!this.handles[type]){
            this.handles[type] = [];
          }
          this.handles[type].push(handle);
        },
        emit: function () {
          //通过传入参数获取事件类型
          //将arguments转为真数组
          var type = Array.prototype.shift.call(arguments);
          if(!this.handles[type]){
            return false;
          }
          for (var i = 0; i < this.handles[type].length; i++) {
            var handle = this.handles[type][i];
            //执行事件
            handle.apply(this, arguments);
          }
        },
        off: function (type, handle) {
          handles = this.handles[type];
          if(handles){
            if(!handle){
              handles.length = 0;//清空数组
            }else{
            for (var i = 0; i < handles.length; i++) {
              var _handle = handles[i];
              if(_handle === handle){
                //从数组中删除
                handles.splice(i,1);
              }
            }
          }
        }  
      }

Как промисы реализуют связанные вызовы и возвращают разные состояния

// MyPromise.js

// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

// 新建 MyPromise 类
class MyPromise {
  constructor(executor){
    // executor 是一个执行器,进入会立即执行
    // 并传入resolve和reject方法
    executor(this.resolve, this.reject)
  }

  // 储存状态的变量,初始值是 pending
  status = PENDING;

  // resolve和reject为什么要用箭头函数?
  // 如果直接调用的话,普通函数this指向的是window或者undefined
  // 用箭头函数就可以让this指向当前实例对象
  // 成功之后的值
  value = null;
  // 失败之后的原因
  reason = null;

  // 更改成功后的状态
  resolve = (value) => {
    // 只有状态是等待,才执行状态修改
    if (this.status === PENDING) {
      // 状态修改为成功
      this.status = FULFILLED;
      // 保存成功之后的值
      this.value = value;
    }
  }

  // 更改失败后的状态
  reject = (reason) => {
    // 只有状态是等待,才执行状态修改
    if (this.status === PENDING) {
      // 状态成功为失败
      this.status = REJECTED;
      // 保存失败后的原因
      this.reason = reason;
    }
  }

    then(onFulfilled, onRejected) {
    // 判断状态
    if (this.status === FULFILLED) {
      // 调用成功回调,并且把值返回
      onFulfilled(this.value);
    } else if (this.status === REJECTED) {
      // 调用失败回调,并且把原因返回
      onRejected(this.reason);
    }
  }

}


Реализовать обещание.все

// Promise.all

Promise.all = function (promises) {
  let result = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promises.forEach((p, index) => {
      // 兼容不是promise的情况 
      Promise.resolve(p).then((res) => {
        result[index] = res;
        count++;
        if(count === promises.length) {
          resolve(result)
        }
      }).catch((err) => {
        reject(err);
      })
    })
  });
}


Преобразование массива объектов в массив деревьев


> 将entries 按照 level 转换成 result 数据结构

const entries = [
    {
        "province": "浙江", "city": "杭州", "name": "西湖"
    }, {
        "province": "四川", "city": "成都", "name": "锦里"
    }, {
        "province": "四川", "city": "成都", "name": "方所"
    }, {
        "province": "四川", "city": "阿坝", "name": "九寨沟"
    }
];
	
const level = ["province", "city", "name"];

const  result = [
	{
		value:'浙江',
		children:[
			{
				value:'杭州',
				children:[
					{
						value:'西湖'
					}
				]
			}
		]
	},
	{
		value:'四川',
		children:[
			{
				value:'成都',
				children:[
					{
						value:'锦里'
					},
					{
						value:'方所'
					}
				]
			},
			{
				value:'阿坝',
				children:[
					{
						value:'九寨沟'
					}
				]
			}
		]
	},
]

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

function transfrom(list, level) {
  const res = [];
  list.forEach(item => {
    pushItem(res, item, 0);
  });

  function pushItem(arr, obj, i) {
    const o = {
      value: obj[level[i]],
      children: [],
    };
    // 判断传入数组里是否有value等于要传入的项
    const hasItem = arr.find(el => el.value === obj[level[i]]);
    let nowArr;
    if(hasItem) {
      // 存在,则下一次遍历传入存在项的children
      nowArr = hasItem.children;
    }else{
      // 不存在 压入arr,下一次遍历传入此项的children
      arr.push(o);
      nowArr = o.children;
    }
    if(i === level.length - 1) delete o.children;
    i++;
    if(i < level.length) {
      // 递归进行层级的遍历
      pushItem(nowArr, obj, i);
    }
  }
}

transfrom(entries, level);

Нативная реализация метода JS instanceof

Простое использование

function Fn () {}
const fn = new Fn()
fn instanceof Fn  // true

Реализация выглядит следующим образом:

// left instanceof right
function _instanceof(left, right) {
  // 构造函数原型
  const prototype = right.prototype
  // 实列对象属性,指向其构造函数原型
  left = left.__proto__
  // 查实原型链
  while (true) {
    // 如果为null,说明原型链已经查找到最顶层了,真接返回false
    if (left === null) {
      return false
    }
    // 查找到原型
    if (prototype === left){
      return true
    }
    // 继续向上查找
    left = left.__proto__
  }
}

const str = "abc"
_instanceof(str, String) // true

вопросы по программированию

Объединение массивов с одинаковыми элементами

// 例如:
const arr = [
    ['a', 'b', 'c'],
    ['a', 'd'],
    ['d', 'e'],
    ['f', 'g'],
    ['h', 'g'],
    ['i']
]
// 运行后的返回结果是:
[
    ['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h'],
    ['i']
]
// 思路一:
const arr = [['a', 'b', 'c'], ['a', 'd'], ['d', 'e'], ['f', 'g'], ['h', 'g'], ['i']]
function transform(arr){
    let res = []
    arr = arr.map(el => el.sort()).sort()
    const item = arr.reduce((pre, cur) => {
      if (cur.some(el => pre && pre.includes(el))) {
        pre = pre.concat(cur)
      } else {
        res.push(pre)
        pre = cur
      }
      return [...new Set(pre)]
    })
    res.push(item)
    return res;
}
transform(arr)
// console.log(transform(arr));

// 思路二: 

function r (arr) {
  const map = new Map()
  arr.forEach((array, index) => {
    const findAlp = array.find((v) => map.get(v))
    if (findAlp) {
      const set = map.get(findAlp)
      array.forEach((alp) => {
        set.add(alp)
        const findAlp2 = map.get(alp)
        if (findAlp2 && findAlp2 !== set) {
          for(const v of findAlp2.values()){
            set.add(v)
            map.set(v, set)
          }
        }
        map.set(alp, set)
      })
    } else {
      const set = new Set(arr[index])
      array.forEach((alp) => map.set(alp, set))
    }
  })
  const set = new Set()
  const ret = []
  for (const [key, value] of map.entries()) {
    if (set.has(value)) continue
    set.add(value)
    ret.push([...value])
  }
  return ret
}

Более лаконичный arr преобразован в res

let arr =[2,1,3,'3',[1,2],7,[4,5,[8]],6,[4]]

// 多维数组扁平化,数组项数字字符串去重,升序排列
res = [1,2,3,4,5,6,7,8]

//思路1
var res = [...new Set(arr.flat(2).map(i=>Number(i)))];
// 思路2
var res = [...new Set(nums1)].filter(item=>new Set(nums2).has(item)

Добавлено: Присоединяйтесь к нам

Записывая использование обучения, я не ожидал, что эта статья будет популярной.

Работает больше месяца.Очень доволен компанией (введение), нажмите внутрь, идентифицируйте QR-код ниже, чтобы просмотреть позицию, и оставьте сообщение, чтобы связаться со мной.

  • Сдержанная иностранная компания, компания без объемных сокровищ, расположенная в Наньшане, Шэньчжэнь.
  • Много моих коллег Даниил, английская офисная среда
  • Вступление, которое на 22 дня ежегодный отпуск, 1075, в настоящее время в понедельник пятница может подать заявку на работу дома (большинство разработчиков)
  • Конкурентное лечение, двусторонняя внутренняя плата за толчок
  • Основная часть сотрудников Шэньчжэньской команды подписала контракт в Шэньчжэне, а материнская компания находится за границей.

Image from iOS (1).jpg