Случайно я нашлаИнтерфейсное перечислениеновый геймплей. Сначала я растерялся и подумал: «Что это?»
Замедлившись, он воскликнул: «Изысканно! Ниуби! Высокая эффективность!»
Я попробовал использовать его в проекте компании, и я действительно почувствовал, что эффективность выполнения программы стала быстрее (конечно, должны быть психологические намеки).
эта неделяCode ReviewКогда коллеги были в шоке:
Давайте посмотрим, что это за игра!
1. Определение перечисления
/**
* SKILLS:面试者的技能枚举
**/
const SKILLS = {
CSS: 1 ,
JS: 1 << 1,
HTML: 1 << 2,
WEB_GL: 1 << 3
}
Определение перечисления выглядит обыденным, но немного странным, не так ли?
пожалуйста, объясни:
<<символjsпобитовые операторы в ,1 << Nозначает:поставь цифры1переместить биты влевоNнемного.
1 << 1 // 2
// 二进制:1 => 10
1 << 2 // 4
// 二进制:10 => 100
...
1 << N // 2的N次方
Во-вторых, использование перечисления
Мы определили перечисление, как в «Шаге 1», так как же его использовать?
Предположим сценарий: когда мы берем интервью у фронтенд-одноклассника, мы постоянно будем отмечать, какие у него навыки.Процесс добавления оценок выглядит следующим образом:
let skills = 0
// 增加一项他会的技能
function addSkill(skill) {
skills = skills | skill // 加上
}
addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13
После завершения добавления умений нам необходимо потратить те умения, которые есть у этого человека в других местах.Процесс расходования выглядит следующим образом:
// 判断他是否会 CSS
SKILLS.CSS & skills // 1 (0 代表不会,非0代表会)
// 判断他是否会 JS
SKILLS.JS & skills // 0 (0 代表不会,非0代表会)
// 判断他是否会 HTML 且会 WebGl
SKILLS.HTML & skills && SKILLS.WEB_GL & skills // 8 (0 代表不会,非0代表会)
// 判断他是否会 JS 或会 HTML
SKILLS.JS & skills || SKILLS.HTML & skills
В ПОРЯДКЕ! Доступны базовые способности.
Некоторые студенты спросят: «Какие у него преимущества? Читабельность такая плохая!»
Плюсы конечно есть, плюсы такие: эффективенВор высокий!
3. Сравнение эффективности
Чтобы проверить его «насколько эффективно», я написал два общих «контрольных» письма для проверки.
Общий метод записи 1: воспроизведение массива
let skills = []
function addSkill(skill) {
if (!skills.includes(skill)) { // 判断技能术里是否有该技能
skills.push(skill)
}
}
addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13
skills.includes(SKILLS.CSS)
skills.includes(SKILLS.JS)
skills.includes(SKILLS.HTML) && skills.includes(SKILLS.WEB_GL)
skills.includes(SKILLS.JS) || skills.includes(SKILLS.HTML)
Таким образом, массив используется для хранения перечисления навыков, а затемarr.includes()метод, чтобы определить, было ли сохранено перечисление.
Обычное написание два:Mapиграть в
let skills = {}
function addSkill(skill) {
if (!(skills[skill])) { // 判断技能术里是否有该技能
skills[skill] = true
}
}
addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13
skills[SKILLS.CSS]
skills[SKILLS.JS]
skills[SKILLS.HTML] && skills[SKILLS.WEB_GL]
skills[SKILLS.JS] || skills[SKILLS.HTML]
Этот метод через{ [value]: true }способ сохранить перечисление, а затем передатьmap[value]способ получить значение, чтобы определить, было ли сохранено перечисление.
сравнить результаты
Угадайте, каковы будут рейтинги эффективности трех способов?
Результат выглядит следующим образом:
Самая быстрая группа: группа битовых операций (способ воспроизведения, рекомендуемый в этой статье)
1,1 миллиарда выполнений в секунду
Второе место: игра с массивом
31,24 миллиона выполнений в секунду
Самая медленная группа:Mapиграть в
9,52 миллиона выполнений в секунду
Адрес варианта использования:Это Mercedes-Benz What/4OK и люди 97 его 9/…
Заинтересованные друзья могут посетить ссылку выше для самопроверки.
Согласно анализу результатов,最快и最慢даже между2-3разница на уровне данных.
В-четвертых, принципиальный анализ (почему так быстро!)
Почему «формула битовой операции», рекомендованная в этой статье, настолько эффективна? Как он выполняет вышеуказанные функции с помощью битовых операций?
4.1 Принцип определения
Это должно быть изJavascriptГоворя о формате данных среднего целого числа, целое число со знаком использует 31 бит для представления значения целого числа, а32Биты представляют знак целого числа,0представляет собой положительное число,1представляет отрицательное число. Диапазон значений[-2^31,2^31-1], то есть [-2147483648, 2147483647].Когда мы определяем перечисления, каждое перечисление занимает двоичное значение в другом бите.
Поэтому этот метод подходит только дляМеньше или равно 31 пункту перечисленияместо действия.
4.2 Принцип хранимой стоимости
Почемуskills = skills | skill Этот код может представлятьсуществуетskillsДобавлен элемент перечисления в?
|даJavascriptПобитовые операторы в:или.
когда два значения|В ходе операции сравнивается каждый бит, и по любому одному биту, если оба числа равны.0, то результат0; остальные результаты1;
Например:
1 << 1 | 1 << 2 // 010 | 100
// 结果为 110,即数字:6
1 | 1 << 3 // 0001 | 1000
// 结果为 1001,即数字:9
Поэтому до тех пор, пока выполнениеskills = skills | skill , в результатеskillДолжен быть соответствующий1.
4.3 Принцип ценности
ПочемуSKILLS.CSS & skillsвозвращение非0значение, может представлятьskillsсодержитSKILLS.CSS? Иначе не включает?
&даJavascriptОператоры в:и.
когда два значения&Во время операции каждый бит сравнивается, и если два числа в любом одном бите равны1, то результат1; остальные результаты0;
Например:
1 & 9 // 0001 & 1001 = 0001 (1)
2 & 8 // 0010 & 1000 = 0000 (0)
следовательно,SKILLS.CSS & skillsвозвращение非0значение, его можно определитьskillsдолжен существовать вSKILLS.CSS.
5. Кто его использует? (Ю Юси: Это здесь)
Где я видел вышеуказанное использование?
Да, это изvue3видно в исходном коде.
Адрес источника:GitHub1 — это .com/v UE JS/core/…
В этом исходном кодеvue3Определять перечисления таким образом, служебные перечисления, очень полезно.
ShapeFlagsПеречисление определяется как:
export const enum ShapeFlags {
ELEMENT = 1,
FUNCTIONAL_COMPONENT = 1 << 1,
STATEFUL_COMPONENT = 1 << 2,
TEXT_CHILDREN = 1 << 3,
ARRAY_CHILDREN = 1 << 4,
SLOTS_CHILDREN = 1 << 5,
TELEPORT = 1 << 6,
SUSPENSE = 1 << 7,
COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,
COMPONENT_KEPT_ALIVE = 1 << 9,
COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT
}
Заканчивать
я春哥.
я люблюvue.js , ElementUI , Element PlusЧто касается стека родственных технологий, то моя цель — поделиться с вами самыми практичными и полезными моментами знаний, надеюсь, каждый сможет пораньше уйти с работы, быстро закончить работу и успокоиться.
ты сможешьНаггетсПодписывайтесь на меня:春哥的梦想是摸鱼, также доступный впубликанайди меня в:前端要摸鱼.
Надеюсь, вы все станете сильнее в 2022 году.