JavaScript 编写枚举的最有效方法分享

目录
  • 前言
  • 定义枚举
  • << 是什么?
  • 用法
  • 如何理解这段代码?
  • 我们为什么要使用这个技巧?
  • 学习Vue源码

前言

假设有这样一个场景,我们需要统计员工的技术栈,目前我们需要标记的技术有 CSS、JavaScript、HTML、WebGL。

然后我可以这样写枚举:

const SKILLS = {
 CSS: 1 ,
 JS: 2,
 HTML: 3,
 WEB_GL: 4
}

之前是这样写的,但是,最近看vue源码的时候,发现了一个高效使用枚举的技巧,在这里分享给大家。

定义枚举

我们可以这样写上面的枚举:

const SKILLS = {
 CSS: 1 ,
 JS: 1 << 1,
 HTML: 1 << 2,
 WEB_GL: 1 << 3
}

<< 是什么?

左移运算符 (<<) 将第一个操作数左移指定位数。向左移动的多余位被丢弃。零位从右侧移入。

例如:

  • 二进制的 1 是 0000 0001 ,左移一位是 0000 0010 ,即十进制的 2 。
  • 如果我们将其移动两位,它将变为 0000 0100 ,即十进制的 4。
  • 如果我们将其移动三位,它将变为 0000 1000 ,即十进制的 8。
  • 如果我们将其移动 N 位,它将变为 2^Nin 十进制。

用法

按照上面的方法定义好枚举后,我们可以这样使用:

const SKILLS = {
 CSS: 1 ,
 JS: 1 << 1,
 HTML: 1 << 2,
 WEB_GL: 1 << 3
}
// Use this value to store a user's tech-stack
let skills = 0
// add a skill for the user
function addSkill(skill) {
 skills = skills | skill
}
addSkill(SKILLS.CSS)
addSkill(SKILLS.JS)
// If this value is not 0, it means that the user has mastered the tech
console.log('Does he know CSS', SKILLS.CSS & skills)
console.log('Does he know JavaScript', SKILLS.JS & skills)
console.log('Does he know Web GL', SKILLS.WEB_GL & skills)

温馨提示:| 是按位或运算符,它在每个操作数的对应位为 1 的每个位位置返回 1。

cons
t a = 5;        // 00000000000000000000000000000101
const b = 3;        // 00000000000000000000000000000011
console.log(a | b); // 00000000000000000000000000000111
// expected output: 7

如何理解这段代码?

在 JavaScript 中,整数存储在 4 个字节中,即 32 位。第一个代表正负,后面的31代表数字。

当我们用二进制表示 1 , 1 << 2 时,它们看起来像这样:

我们定义的枚举变量只有一个二进制格式的1,并且占据不同的位置。

当我们向技能添加枚举选项时,我们使用skills | skill。假设现在我们需要添加的技能是SKILLS.CSS,那么在执行过程中,就是:

我们可以发现,在技能中,SKILLS.CSS对应的位置会变成1。反之,那么我们可以通过查看skills&SKILLS.CSS的结果是否为0来判断技能中是否存在SKILLS.CSS。顺便说一句,这里我们也可以发现这个技巧有个缺点,就是枚举项不能超过 31 个。

我们为什么要使用这个技巧?

答案很简单,这样的代码运行起来更高效。CPU中有直接对应位操作的指令,因此效率更高。

我们也可以做一个性能测试。如果我们不使用按位运算,而是使用传统的方法(数组或映射)来实现,那么代码如下。

Array 方法:

const SKILLS = {
 CSS: 1 ,
 JS: 1 << 1,
 HTML: 1 << 2,
 WEB_GL: 1 << 3
}
// Use an array to store the user's tech-stack
let skills = []
function addSkill(skill) {
 if (!skills.includes(skill)) { // Avoid duplicate storage
   skills.push(skill)
 }
}
addSkill(SKILLS.CSS)
addSkill(SKILLS.JS)
skills.includes(SKILLS.CSS)
skills.includes(SKILLS.JS)
skills.includes(SKILLS.WEB_GL)

Map 方法:

const SKILLS = {
 CSS: 1 ,
 JS: 1 << 1,
 HTML: 1 << 2,
 WEB_GL: 1 << 3
}
// Use a map to store the user's tech-stack
let skills = {}
function addSkill(skill) {
 if (!skills[skill]) {
   skills[skill] = true
 }
}
addSkill(SKILLS.CSS)
addSkill(SKILLS.JS)
skills[SKILLS.CSS]
skills[SKILLS.JS]
skills[SKILLS.WEB_GL]

这是 jsbench.me 的性能测试:

使用按位枚举,性能明显更高。

学习Vue源码

我是从 Vue 源代码中学到的。

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
}

到此这篇关于JavaScript 编写枚举的最有效方法分享的文章就介绍到这了,更多相关JavaScript 枚举编写内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 深入剖析JavaScript中的枚举功能

    由于 Microsoft AJAX Library 对于 JavaScript 进行了大幅扩展, 枚举这个常用的功能当然也被加进去了, 本次就是来探讨 JavaScript 的枚举功能. 由于范例很简单, 所以直接看 HTML 标签就 OK 了 复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">     <title></t

  • 怎样用JS模拟实现枚举

    前言 在当前的JavaScript中,并没有枚举这个概念,在某些场景中使用枚举更能保证数据的正确性,减少数据校验过程,下面就介绍一下JavaScript如何模拟实现枚举效果. 枚举主要特点 枚举值不能重复 不能被修改 实现 let days; (function (days) { days[days["Sunday"] = 0] = "Sunday"; days[days["Monday"] = 1] = "Monday";

  • JavaScript enum枚举类型定义及使用方法

    enum型也被成为枚举类型,它是一种可以将多个常量分组为一个并附加一系列值的类型,使用枚举定义的常量称为枚举器列表,默认情况下,枚举器从零开始按顺序编号.本篇文章给大家介绍关于JavaScript中枚举类型的使用. JavaScript中enum(枚举类型)是什么? JavaScript中是没有枚举类型的,除了JavaScript以外的语言都有enum这个关键词,但为了在JavaScript中使用枚举变量,我们必须自己创建它. 下面我们就来看如何在JavaScript中定义enum(枚举类型)

  • JS 对象属性相关(检查属性、枚举属性等)

    1.删除属性 delete运算符可以删除对象的属性 复制代码 代码如下: delete person.age //即person不再有属性age delete person['age'] //或者这样 delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性 看到delete a.p之后b.x仍然为1 var a = {p:{x:1}}; var b = a.p; console.log(a.p.x); //1 delete a.p; console.log(a.p.x); //Typ

  • javascript模拟枚举的简单实例

    如下,我们来定义Week的枚举: 复制代码 代码如下: if(typeof WeekDay == "undefined"){ var WeekDay = {}; WeekDay.Sunday = 0; WeekDay.Monday = 1; WeekDay.Tuesday = 2; WeekDay.Wedesay = 3; WeekDay.Thursday = 4; WeekDay.Friday = 5; WeekDay.Saturday = 6; } 测试如下:alert(WeekD

  • 枚举JavaScript对象的函数

    From: JavaEye.com 枚举JavaScript对象的函数: function iterator(obj) {  for (var property in obj) {  document.writeln("<p>" + property + " : " + obj[property] + "</p>");  } } 一个简单示例(test.js): function Employee () {   this.

  • Node.JS枚举统计当前文件夹和子目录下所有代码文件行数

    使用Node.JS的大多数用记事本开发,有时侯会需要统计工程代码量,然后记事本大部分没有这个功能.其实用node.js几行代码就可以实现. var path = require('path') var fs = require('fs') //需要统计的文件类型,可自己删减,均小写 var codesFiles = [ '.css', '.js', '.html', '.tmpl', '.part', '.json', '.md', '.txt', '.yml', '.java', '.cs',

  • 通过实例解析js可枚举属性与不可枚举属性

    在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被for-in查找遍历到. 一.怎么判断属性是否可枚举 js中基本包装类型的原型属性是不可枚举的,如Object, Array, Number等,如果你写出这样的代码遍历其中的属性: var num = new Number(); for(var pro in num) { console.log("num." + pro + " = "

  • JavaScript 编写枚举的最有效方法分享

    目录 前言 定义枚举 << 是什么? 用法 如何理解这段代码? 我们为什么要使用这个技巧? 学习Vue源码 前言 假设有这样一个场景,我们需要统计员工的技术栈,目前我们需要标记的技术有 CSS.JavaScript.HTML.WebGL. 然后我可以这样写枚举: const SKILLS = { CSS: 1 , JS: 2, HTML: 3, WEB_GL: 4 } 之前是这样写的,但是,最近看vue源码的时候,发现了一个高效使用枚举的技巧,在这里分享给大家. 定义枚举 我们可以这样写上面的

  • JavaScript实现数组去重的十种方法分享

    目录 方法1 方法2 方法3 方法4 方法5 方法6 方法7 方法8 方法9 方法10 方法1 利用 ES6的set 方法和解构赋值——最常用.最简单. 这个方法是es6之后加入的,是最简单的一种方法. Set是一种结构,是一种不重复值的集合,如:{1,2,3}.它的特性之一就是里面的每一个值都是不重复的: [...new Set(arr)] 意思是将Set结构解构赋值为数组. function Unrepeated1(arr) { return [...new Set(arr)] } cons

  • javascript中自定义对象的属性方法分享

    首先介绍下关联数组: 复制代码 代码如下: <script> var test=new Object(); test["a"]=1; test["b"]="string"; test["c"]=false; alert(test["a"]); </script> 执行上面的代码,显示1.在javascript中,方法和属性一样当做值来看待. 复制代码 代码如下: <script

  • JavaScript编写简单的计算器

    本文实例讲述了JavaScript编写简单计算器的代码.分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>计算器</title> <style> /*Basic reset*/ *{ margin:0; padding:0; b

  • 学习JavaScript的最佳方法分享

    学习新的东西是件可怕的事.对我来说,掌握一项新技能最大的问题是,我不知道自己懂什么.鉴于此,定个计划,学习你感兴趣的东西应该会有用.这篇文章的主旨就是:你为学习JavaScript 制定的蓝图.路线.行动计划!你不必担心找不到最好的资源,先整理些不好的资源,再确定下一步该学什么.遵循它,一步一步来. 任务0:了解什么是JavaScript 在你真正开始学习JavaScript 之前,花一分钟了解一下什么是JavaScript,它有哪些功能. JavaScript不是jQuery.Flash或Ja

  • JavaScript获取URL参数的方法分享

    目录 一.字符串 split 方法 二.使用 URLSearchParams 方法 1.解析搜索字符串 2.生成搜索字符串 3.Node.js 代码 三.使用正则匹配方法 四.使用第三方库 qs 一.字符串 split 方法 url 地址是字符串形式的,所以利用 split 方法将参数提取出来,该方法比较常用,而且容易理解(无关正则) let URL = "http://www.baidu.com?name=小宇&age=25&sex=男&wife=小君"; f

  • 分享JavaScript 类型判断的几种方法

    目录 一.JavaScript 基本类型 1.原始数据类型 2.引用数据类型 3.两种数据类型的存储方式 二.Javascript 数据类型判断的几种方法 1.typeof 2.instanceof 3.构造函数(constructor) 4.Object.prototype.toString.call() 三.写在最后 一.JavaScript 基本类型 首先介绍一下JavaScript中的八大基本类型 1.原始数据类型 除对象类型(object)以外的其它任何类型定义的不可变的值(值本身无法

  • JavaScript求解最长回文子串的方法分享

    目录 题目描述 题解 解决方案 思路一:暴力法 思路二:最长公共字串 思路三:中心拓展 思路四:Manacher 算法 题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案. 示例 2: 输入: "cbbd" 输出: "bb" 题解 回文:指一个正读和反读都相同的字符串

  • JavaScript中关于class的调用方法

    PS:class的调用,其实是可以叠加的,当然了这要求样式不同的情况下,如果样式相同,则后一个样式会覆盖前一个样式. 1.举例如下: <div id="test" class="aaa bbb">测试关于class的调用</div> .aaa{ font-size:20px; color:red; } .bbb{ font-size:50px; color:green; } var test=document.getElementById('

随机推荐