• junjianlin
    junjianlin
    前端开发工程师 · 2023-02-21 08:48:31

    localhost与127.0.0.1的区别:

    localhost:也叫local ,正确的解释是:本地服务器 127.0.0.1:在windows等系统的正确解释是:本机地址(本机服务器)

    localhost:是不经网卡传输的,它不受网络防火墙和网卡相关的的限制。 127.0.0.1:是通过网卡传输的,它依赖网卡,并受到网络防火墙和网卡相关的限制。

  • violetguo
    violetguo
    前端开发工程师 · 2023-02-13 03:16:31

    JS复制文字到剪切板

    execCommand方法

    复制一段文字内容实现的方法是 document.execCommand,兼容性好,但是执行有限制,有性能隐患。需要文字选中才有效,通常做法是创建一个隐藏的输入框,赋值,选中,然后复制。虽然已经被弃用但目前仍可以生效。

    // 创建输入框
    const textarea = document.createElement('textarea');
    document.body.appendChild(textarea);
    // 隐藏此输入框
    textarea.style.position = 'absolute';
    textarea.style.clip = 'rect(0 0 0 0)';
    // 赋值
    textarea.value = '复制的文本内容...';
    // 选中
    textarea.select();
    // 复制
    document.execCommand('copy', true);
    

    image.png

    Clipboard API

    无需浏览器权限申请,文字内容直接进入剪切板,代码简单,使用方便简单,同时是异步,不用担心阻塞。然而,兼容性不足有点遗憾。

    if (navigator.clipboard) {
        navigator.clipboard.writeText(text);
    }
    

    image.png

  • ininitluo
    ininitluo
    前端开发工程师 · 2023-01-05 10:09:35

    使用 Git Bisect 快速找到第一個有問題的 Commit

    
     开始搜寻并标记好与坏的 Commit
    
    git bisect start <坏的 Commit> <好的 Commit>
    
    
     开始后将自动 Checkout 到要检查的 Commit。
    
    
     请执行以下指令标记正常或错误
    
    git bisect good
    
    git bisect bad
    
    
     看到以下文字,代表找到第一个有问题的 Commit。
    
    0675162a1b00bf8d2cdd535d4fc80e3a31196a8e is the first bad commit
    
  • wendylin
    wendylin
    前端开发工程师 · 2023-01-05 09:59:08

    css3 性能优化之 will-change 属性

    will-change:顾名思义“我要变形了“,它的作用是“提高浏览器的页面渲染性能”

    属性:

    auto:默认值,实行标准浏览器优化。

    scroll-position:表示开发者希望在不久后改变滚动条的位置或者使之产生动画。

    contents:表示开发者希望在不久后改变元素内容中的某些东西,或者使它们产生动画。

    <custom-ident>:表示开发者希望在不久后改变指定的属性名或者使之产生动画,比如transform 或 opacity

    例子

    下面告诉浏览器期望元素的变换属性发生变化,以便提前进行适当的优化。

    .el {
        will-change: transform;
    }
    
  • violetguo
    violetguo
    前端开发工程师 · 2023-01-03 02:10:48

    target="_blank"隐患

    应用场景

    通常使用于注重相关用户体验,在用户点击一个链接的时候在新窗口中打开。

    <a href="https://www.baidu.com/" target="_blank">baidu</a>

    安全隐患

    使用该属性来打开新标签或者新窗口时,站点会通过window.opener API给了新页面对原有窗口的访问入口,并授予一些权限,其中window.location是没有被跨域限制拦截的。这可能就存在一个钓鱼的安全隐患。

    解决方法

    尽量不使用 target="_blank",如果一定要用,需要加上 rel="noopener"或者 rel="noreferrer"。这样新窗口的 window.openner就是 null了,而且会让新窗口运行在独立的进程里,不会拖累原来页面的进程。

    <a href="https://www.baidu.com/" target="_blank" rel="noopener">baidu</a>

    或者使用以下可能触发弹出窗口阻止程序的 JavaScript 解决方法:

    var otherWindow = window.open();
    otherWindow.opener = null;
    otherWindow.location = url;
    

    有些浏览器对性能做了优化,即使不加这个属性,新窗口也会在独立进程打开。

    https://mathiasbynens.github.io/rel-noopener/

  • sourceliu
    sourceliu
    前端开发工程师 · 2023-01-03 01:25:05

    专注于开发代码的语言学习模型,比肩chatpt,服务开发人员的瑞士军刀。

    What does Bito’s AI Assistant help with? Ask any technical question
    - Generate Code: Examples: “code in java to convert a number from one base to another”, “code to implement a simple REST API in GO”
    - Command Syntax: “how to set git config variables”, “create an encrypted s3 bucket using the AWS cli”
    - Test Cases: “Generate test cases for this code < insert your code here >"
    - Explain code: “explain this code < insert your code here >”
    - Comment Method: “Explain this code and explain the parameters < insert your code here >”
    - Improve Performance: “how can I improve performance of this code? < insert your code here >”
    - Check Security: “Is this code secure? < insert your code here > ”
    - Explain concepts : "explain B+ trees, give an example with code", “explain banker’s algorithm”
    

    ( 可惜只有英文版

    https://chrome.google.com/webstore/detail/bito-ai-assistant/afchmofckbnlkpnjkdikdkgnjelhlbkg/related?hl=en

  • sourceliu
    sourceliu
    前端开发工程师 · 2023-01-03 01:17:16

    Motion轻松成为前端动画师

    https://chrome.google.com/webstore/detail/motion-devtools/mnbliiaiiflhmnndmoidhddombbmgcdk

  • yinglichen
    yinglichen
    前端开发工程师 · 2022-12-30 10:06:02

    CSS attr() 函数

    CSS 表达式 attr() 用来获取DOM某一属性值,并用于其样式中。

    语法:attr( attribute-name )

    示例:

    image.png

    浏览器支持:

    image.png

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-12-30 08:55:56

    chrome 106版本之后,支持对某个容器的媒体查询:

    .a {
       container-type: inline-size;
    }
    
    .b {
       color: yellow;
    }
    
    @container (min-width: 400px) {
      .b {
         color: blue;
      }
    }
    
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-12-30 08:52:22

    git worktree

    git worktree 可以为同一项目创建多个工作目录,方便分支对比、修bug和插单需求介入,不需要 stash 暂存改动。

    常见场景:

      1. 在业务迭代穿插 bugfix,不需要 stash 当前业务迭代代码,使用 git worktree 开启新的bugfix 工作目录,当 commit 后自动回到业务迭代。
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-12-29 03:44:27

    除了通过eval函数还有另一种方式可以将字符串当初js代码运行 new Function('data','return data')(data) ` 签名第一个是传参,后面的字符串是代码

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-12-13 01:45:04

    Vite 4 公告封面图片https://vitejs.dev/blog/announcing-vite4.html

  • wendylin
    wendylin
    前端开发工程师 · 2022-12-07 10:11:17

    前端缓存

    • 浏览器缓存:localStorage、sessionStorage、cookie等等,功能主要用于缓存需要携带到后端的参数、用户信息、列表数据等等。⚠️:localStorage、sessionStorage这种用户缓存数据的功能,只能存储5M左右的数据,而cookie大概只能有4kb的数据
    • http缓存:官方介绍:“Web 缓存是可以自动保存常见文档副本的 HTTP 设备。当 Web 请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取这 个文档“。通俗的讲,就是服务器不去处理这个http请求,客户端也可以拿到数据。

    「http缓存流程图👇🏻」

    image.png

    http缓存又分为两种两种缓存,强制缓存协商缓存

    • 强制缓存:浏览器判断请求的目标资源有效命中强缓存,如果命中,则可以直接从内存中读取目标资源,无需与服务器做任何通讯。

      基于 Cache-control 的强制缓存:在资源的响应头上写上需要缓存的时间即可,单位是秒,如下:

      image.png

    • 协商缓存:通过服务器来判断缓存是否可用

      Last-Modified:表示这个响应资源的最后修改时间,web服务器在响应请求时,告诉浏览器资源的最后修改时间

      Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识。

      If-None-Match:需要配合Cache-Control使用,当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304

  • violetguo
    violetguo
    前端开发工程师 · 2022-12-05 08:07:47

    判断字符是否为emoji表情的方法

    1.UTF-8 字节流

    UTF-8 的编码中,英文是1个字节,中文是3个字节,emoji一般是4个字节。

    TextEncoder 接受码位流作为输入,并提供 UTF-8 字节流作为输出。

    TextEncoder.encode()接受一个字符串作为输入,返回一个包含 UTF-8 编码的文本的 Uint8Array

    const textEncoder = new 
    TextEncoder()textEncoder.encode('🤔').length //4
    

    2.emoji-regex导入

    emoji-regex提供了一个正则表达式来匹配所有表情符号和序列(包括表情符号的文本表示)符合 Unicode 标准,基于emoji-test-regex-pattern。

    获取完整的首字母字符

    使用slice(0,1)无法完整切割emoji表情,使用Array.from()将其转换为数组则可以获取完成emoji表情

    const str = '🤔1哦哦'
    str.slice(0,1)	//'\uD83E' 
    str.slice(0,2)	//'🤔'
    const arr = Array.from(str) //['🤔', '1', '哦', '哦']
    textEncoder.encode(arr[0]).length	//4
    
  • Shirleychen
    Shirleychen
    前端开发工程师 · 2022-10-20 08:42:34

    监听元素大小、位置变化的方法

    1.ResizeObserver,可以监听Element或SVG边界尺寸的变化

    const resizeOb = new ResizeObserver(entries => {
      for (const entry of entries){
        console.log(entry?.target?.clientWidth)
      }
    })
    resizeOb.observe(document.getElementById('test'))
    

    实例化一个监听器,调用observe方法传入一个要执行监听的DOM元素或SVG元素,每次resizes事件触发时都会执行实例化时传入的回调函数。回调函数第一个参数是被监听元素数组,数组内元素按被监听的顺序排列。

    2.MutationObserver,监听范围更广,会将DOM变化记录为一个MutationRecord对象

  • wendylin
    wendylin
    前端开发工程师 · 2022-10-17 08:22:11

    🌲下一代CSS

    • @container(容器查询):根据组件所在容器的大小添加动态样式
    • Scroll Snap(滚动捕捉):例如scroll-snap-type:x mandatory; (x表示捕捉x轴方向上的滚动,mandatory表示强制将滚动结束后的元素的停留位置到我们规定的地方)
    • object-view-box(对象视图框):属性在一个元素上指定了一个 “视图框”,类似于 <svg viewBox>属性,在元素的内容上进行缩放或平移
    • Scroll Timeline(滚动时间轴):@scroll-timeline能够设定一个动画的开始和结束由滚动容器内的滚动进度决定,而不是由时间决定
  • sourceliu
    sourceliu
    前端开发工程师 · 2022-10-17 07:05:25

    喜闻乐见之Node18亲自操刀

    image.png

    https://nodejs.org/en/blog/release/v18.11.0/

  • perrysong
    perrysong
    前端开发工程师 · 2022-10-14 02:32:21

    okki-galio-cli 快速生成galio项目子应用

    https://www.npmjs.com/package/okki-galio-cli

    安装

        npm install -g okki-galio-cli
        
     or
        yarn global add okki-galio-cli
    

    命令

    • galio --version
    • galio --help
    • galio init <project-name>
  • jielu
    jielu
    前端开发工程师 · 2022-10-13 10:32:05

    webpack5 资源模块

    webpack5新增了资源模块(asset module),允许使用资源文件(字体,图标等)而无需配置额外 loader。资源模块定义了四种类型,用以代替之前的 file-loaderurl-loaderraw-loader

    • asset/resource 代替 file-loader 实现。
    • asset/inline 代替 url-loader 实现。
    • asset/source 代替 raw-loader 实现。
    • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。

    原先 loader 中的选项配置可以使用资源模块相应的配置项代替

    // before
    {
      test: /\.url\.(png|jpe?g|gif|webp)(\?.*)?$/,
      use: [
        /* config.module.rule('images').use('url-loader') */
        {
          loader: 'url-loader',
          options: {
            limit: 4096,
            fallback: {
              loader: 'file-loader',
              options: {
                name: 'static/img/[name].[contenthash:8].[ext]',
    						publicPath: 'https://cfile.xiaoman.cn/${CDN_ENV}/'
              }
            }
          }
        }
      ]
    }
    // after
    {
      test: /\.url\.(png|jpe?g|gif|webp)(\?.*)?$/,   
      type: 'asset',
      generator: {
        filename: 'static/img/[name].[hash:8][ext]'
        publicPath: 'https://cfile.xiaoman.cn/${CDN_ENV}/'
      },
      parser: {
    	  dataUrlCondition: {
    	    maxSize: 4096
    	  }
      }
    }
    

    官方文档: https://webpack.docschina.org/guides/asset-modules/

  • vickwang
    vickwang
    前端开发工程师 · 2022-10-10 10:25:11

    CSS clamp()函数

    clamp()函数的作用是把一个值限制在上限和下限之间

    基本语法:clamp(MIN, VAL, MAX)

    该函数接收三个用逗号分隔的表达式作为参数,按最小值、首选值、最大值排列;当首选值比最小值要小时,则使用最小值,当首选值比最大值要大时,则使用最大值,首选值介于二者之间时,则使用首选值

    有时候,页面的某个区域高度需要根据视口的大小而变化,但是在较大视口上高度不能过高,在较小视口上高度不能过低,这种场景下,使用 clamp()函数是很好的选择

    举个简单的例子:

    width: 100%;
    height: clamp(250px, 50vw, 400px)
    

    WeChat4f23c8144f7cd9028fc6263c25491400.png

  • perrysong
    perrysong
    前端开发工程师 · 2022-10-02 01:48:20

    OkkiTable 组件 空数据时,自定义empty方式

    <OkkiConfigProvider>
      <template 
    renderEmpty>
         <img src=""/>
         <OkkiButton type="primary">
            重新加载
          </OkkiButton>
      </template>
    
      <OkkiTable>
        // ...
      </OkkiTable>
    </OkkiConfigProvider>
    
  • vickwang
    vickwang
    前端开发工程师 · 2022-09-30 10:19:50

    TS内置类型Partial,用于把一个类型的成员属性设为可选模式,其源码定义如下

      type Partial<T> = {
        [P in keyof T]?: T[P]
      }
    

    当使用一个空对象准备接收上传的文件时,会报如下错误

    1664531869668.jpg

    可以选择使用内置的Partial类型解决这个问题

    1664532529783.jpg

    不过Partial无法将更深层的成员属性变为可选模式,可以自定义一个DeepPartial实现深度Partial

      type DeepPartial<T> = {
        [P in keyof T]?: T[P] extends Object ? DeepPartial<T[P]> : T[P]
      }
    
  • perrysong
    perrysong
    前端开发工程师 · 2022-09-30 03:00:08

    npm包 patch-package让开发者可以立即对 npm 依赖项进行修复,而不用通过升级npm 版本或clone npm包等其他操作处理。

    操作步骤:

    1.安装 patch-package

    npm install patch-package --save-dev
    

    2.package.json新增

    scripts: {
      "postinstall": "patch-package"
    }
    

    3.手动修改 node_modules 依赖包中的源码

    4.创建补丁文件

    npx patch-package package-name
    
  • yinglichen
    yinglichen
    前端开发工程师 · 2022-09-29 10:42:47

    Object.fromEntries() 方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@iterator方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。

    常用场景:将数组对象转化为Object,比如以下,将person转化为以name属性值为key,数组对象为value的Object

    image.png

  • junjianlin
    junjianlin
    前端开发工程师 · 2022-09-28 03:12:19

    浏览器打开新标签安全问题

    如果在项目中需要 打开新标签 进行跳转一般会有两种方式:

    window.open

    <a href="..." target="_blank">new tab</a>

    这两种方式看起来没什么问题,但是存在漏洞

    通过这两种方式打开的页面可以使用 window.opener 来访问源页面的 window 对象,场景:

    在自己的系统内通过 <a target="_blank" 标签或 window.open打开第三方网站,第三方网站可以通过 window.opener.location.replace("https://test.evil.com")(跨域仍然有效)将原来的页面替换成钓鱼网站。

    如何防止?

    劫持window.open:

    const openPage = (url) => {
        var newTab = window.open()
        newTab.opener = null
        newTab.location = url
    }
    
    
    <!-- 
      noopener:将 window.opener置空
      noreferrer:兼容老浏览器/火狐。禁用HTTP头部Referer属性(后端方式)
     -->
    <a target="_blank" href="" rel="noopener noreferrer nofollow">a标签跳转url</a>
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-09-26 11:23:30

    proposal-extractors

    proposal-extractors 是一个关于解构能力增强的提案,支持在直接解构时执行自定义逻辑。

    当我们需要对结构的数据进行赋值时加工,就会退化成非解构版本

    
    const [first: firstTemp, second: secondTemp] = arr
    const {name: nameTemp, age: ageTemp} = obj
    const first = someLogic(firstTemp)
    const second = someLogic(secondTemp)
    const name = someLogic(nameTemp)
    const age = someLogic(ageTemp)
    

    proposal-extractors 提案就是用来解决这个问题,希望保持解构语法优雅的同时,加一些额外逻辑:

    const SomeLogic(first, second) = arr // 解构数组
    const SomeLogic{name, age} = obj // 解构对象
    

    SomeLogic 定义:

    const SomeLogic = {
      [Symbol.matcher]: (value) => {
        return { matched: true, value: value.toString() + "特殊处理" };
      },
    };
    
  • vitoliu
    vitoliu
    前端开发工程师 · 2022-09-26 09:49:12

    一图看懂 Typescript 4.9bate 新操作符 satisfies

    image.png

  • vickwang
    vickwang
    前端开发工程师 · 2022-09-23 03:43:18

    OKKI UI upload 组件踩坑记录

    因为OKKI UI是基于 ant design vue 二次封装的,所以OkkiUploader会有与之相同的问题,即使用 FileReader 的readAsBinaryString()、erAsDataUrl()等方法会报错

    报错信息如下:readFailed to execute 'readAsBinaryString' on 'FileReader': parameter 1 is not of type 'Blob'.

    解决方法:使用组件返回的file对象中的originFileObj,因为ant design在上传的原始file对象外面包裹了一层,originFileObj 是原始的文件对象,FileReader可读取其内容

  • robb
    robb
    前端开发工程师 · 2022-09-23 03:33:28

    Via 是一个通用首部,是由代理服务器添加的,适用于正向和反向代理,在请求和响应首部中均可出现。这个消息首部可以用来追踪消息转发情况,常用于查看CDN资源经过了哪些节点,例如:

    image.png

  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-09-23 03:32:34

    TC39新提案:Array.fromAsync

    作用与 Array.from 类似,Array.fromAsync 可以将异步迭代转换为 promise,并将解析为新数组。在 promise 解析之前,它将从输入值中创建一个异步迭代器,进行惰性的迭代,并将每个产生的值添加到新数组中。

    与其他基于 Promise 的 API 一样,Array.fromAsync 总是会立即返回一个 promise。当 Array.fromAsync 的输入在创建其异步或同步迭代器时引发错误时,则此 promise 状态将被置为 rejected。

    示例:

    async function * asyncGen (n) {
      for (let i = 0; i < n; i++)
        yield i * 2;
    }
    
    // arr 将变为 [0, 2, 4, 6]
    const arr = [];
    for await (const v of asyncGen(4)) {
      arr.push(v);
    }
    
    // 与上述方式等价
    const arr = await Array.fromAsync(asyncGen(4))
    
  • perrysong
    perrysong
    前端开发工程师 · 2022-09-22 01:47:31

    for...in 和 for...of 的区别

    • for...in 遍历一个对象的可枚举属性,如对象、数组、字符串。针对属性,所以获得 key
    • for...of 遍历一个可迭代对象,如数组、字符串、Map/Set 。针对一个迭代对象,所以获得 value
  • jielu
    jielu
    前端开发工程师 · 2022-09-09 03:19:31

    零宽字符

    零宽字符是一系列不显示内容也不占用宽度的不可打印的字符

    如 零宽空格(zero-width space, ZWSP)Unicode: \u200B Urlencode: %E2%80%8B

    若前端发送的请求参数重包含了零宽空格,虽然看起来一切正常,后端会因为数据库中无法查询到数据导致无法返回预期的结果

  • harleyhong
    harleyhong
    前端开发工程师 · 2022-08-25 07:32:29

    当事件捕获和事件冒泡一起存在的情况,事件又是如何触发呢。 这里记被点击的DOM节点为target节点

    1. document 往 target节点,捕获前进,遇到注册的捕获事件立即触发执行
    2. 到达target节点,触发事件(对于target节点上,是先捕获还是先冒泡则捕获事件和冒泡事件的注册顺序,先注册先执行)
    3. target节点 往 document 方向,冒泡前进,遇到注册的冒泡事件立即触发
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-08-24 02:38:35

    JavaScript 的 undefined 是一个变量,并非是一个关键字,这是 JavaScript 语言的设计失误。在开发中为了避免被无意篡改,建议使用 void 0 来获取 undefined

  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-08-22 06:36:34

    vscode server——拯救你的散热器

    巨硬在 2019年发布了 Visual Studio Code Remote Development 远程开发插件,能在 vscode 像编辑本地文件一样去编辑远程机器上的代码,并且能将远程机器的终端命令行和监听端口映射到本地。让散热器的寿命 +1s。

    之后巨硬更进一步,发布了 vscode server,支持在远程机器上私有化部署一个 vscode 的 web 服务。得益于 vscode 本身良好的跨平台支持,能让开发者在浏览器里访问自己部署的 vscode 编辑器。

    让开发者随时随地有一个浏览器就可以写代码,能腾出更多时间来喝酒打屁,这波利好茅台。

  • sallyhuang
    sallyhuang
    前端开发工程师 · 2022-08-22 01:14:22

    MouseEvent metaKey 属性

    在MAC键盘上,表示 Command 键(⌘),在Windows键盘上,表示 Windows 键(⊞)

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-08-18 04:55:31

    AbortController 是一个用于终止行为的控制器(实验性功能)。

    • 取消 API 的请求
    function fetchVideo() {
      controller = new AbortController() // 新建一个 controller
      const signal = controller.signal
      fetch(url, { signal }) // 在 fetch 方法传入 signal
        .then(function (response) {
          console.log('Download complete', response)
        })
        .catch(function (e) {
          console.log('Download error: ' + e.message)
        })
    }
    
    abortBtn.addEventListener('click', function () {
      if (controller) controller.abort() // 调用 controller.abort 取消 fetch
      console.log('Download aborted')
    })
    
    • 取消事件监听
    const controller = new AbortController();
    
    downloadBtn.addEventListener('click', fetchVideo);
    abortBtn.addEventListener('click', function() {
      controller.abort();
      console.log('Download aborted');
    });
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-08-16 09:46:49

    chromium 历史版本全家桶

    https://vikyd.github.io/download-chromium-history-version/ /

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-08-11 13:00:52

    一个忽略的点

    svg文件不能以文件路径的形式放置在 img标签的src里面,这样是不会显示出来的

    因为svg的真正链接路径应该是svg里面的 xlink:href的路径,通常是以data:..., base64....开头的地址

  • sallyhuang
    sallyhuang
    前端开发工程师 · 2022-08-10 15:39:54

    Referrer Policy 指令值

    • 空字符串
    • no-referrer
    • no-referrer-when-downgrade
    • same-origin
    • origin
    • strict-origin
    • origin-when-cross-origin
    • strict-origin-when-cross-origin
    • unsafe-url
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-08-10 11:40:06

    npm run xxx 的原理

    • 运行 npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
    • 没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx就是安装到到全局目录;
    • 如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。
    
     unix 系默认的可执行文件,必须输入完整文件名
    vue-cli-service
    
    
     windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件
    vue-cli-service.cmd
    
    
     Windows PowerShell 中可执行文件,可以跨平台
    vue-cli-service.ps1
    
  • yulu
    yulu
    前端开发工程师 · 2022-08-09 05:03:31

    Promise.allSettled 的参数接受一个 Promise 的数组,返回一个新的 Promise。执行完之后不会失败,也就是说当 Promise.allSettled 全部处理完成后,我们可以拿到每个 Promise 的状态,而不管其是否处理成功。

    image.png

    可以看到,Promise.allSettled 最后返回的是一个数组,记录传进来的参数中每个 Promise 的返回值,这就是和 all 方法不太一样的地方。

    适用场景:

    Promise.allSettled: 适用于需要执行多个不依赖于彼此成功完成的异步任务,或者当你总是想知道每个承诺的结果时;

    Promise.all: 适用于任务相互依赖/想在其中任何一个拒绝时立即拒绝。

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-08-03 15:59:34

    Google 推动的 File System Access API,在得到用户授权后,能与用户本地设备上的文件进行交互,可以让 PWA 技术读写本地文件系统。

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-07-28 01:14:17

    Performance insights 网站性能的可行性深度分析

    新的 Performance insights 面板

    https://developer.chrome.com/zh/blog/new-in-devtools-102/ perf

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-07-27 02:32:02

    TypeScript 的 Enums 会生成大量代码,因为在默认情况下,枚举会创建反向映射。通过 const 在 TypeScript 中与 Enums 一起引入关键字,可以减轻大量生成的代码。

    enum Sizes {
      Small,
      Medium,
      Large,
    }
    // 编译后代码
    var Sizes;
    (function (Sizes) {
        Sizes[Sizes["Small"] = 0] = "Small";
        Sizes[Sizes["Medium"] = 1] = "Medium";
        Sizes[Sizes["Large"] = 2] = "Large";
    })(Sizes || (Sizes = {}));
    var size = Sizes.Small;
    
    
    /****  使用 const 声明枚举类型  ****/
    const enum Sizes {
      Small,
      Medium,
      Large,
    }
    const size = Sizes.Small;
    
    // 编译后代码
    var size = 0 /* Small */;
    
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-07-21 11:07:04

    lodash 中判断是不是对象是用 isPlainObject而不是用 isObject isObject底层用的typeof,数组这种也对被判定为对象

  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-07-21 02:40:19

    如何用一行 CSS 实现 10 种现代布局

    1. 超级居中:place-items: center

    2. 解构煎饼式布局:flex: <grow> <shrink> <baseWidth>

    3. 侧边栏布局:grid-template-columns: minmax(<min>, <max>) …)

    4. 煎饼堆栈布局:grid-template-rows: auto 1fr auto

    5. 经典圣杯布局:grid-template: auto 1fr auto / auto 1fr auto

    6. 12 跨网格:grid-template-columns: repeat(12, 1fr)

    7. RAM (Repeat, Auto, MinMax): grid-template-columns(auto-fit, minmax(<base>, 1fr))

    8. 排列布局:justify-content: space-between

    9. 保持我的风格:clamp(<min>, <actual>, <max>)

    10.保持宽高比:aspect-ratio: <width> / <height>

    点击动图示例

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-07-20 01:41:18

    UI 组件化是前端的主流开发模式,由 Google 推动的浏览器原生组件,即 Web Components,支持跨技术栈调用

    Web Components 主要技术部分是:

    • Custom Elements:用于创建自定义标签
    • Shadow DOM:对 DOM 进行封装,能完美做到样式、行为的隔离
    • templates & slot:template 使用模板语法特性书写组件结构;slot 作为组件模板的内容分发插槽,支持自定义渲染(注:Vue 框架的 template、slot 的设计概念源于 Web Components)
  • sourceliu
    sourceliu
    前端开发工程师 · 2022-07-20 01:12:15

    你可以不用 但是不能不知道系列

    近期社区再次火起来的Svelte

    Rollup之父对Vue、React降维打击

    https://github.com/sveltejs/svelte

  • sallyhuang
    sallyhuang
    前端开发工程师 · 2022-07-19 08:55:01

    user-select属性详解

    user-select: none | text | all | element

    none: 文本不能被选择

    text: 可以选择文本

    all: 当所有内容作为一个整体时可以被选择。如果双击或者在 上下文上点击子元素,那么被选择的部分将是以该子元素 向上回溯的最高祖先元素。

    Element: 可以选择文本,但选择范围受元素边界的约束

  • yulu
    yulu
    前端开发工程师 · 2022-07-18 10:05:33

    git revert是用一次新的commit来回滚之前的commit;

    git reset是直接删除指定的commit。

    在回滚这一操作上看,效果差不多。但是在以后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此之后合并老的branch时,导致这部分改变不会再次出现,但是git reset是直接把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。

  • jielu
    jielu
    前端开发工程师 · 2022-07-15 09:29:31

    复制 git 暂存区中的文件到临时目录的脚本

    可用于辅助处理技术栈升级代码同步的工作

    mkdir temp
    // 复制被修改的文件
    git status | grep modified | awk '{print $2}' |  xargs -I % dirname % > temp.txt
    cat temp.txt | xargs -I % mkdir -p ./temp/%
    git status | grep modified | awk '{print $2}' |  xargs -I % cp % ./temp/%
    // 复制新增的文件
    git status | grep 'new file' | awk '{print $3}' |  xargs -I % dirname % > temp.txt
    cat temp.txt | xargs -I % mkdir -p ./temp/%
    git status | grep 'new file' | awk '{print $3}' |  xargs -I % cp % ./temp/%
    
  • Shirleychen
    Shirleychen
    前端开发工程师 · 2022-07-15 04:01:45

    Web端直传文件到OSS

    为什么

    Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传的OSS,跟数据直传相比,缺点如下:

    ①上传慢:OSS采用BGP带宽,能保证各地各运营商之间的传输速度

    ②扩展性差:用户数量多时,应用服务器会成为瓶颈

    ③费用高:需要多台应用服务器,与其同时OSS上行流量免费

    技术方案

    ①利用OSS Browser.js SDK将文件上传到OSS:网络不好时可以断点续传上传大文件。在个别浏览器上有兼容性问题。

    ②利用OSS提供的PostObject接口,通过表单上传的方式将文件上传到OSS。兼容大部分浏览器,但网络不好时,如果单个文件上传失败,只能重试上传。——我们目前用的也是这种。

    ③通过小程序上传到OSS。

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-07-13 04:39:13

    gitboy 这一步一定要设置!

    在最新版的 Git 2.37.0 中,开启如下配置项后就能直接 git push 新分支,不再需要 --set-upstream origin: git config --global --add --bool push.autoSetupRemote true

    image.png

    from: 卡颂

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-07-08 01:49:58

    要想搬砖稳准狠,利其器是关键

    vscode6月版体验,亮眼功能 合并编辑器

    接受合并冲突的双方

    更多查看:https://code.visualstudio.com/updates/v1_69

  • Shirleychen
    Shirleychen
    前端开发工程师 · 2022-07-06 03:33:07

    sass编译器简单介绍

    第一代ruby sass,由于ruby是解释型语言,前端要编译sass需要安装ruby,2019年不再维护。

    第二代node-sass,由c++实现的LibSass和node集成,成为node-sass,开发者可以在Node.js里通过api来编译sass代码。

    但因为node-sass是一个c++模块,所以安装时需要与node版本对应,否则会编译报错。

    2020年node-sass不再支持新特性,并标记为过时。

    第三代dart-sass,官方推荐的sass编译器。dart可以编译为js,所以不需要适配node版本。

  • vitoliu
    vitoliu
    前端开发工程师 · 2022-07-05 03:50:54

    TS 类型体操:根据类型获取引用类型的 key

    type TypeKeys<T extends Record<string, any>, Type> = keyof { [Key in keyof T as T[Key] extends Type ? Key : never]: any }
    

    使用案例:点我在线看

    type MyPlugin = {
      name: string
      onFetch: (res: any, payload: Record<string, any>) => void
      onSelect: (selected: any[]) => void
    }
    // 批量触发 plugin 中的函数 hook
    const runNotify = (key: keyof MyPlugin) => {
      //...
    }
    
    runNotify('name') // 开发时没有错误提示
    
    // 改进版
    const runNotifyPlus = (key: TypeKeys<MyPlugin, Function>) => {
      //...
    }
    
    runNotifyPlus('name') // 报错:Argument of type '"name"' is not assignable to parameter of type '"onFetch" | "onSelect"'.(2345)
    
  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-07-04 09:39:53

    使用CSS 改变任意文字尺寸

    size-adjust 属性用在 @font-face 中,可以自定义字体的时候指定字号大小,仅支持百分比值。

    unicode-range 可以指定哪些字符应用这个自定义字体,支持任意数量的字符,也支持字符范围。任意字符转换成HTML识别格式工具页面

    @font-face {
        font-family: smallYuan;
        src: local('PingFang SC'),
           local("Microsoft Yahei");
        size-adjust: 50%;
        unicode-range: U+5143;
    }
    

    另类字符隐藏方法

    size-adjust 是支持 0%,此时字符会隐藏不可见。这种隐藏会更巧妙,爬虫是不可识别的。

  • solomonguo
    solomonguo
    前端开发工程师 · 2022-07-01 01:25:32

    VSCode Snippets,提高开发效率

    snippets 是片段的意思,VSCode 支持自定义 snippets,写代码的时候可以基于它快速完成一段代码的编写。

    不只是 VSCode,基本所有的主流编辑器都支持 snipeets。

    snippets 基础

    { "alpha": { "prefix": ["a", "z"], "body": [ "abcdefghijklmnopqrstuvwxyz" ], "description": "字母", "scope": "javascript" } }

    • prefix 是触发的前缀,可以指定多个
    • body 是插入到编辑器中的内容,支持很多语法
    • description 是描述
    • scope 是生效的语言,不指定的话就是所有语言都生效

    算是一种 DSL 了,支持很多语法,比如指定光标位置、多光标编辑、placeholder、多选值、变量、对变量做转换等语法。

    • 指定光标位置:$x
    • 多光标编辑:$x $x
    • 指定 placeholder 文本:${x:placeholder}
    • 指定多选值:${x|aaa,bbb|}
    • 取变量:$VariableName
    • 对变量做转换:${VariableName/正则/替换的文本/}
  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-30 08:57:49

    scrollbar-gutter

    scrollbar-gutter 可以让滚动条出现的时候内容不晃动。

    scrollbar-gutter: auto | stable | both-edges
    

    auto就是默认的表现。没有滚动条的时候,内容尽可能占据宽度,有了滚动条,可用宽度减小。

    stable如果 overflow 属性计算值不是 visible,则提前预留好空白区域,这样滚动条出现的时候,整个结构和布局都是稳定的。

    both-edges这个是让左右两侧同时预留好空白区域,目的是让局部绝对居中对称。

  • vitoliu
    vitoliu
    前端开发工程师 · 2022-06-30 06:06:13

    Volar 强大、全面的 Vue 开发神器

    随着 Vue3 一大堆新特性的发布,并且源头上支持了 TS,而 Vetur 备受诟病的 性能、TS 支持已经跟不上 Vue 了,于是基于 @vue/reactivity ,实现一切按需计算,提供原生 TypeScript 语言服务级别的性能对 Volar 这一高性能的 Vue 语言插件孕育而生。

    使用方式也很简单,正常通过 vite 创建 Vue 项目即可。

    除了支持 Vue3 基本的语法高亮、和代码提示, Volar 还具备:

    1. 超级快的 .vue 文件解析
    2. 完备的 TypeScript 提示,哪怕是在 <template> 上。
    3. 右上角的代码分割
    4. <style> 里面的 class 引用
    5. CSS Module 类型提示
    6. lang 语法提示
    7. <template> 语法转换

    让人意外的是,Volar 还支持了 vue2,只需要在 ts.config.json 加上个配置即可。

    (文档上说还需安装 @vue/runtime-dom 和删除 .d.ts,但是效果并不好)

    {
      //...
      "vueCompilerOptions": {
        "target": 2,
      },
    }
    

    此外, Volar 还提供了一些开箱即用的插件,有兴趣的可以了解一下

  • yulu
    yulu
    前端开发工程师 · 2022-06-29 11:54:36

    浏览器提供了原生的 API,可以轻松实现浏览器滚动后不记住滚动位置每次刷新都回到顶部的能力!使用很简单,在页面的任意位置执行下面几行 JS 代码就可以了

    if (history.scrollRestoration) {
      history.scrollRestoration = 'manual';
    }
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-06-29 11:53:48

    Chrome DevTools 小技巧

    Source 面板 = VSCode

    使用 command + p 可以快捷打开指定文件,在有sourcemap 环境下与源码文件对应,可以快捷打断点:

    image.png

  • davoschen
    davoschen
    前端开发工程师 · 2022-06-29 11:44:45

    众所周知,NaN !== NaN。

    const x = NaN;
    x !== x  // true
    

    这是因为 NaN 代表的是一个范围,而不是一个具体的数值。在早期的 isNaN() 函数中,即使传入字符串,也会返回 true ,这个问题已经在 es6 中修复。

    isNaN('abc');       // true
    Number.isNaN('abc') // false
    

    所以如果想兼容旧浏览器,可以用 x !== x 来判断是不是NaN

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-06-29 11:23:34

    vue3 console.log 一个ref等响应值,看到的数据是一层又一层的proxy嵌套,有时候找某个属性很困难,很低效

    教你一个小方法

    打开Chrome 控制台的设置页面,找到console里面的

    enable custom fomatters 打开即可看到console.log的值就很精简了

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-06-28 12:03:44

    npm 包打补丁

    npm 包有错误需要本地 hack 修复, patch-package 最佳实践

    telegramcloudphotosize56181397536510685932x.jpg

    安装

    // 官方推荐同时安装 postinstall-postinstall
    yarn add patch-package postinstall-postinstall
    

    script 添加命令

     "scripts": {
    +  "postinstall": "patch-package"
     }
    

    修改 npm 包

    
    yarn patch-package package-name
    

    引用

    https://www.npmjs.com/package/patch-package

  • ianchen
    ianchen
    前端开发工程师 · 2022-06-28 11:44:51

    yarn.lock 的作用?

    锁定唯一版本!

    • package.json 里定义的是版本区间,如 ^1.0.0
    • 而 yarn.lock 里的 version字段是唯一的版本号,如 1.0.0

    yarn.lock 长啥样?

    "@xiaoman/element-ui@^1.4.9": version "1.4.9" resolved "http://npm.xiaoman.cn/@xiaoman...." integrity sha512-oJ...... dependencies: async-validator "~1.8.1" babel-helper-vue-jsx-merge-props "^2.0.0" deepmerge "^1.2.0" throttle-debounce "^1.0.1"

    各个字段代表的意思?

    version是实际安装的版本

    resolved的是一个链接,是下载这个包的地址

    integrity是对 resolved下载下来的文件进行完整性校验

    dependencies是这个包自己的依赖

  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-28 09:59:17

    scrollbar-color 可以定义滚动条的颜色,语法如下:

    scrollbar-color: auto | 滑杆颜色 轨道颜色;
    

    scrollbar-width 可以设置滚动条的宽度,不过这个宽度不能随意指定,是有约束的,语法如下所示:

    scrollbar-width: auto | thin | none;
    
    • auto 就是默认的尺寸,在 Windows 系统下是 17px;
    • thin 是窄滚动条,在 Windows 系统下是 8px;
    • none 没有滚动条,宽度为0,但是内容依然可以滚动。
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-06-28 03:34:50

    有这么一种情况,我们需要拿某个数组arr的最后一个元素,很平常的做法 => arr[arr.length -1]

    如果arr这个变量名过长那样显得很冗杂

    巧了,es2020新出规范,数组新增一个at方法, 想要拿数组最后一个元素,很简单 => arr.at(-1)

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-06-28 02:05:05

    命令式编程需要明确指出计算机需要完成目标的具体步骤,重点在于如何做

    声明式(函数式)编程就是将现实的事物抽象为程序运算,不关心具体的实现

    例如:从数组中获取所有偶数

    const arr = [1, 2, 3, 4, 5, 6];
    
    // 命令式编程
    const result = [];
    for (let i = 0; i < arr.length; i++) {
      if (arr[i] % 2 === 0) {
        result.push(arr[i]);
      }
    }
    
    // 声明式编程
    const result = arr.filter(item => item % 2 === 0);
    
    
  • yulu
    yulu
    前端开发工程师 · 2022-06-27 12:12:21

    设置了content-visibility: auto 的内容在可视区外将不被渲染,它相比于visibility属性,提升了首次渲染的速度,相比于display属性它又不会影响全局的搜索功能,使用它能提升长列表、长文本页面的渲染性能;

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-06-27 11:54:46

    Resource Timing API

    通过**Resource Timing API**可以获取和分析应用资源加载的详细网络计时数据,应用程序可以使用时间度量标准来确定加载特定资源所需要的时间,比如XMLHttpRequest, <SVG>, 图片,或者脚本。

    Graphic of Resource Timing timestamps

    计算资源加载各阶段的时间

    https://developer.mozilla.org/zh-CN/docs/Web/API/Resource_Timing_API/Using_the_Resource_Timing_API

  • ianchen
    ianchen
    前端开发工程师 · 2022-06-27 10:51:36

    **package-lock.json

    package-lock.json 在 npm 更改 node_modules 目录树 或者 package.json 时自动生成的 ,它准确的描述了当前项目npm包的依赖树,并且在随后的安装中会根据 package-lock.json 来安装,保证是相同的一个依赖树,不考虑这个过程中是否有某个依赖有小版本的更新。

    当 npm install 时,会自动生成一个 package-lock.json 文件,和 package.json 在同一级目录下。package-lock.json 记录了项目的一些信息和所依赖的模块。这样在每次安装都会出现相同的结果。

  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-27 09:00:41

    CSS accent-color属性

    CSS accent-color 属性可以在不改变浏览器默认表单组件基本样式的前提下重置组件的颜色。

    目前支持下面这些 HTML 控件元素:

    复选框:<input type=”checkbox”>

    单选框 <input type=”radio”>

    范围选择框:<input type=”range”>

    进度条:<progress>

    accent-color 属性具有继承性,只需要在对应表单控件元素的祖先元素上设置,响应的控件的颜色就会发生变化。

  • davoschen
    davoschen
    前端开发工程师 · 2022-06-27 03:18:48

    使用按位操作取整:

    let x = 1.23 | 0;  // 1
    

    因为按位操作只支持32位的整型,所以小数点部分全部都被抛弃

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-06-27 03:05:21

    当你需要过滤数组某个不符合条件的元素,并且将每个元素都格式化成想要的数据的时候

    1.先filter后再map(low)

    2.reduce写法 (medium)

    3.flatMap --- 过滤的返回空数组即可 (good)

  • emily
    emily
    前端开发工程师 · 2022-06-24 10:08:00

    $i 直接在控制台安装npm包

    有时候如果想在控制台直接调试 dayjs或者 lodash的某个 API可以通过安装 Console Importer插件

    $i('name') 安装npm包

  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-24 07:08:43

    CSS用户行为三剑客

    • user-select 属性可以设置是否允许用户选择页面中的图文内容。
    • user-modify属性可以设置是否允许输入框输入内容,以及是否只允许输入纯文。
    • user-drag 属性可以设置是否允许页面元素拖拽。
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-06-24 02:54:33

    findLast 提案成功进入到 Stage 4

    提案链接:https://tc39.es/proposal-array-find-from-last/index.html

    这一提案为数组(Array 与 TypedArray)引入了两个新方法 findLastfindLastIndex,来支持从数组的结尾开始查找一个元素,以及它在数组中位于倒数第几项(如 -1、-2)。

    我们知道 JavaScript 中 Array.find 方法会返回第一个符合条件的数组成员,如果我们想做的是获取最后一个符合条件的成员(如多次操作中取最后一次操作),就需要复制一个数组,调用 reverse 方法,然后才能进行搜索:

    [...[]].reverse().find();
    

    这意味着你需要额外创建一个数组并进行操作。

    类似的,Array.findIndex 方法也会返回第一个符合条件的数组成员的索引,如果你希望获得最后一个符合条件成员的索引,也需要进行数组的复制和反转,然后配合数组的长度进行计算:

    const arr = [1, 2, 3, 4];
    
    arr.length - 1 - [...arr].reverse().findIndex(i => i % 2 === 1); // 2
    arr.length - 1 - [...arr].reverse().findIndex(i => i % 2 === 10); // 4,错误
    

    在第二处调用中,由于 findIndex 会在没有找到符合条件成员时返回 -1,此时就需要进行额外的处理。

    基于此提案引入的方法,你可以使用符合直觉的方式来找到最后一个满足条件的成员:

    const arr = [1, 2, 3, 4];
    
    arr.findLast(i => i % 2 === 1); // 3
    arr.findLastIndex(i => i % 2 === 1); // 2
    arr.findLastIndex(i => i % 2 === 10); // -1
    

    目前,我们已经可以在 Chrome 97 中使用这些 API 了。另外,现在也可以通过 core-js 和 es-shims 来使用这两个方法。

  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-06-24 02:51:52

    ES2022 新增 Object.hasOwn() 方法

    2022 年 6 月 22 日,第 123 届 ECMA 大会批准了 ECMAScript 2022 语言规范,其中包含 Object.hasOwn()。

    在ES2022之前,可以使用 Object.prototype.hasOwnProperty() 来检查一个属性是否属于对象。 Object.hasOwn 特性是一种更简洁、更可靠的检查属性是否直接设置在对象上的方法:

    const example = {
      property: '123'
    };
    
    console.log(Object.prototype.hasOwnProperty.call(example, 'property'));
    console.log(Object.hasOwn(example, 'property'));
    

    该特性的浏览器支持如下:

    image.png

  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-22 10:03:58

    v-memo

    记住一个模板的子树。元素和组件上都可以使用。该指令接收一个固定长度的数组作为依赖值进行记忆比对。如果数组中的每个值都和上次渲染的时候相同,则整个该子树的更新会被跳过。例如:

    <ul v-for="member of members" :key="member.id" v-memo="[member.username]">
      <li>{{ member.username }}</li>
    </ul>
    

    当组件重新渲染的时候,如果 member.username 的值维持不变,那么对这个 <ul> 以及它的所有子节点的更新都将被跳过。事实上,即使是虚拟 DOM 的 VNode 创建也将被跳过,因为子树的记忆副本可以被重用。

    正确地声明记忆数组是很重要的,否则某些事实上需要被应用的更新也可能会被跳过。带有空依赖数组的 v-memo (v-memo="[]") 在功能上等效于 v-once

    v-memo 仅供性能敏感场景的针对性优化,会用到的场景应该很少。渲染 v-for 长列表 (长度大于 1000) 可能是它最有用的场景:

    <ul v-for="member of members" :key="member.id"
        v-memo="[member.name, member.id == selectedUser]">
      <li>
        <span :class="{ selected: selectedUser == member.id }">{{ user.name }}</span>
      </li>
    </ul>
    

    v-memo数组中也可以接收 条件判断语句,上面的代码演示中,当组件的 selectedUser 状态发生变化时,即使绝大多数 member 都没有发生任何变化,大量的 VNode 仍将被创建,此处使用的 v-memo 本质上代表着“仅在 member 从未选中变为选中时更新它,反之亦然”

    v-for 中使用 v-memo 时,确保它们被用在了同一个元素上。 v-memov-for 内部是无效的。

  • fengzegui
    fengzegui
    前端开发工程师 · 2022-06-21 11:55:24

    File 文件格式(本地上传)的图片进行预览:

    // 1. URL.createObjectURL()
    // 创建DOMString,返回一个URL,URL和document绑定,表示指定的File对象
    const url = URL.createObjectURL(uploadedFile)
    
    // FileReader.readAsDataURL()
    // 一个FileReader上面的实例方法,读取指定的File对象,
    // 读取完成的时候触发回调,返回URL格式的字符串(base64)
    const fileReader = new FileReader()
    fileReader.readAsDataURL(uploadedFile)
    fileReader.addEventListener('load', () => {
        const url = fileReader.result as string
    })
    

    这两种方式的不同点:

    • 返回值:readAsDataURL可以得到一段base64的字符串。createObjectURL可以得到当前文件的一个内存url。
    • 执行机制:readAsDataURL通过回调的形式返回,异步执行。createObjectURL直接返回,同步执行。
    • 内存清理:readAsDataURL依照js垃圾回收机制自动从内存中清理。createObjectURL存在于当前document内,清除方法只有unload()事件或者revokeObjectURL()手动清除。

    总结:

    • createObjectURL得到本地内存容器的URL地址,同步使用,比较方便快捷,多次使用需要注意手动释放内存的问题,性能优秀。
    • readAsDataURL胜在直接转为base64格式,可以直接用于业务,无需二次转关格式。
  • Ryanzeng
    Ryanzeng
    前端开发工程师 · 2022-06-20 07:36:59

    多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,这就有点大材小用了。所以就有了 $attrs / $listeners ,通常配合 inheritAttrs 一起使用。

    inheritAttrs:默认值为 true。默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrsfalse,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例 property $attrs 可以让这些 attribute 生效,且可以通过 v-bind 显性的绑定到非根元素上。查 看 官 网

    简单的说就是 inheritAttrs:true 继承除props之外的所有属性;inheritAttrs:false 只继承class属性

    $attrs :包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。

    $listeners :包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。

  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-06-20 01:35:27

    GitHub相关域名连接失败的解决方案

    背景:

    我们在安装项目时会用到众多 npm 依赖库,部分库在安装时会从 raw.githubusercontent.com 下载静态资源包。

    而由于众所周知的原因,GitHub 域名会受到不可控的 DNS 污染,导致依赖安装失败。

    解决方案:

    此时我们可以手动配置host,或者使用 Google dns

    手动配置host:

    **手动配置host之前,需要知道相关域名解析的IP地址,此时可访问 **https://ipaddress.com/website 进行查询,

    例如我们通过该网站查询【raw.githubusercontent.com】的 IP,在结果页中找到该域名对应的 IPv4 的地址并添加到本地 host 即可,如下图:

    tips: 如果有多个IP,可在本地使用 ping 命令找到其中最快的一个:

    配置Google dns:

    https://developers.google.cn/speed/public-dns/

    不定时更新 GitHub host 列表

    https://raw.hellogithub.com/hosts

    语雀链接

    GitHub相关域名连接失败的解决方案 · 语雀 (yuque.com)

  • Shirleychen
    Shirleychen
    前端开发工程师 · 2022-06-17 11:38:20

    Tooltip和select等有浮层的组件,可以设置getPopupContainer属性,将浮层渲染到父节点上(默认渲染到 body 上)。

    用法:

    getPopupContainer={triggerNode => triggerNode.parentNode}

    可以用于解决浮层滚动时的定位问题,而不需要修改样式。

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-06-17 07:25:40

    pt 是一个专用的印刷单位“磅”,属于物理长度单位,其大小为 1/72 英寸,称为“绝对长度”。换算公式为: pt = px * 3/4

    px 全称为 pixel,是针对于显示器屏幕分辨率而言的“相对长度”。默认情况下:16px = 1em = 1rem

    em 全称为 font-size of the element,是指相对于父元素的字体大小的单位,也属于“相对长度”。

    rem 全称为 font-size of the root element,是指相对于根元素的字体大小的单位,也属于“相对长度”。

  • fengzegui
    fengzegui
    前端开发工程师 · 2022-06-15 10:35:48

    meta 标签:自动刷新/跳转

    假设要实现一个类似 PPT 自动播放的效果,你很可能会想到使用 JavaScript 定时器控制页面跳转来实现。但其实有更加简洁的实现方法,比如通过 meta 标签来实现:

    <meta http-equiv="Refresh" content="5; URL=page2.html">
    

    上面的代码会在 5s 之后自动跳转到同域下的 page2.html 页面。我们要实现 PPT 自动播放的功能,只需要在每个页面的 meta 标签内设置好下一个页面的地址即可。

    另一种场景,比如每隔一分钟就需要刷新页面的大屏幕监控,也可以通过 meta 标签来实现,只需去掉后面的 URL 即可:

    <meta http-equiv="Refresh" content="60">
    
  • yulu
    yulu
    前端开发工程师 · 2022-06-15 03:20:50

    常用的meta标签:

    charset:用于描述HTML文档的编码形式

    http-equiv:顾名思义,相当于http的文件头作用,比如下面的代码就可以设置http的缓存过期日期

    viewport:移动前端最熟悉不过,Web开发人员可以控制视口的大小和比例

    apple-mobile-web-app-status-bar-style:开发过PWA应用的开发者应该很熟悉,为了自定义评估工具栏的颜色。

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-06-15 02:38:26

    margin和padding设置百分比的时候,百分数是相对于父级宽度的百分比

  • davoschen
    davoschen
    前端开发工程师 · 2022-06-06 02:00:35

    css3实现0.5px的细线

     <style>
        .line {
            position: relative;
        }
        .line:after {
            content: "";
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 1px;
            background-color: #000000;
            -webkit-transform: scaleY(.5);
            transform: scaleY(.5);
        }
    </style>
      
    <div class="line"></div>
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-06-06 01:38:08

    sideEffects

    优化构建体积

    加快构建速度

    sideEffects: boolean | string[]
    

    注意事项

    1. 对于 css 等样式文件需要显性配置

    局限性

    1. sideEffects 配置是以文件为维度的, 只要你配置了文件具备副作用, 即便你只用了该文件中没有副作用的那部分功能, 仍然会将副作用保留
  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-06-02 06:59:27

    理解process.nextTick()

    process.nextTick() 是 Nodejs 异步 API 的一部分,但并不属于事件循环。 process.nextTick() 会在事件循环的每个阶段操作完成后处理,即执行下一个tick--宏任务前,而不管事件循环的当前是哪个阶段 因此在调用回调之前就能拿到所有的变量、函数等。process.nextTick()还具有阻止事件循环继续的优势,适用于在事件循环继续之前,提醒用户有错误发生。

  • solomonguo
    solomonguo
    前端开发工程师 · 2022-05-27 02:18:13

    vue3对于关闭的特性,可以利用 Tree-Shaking 机制摇掉相关代码,使最终打包的资源体积最小化。

    特性开关实现: 本质上是利用rollup.js的预定义常量插件来实现。比如

    { FEATURE_OPTION_API: isBundlerESMBuild ? __VUE_OPITIONS_API__ : true }

    __VUE_OPITIONS_API__ 是个特性开关,通过设置该值来控制是否要包含兼容 vue2 选项API的调用方式

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-05-27 00:50:28

    Chrome 103 测试版于 2022 年 5 月 26 日发布,预计将于 2022 年 6 月下旬成为稳定版。

    关键变化如下:

    沙盒 iframe 中阻止外部协议

    移除元素 <param>

    更多查看:https://developer.chrome.com/en/blog/deps-rems-103/

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-05-24 12:30:57

    『包管理器的管理器』- Corepack

    // 启用
    corepack enable
    
    // package.json
    "packageManager": "pnpm@7.1.5"
    
    // 升级全局版本
    corepack prepare yarn@x.y.z --activate
    
    
  • wendylin
    wendylin
    前端开发工程师 · 2022-05-24 10:05:02

    简单的广告跟踪三步走:

    • 首次访问网站时,通过第三方cookie植入将你标记
    • 浏览网站时,通过植入的cookie不断的向营销平台发送你的浏览足迹(几乎精确到了每一步操作,一个点击,一个停滞都会被记录)
    • 在访问其他社交网站时,会值入相同的第三方cookie将你标记,同时给你推送相关广告
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-22 12:38:51

    HTML页面的生命周期 DOMContentLoaded:浏览器完全加载了HTML,Dom树构建完毕,但是像 <img>和样式表等外部资源可能并未下载完毕

    load:浏览器已加载所有资源

    beforeunload:用户即将离开当前页(刷新或关闭)时触发。正要去服务器读取新的页面时调用,此时还没开始读取

    unload:用户离开页面后触发。已从服务器读取到需要加载的新页面,即将替换当前页面时调用

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-21 08:55:38

    js新出规范--管道运算符 |> 它可以代替我们原先丑陋的嵌套函数的写法,eg. fn1(fn2(x)) 用管道运算符可以写成: x |> fn1 |> fn2

  • yulu
    yulu
    前端开发工程师 · 2022-05-21 08:27:03

    async 和 defer的区别图解

    image.png

  • yulu
    yulu
    前端开发工程师 · 2022-05-21 08:22:52

    HTTP状态码简易分类 1××开头 - 信息提示 2××开头 - 请求成功 3××开头 - 请求被重定向 4××开头 - 请求错误 5××开头 - 服务器错误

  • harleyhong
    harleyhong
    前端开发工程师 · 2022-05-20 06:54:58

    如何理解函数式编程

    函数式编程具有五个鲜明的特点。

    1. 函数是"第一等公民"

    所谓"第一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。

    举例来说,下面代码中的print变量就是一个函数,可以作为另一个函数的参数。

    var print = function(i){ console.log(i);};

    [1,2,3].forEach(print);

    2. 只用"表达式",不用"语句"

    "表达式"(expression)是一个单纯的运算过程,总是有返回值;"语句"(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

    原因是函数式编程的开发动机,一开始就是为了处理运算(computation),不考虑系统的读写(I/O)。"语句"属于对系统的读写操作,所以就被排斥在外。

    当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。

    3. 没有"副作用"

    所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。

    函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

    4. 不修改状态

    上一点已经提到,函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。

    在其他类型的语言中,变量往往用来保存"状态"(state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。下面的代码是一个将字符串逆序排列的函数,它演示了不同的参数如何决定了运算所处的"状态"。

    function reverse(string) {

    if(string.length == 0) {

    return string;

    } else {

    return reverse(string.substring(1, string.length)) + string.substring(0, 1);

    }

    }

    由于使用了递归,函数式语言的运行速度比较慢,这是它长期不能在业界推广的主要原因。

    5. 引用透明

    引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。

    有了前面的第三点和第四点,这点是很显然的。其他类型的语言,函数的返回值往往与系统状态有关,不同的状态之下,返回值是不一样的。这就叫"引用不透明",很不利于观察和理解程序的行为。

  • andyyang
    andyyang
    前端开发工程师 · 2022-05-20 06:42:06

    URLSearchParams定义了一些实用的方法来处理URL的查询字符串。使用它的构造函数会返回一个新的URLSearchParams对象。开头的 ? 字符会被忽略。

    一个简单的hooks用于获取链接query参数

    const useQueryParams = (query: string = null) => {  
        const result: Record<string, string> = {};
        new URLSearchParams(query||window.location.search).forEach((value, key) => {
          result[key] = value;
        });
        return result;
    }
    

    使用

    // http://localhost:3000/?userId=1889&num=112
    const { userId, num } = useQueryParams();
    // OR
    const params = useQueryParams('userId=1889&num=112');
    

    URLSearchParams MDN链接

    react-router-dom

    react-router-dom v6可以使用**useSearchParams **。react router v4/v5没有此hooks.

    const [searchParams, setSearchParams] = useSearchParams();
    searchParams.get("userId")
    
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-18 06:28:55

    竟态问题可以简略描述为:

    由于请求是异步,请求第一个接口后,数据1还没有响应回来,又立马请求了第二个接口,而第二个接口数据2的响应比数据1先得到,这样就有可能导致明明交互触发接口2得到的应该是数据2 却得到接口1的数据1

    解决竟态问题可以利用AbortController接口,AbortController.signal是一个信号源可以用来停止网络请求

  • linalu
    linalu
    前端开发工程师 · 2022-05-16 10:21:09

    节流

    // 使用时间戳
    function throttle(func, wait) {
      let preTime = 0;
    
      return function () {
        let nowTime = +new Date();
        let context = this;
        let args = arguments;
    
        if (nowTime - preTime > wait) {
          func.apply(context, args);
          preTime = nowTime;
        }
      };
    }
    
    // 定时器实现
    function throttle(func, wait) {
      let timeout;
    
      return function () {
        let context = this;
        let args = arguments;
    
        if (!timeout) {
          timeout = setTimeout(function () {
            timeout = null;
            func.apply(context, args);
          }, wait);
        }
      };
    }
    
    
  • linalu
    linalu
    前端开发工程师 · 2022-05-16 10:20:52

    防抖

    function debounce(func, wait, immediate) {
      let timeout;
    
      return function () {
        let context = this;
        let args = arguments;
    
        if (timeout) clearTimeout(timeout);
        if (immediate) {
          let callNow = !timeout;
          timeout = setTimeout(function () {
            timeout = null;
          }, wait);
          if (callNow) func.apply(context, args);
        } else {
          timeout = setTimeout(function () {
            func.apply(context, args);
          }, wait);
        }
      };
    }
    
    
  • linalu
    linalu
    前端开发工程师 · 2022-05-16 10:12:17

    cookie、localStorage、sessionStorage

    1、cookie

    • 本身用于浏览器和 server 通讯。
    • 被“借用”到本地存储来的。
    • 可用 document.cookie = '...' 来修改。

    其缺点:

    • 存储大小限制为 4KB。
    • http 请求时需要发送到服务端,增加请求数量。
    • 只能用 document.cookie = '...' 来修改,太过简陋。

    2、localStorage 和 sessionStorage

    • HTML5 专门为存储来设计的,最大可存 5M。
    • API 简单易用, setItem getItem。
    • 不会随着 http 请求被发送到服务端。

    它们的区别:

    • localStorage 数据会永久存储,除非代码删除或手动删除。
    • sessionStorage 数据只存在于当前会话,浏览器关闭则清空。
  • fengzegui
    fengzegui
    前端开发工程师 · 2022-05-16 05:35:49

    使用 canvas进行上传图片的压缩

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>canvas 压缩图片</title>
    </head>
    <body>
      <input type="file" id="upload">
      <script>
        const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']
        const MAXSIZE = 3 * 1024 * 1024
    
        function convertImageToBase64(file, callback) {
          let render = new FileReader()
          render.addEventListener('load', function(e) {
            // 此时拿到base64的文件
            const base64Image = e.target.result
            callback && callback(base64Image)
            render = null
          })
          render.readAsDataURL(file)
        }
    
        function compress(base64Image, callback) {
          let maxW = 1024
          let maxH = 1024
          const image = new Image()
          image.addEventListener('load', function(e) {
            let ratio // 图片的压缩比
            let needCompress = false // 是否需要压缩
            if (maxW < image.naturalWidth) {
              needCompress = true
              ratio = image.naturalWidth / maxW
              maxH = image.naturalHeight / ratio
            }
            if (maxH < image.naturalHeight) {
              needCompress = true
              ratio = image.naturalHeight / maxH
              maxW = image.naturalWidth / ratio
            }
            if (!needCompress) {
              maxW = image.naturalWidth
              maxH = image.naturalHeight
            }
            const canvas = document.createElement('canvas')
            canvas.setAttribute('id', '__compress__')
            canvas.width = maxW
            canvas.height = maxH
            canvas.style.visibility = 'hidden'
            document.body.appendChild(canvas)
    
            const ctx = canvas.getContext('2d')
            ctx.clearRect(0, 0, maxW, maxH)
            ctx.drawImage(image, 0, 0, maxW, maxH)
            const compressImage = canvas.toDataURL('image/jpeg', 0.8)
            callback && callback(compressImage)
            canvas.remove()
          })
          image.src = base64Image
          document.body.appendChild(image)
        }
    
        const upload = document.getElementById('upload')
        upload.addEventListener('change', function(e) {
          const [file] = e.target.files
          if (!file) {
            return
          }
          const {type: fileType, size: fileSize} = file
          if (!ACCEPT.includes(fileType)) {
            console.log('不支持的文件类型')
            upload.value = ''
            return
          }
          if (fileSize > MAXSIZE) {
            console.log('文件超出大小')
            upload.value = ''
            return
          }
    
          convertImageToBase64(file, (base64Image) => {
            compress(base64Image, (compressImage) => {
              console.log(compressImage)
            })
          })
        })
      </script>
    </body>
    </html>
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-05-16 01:58:40

    在 ES6 之后 Object 的键值对按照自然数、非自然数和 Symbol 进行排序,自然数是按照大小升序进行排序,其他两种都是按照插入的时间顺序进行排序。

  • yulu
    yulu
    前端开发工程师 · 2022-05-16 01:54:32

    globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身)。不像 window 或者 self 这些属性,它确保可以在有无窗口的各种环境下正常工作。所以,你可以安心的使用 globalThis,不必担心它的运行环境。

    需要注意的是,globalThis 虽然好用,在浏览器兼容方面有一些要求(如图),如果对浏览器兼容要求高的,最好写上polyfill。

    image.png

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-15 12:57:15

    vue3中computed会影响性能的原因主要是:

    computed是 lazy惰性的,只会在读取依赖更新时再去重新执行计算

    正是因为是lazy的,所以有些情况下比如一个computed返回的是简单数据结构比如布尔值,由于依赖变了,让computed认为它需要变也就是 dirty的,另一个依赖这个布尔值computed的也被通知要变化,然后去计算这个布尔值的computed

    但其实这个布尔值computed返回的布尔值没有变,这样就会导致页面更新了

    推荐返回布尔值的computed使用vueuse的eagerComputed

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-05-15 12:56:55

    display:none 隐藏对应的元素,其 DOM 结构不会渲染。 visibility:hidden 隐藏对应的元素,但仍保留 DOM 结构。

    主要区别在于:是否会占用空间

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-14 12:52:24

    map与weekmap的区别:

    Map 的键可以是任意类型,WeakMap 只接受对象作为键(null除外)

    Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键; WeakMap 的键是弱引用,键所指向的对象可以被垃圾回收,此时键是无效的

    Map 可以被遍历, WeakMap 不能被遍历

  • Nicolasyan
    Nicolasyan
    前端开发工程师 · 2022-05-13 16:32:45

    web 端图像处理之亮度计算

    核心算法:

    
    void main() {
        gl_FragColor = texture2D(u_image, v_texCoord);
        // 亮度
        if (brightness != 0.0){
            vec3 hsv_color = rgb2hsv(gl_FragColor);// RGB 转 HSV 色彩空间
            if (brightness > 0.0) {
                hsv_color.z *= 1.0 + 1.5 * brightness / 100.0;// 输入值正向范围(0~100)对应饱和度范围为(1~2.5)
            } else if (brightness < 0.0) {
                hsv_color.z *= 1.0 + 0.7 * brightness / 100.0;// 输入值反向范围(-100~0)对应饱和度范围为(0.3~1)
            }
            vec3 rgb_color = hsv2rgb(hsv_color);
            gl_FragColor = vec4(rgb_color.xyz, gl_FragColor.w);
        }
    }
    
    

    查看示例:亮度 | 辣椒炒肉 (yanwei.info)

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-05-13 16:16:21

    回流一定会触发重绘,而重绘不一定会回流

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-05-13 00:33:25

    利用nodejs创造属于自己的加密货币

    https://blog.logrocket.com/build-cryptocurrency-node-js-blockchain/

  • wendylin
    wendylin
    前端开发工程师 · 2022-05-12 10:15:23

    vue-router 在实现单页面前端路由时,提供了 HashHistory 两种模式

    vue2 :根据 mode 参数决定采用哪种方式

    vue3 : 采用 history 参数

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-05-10 13:32:12

    2022 Frontend Developer Roadmap https://roadmap.sh/roadmaps/frontend.png

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-10 09:48:08

    避免大数据number类型丢失精度,造成一定安全性问题----BigInt

    BigInt是一种新的数据类型,用于当整数值大于Number数据类型支持的范围时。

    这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数id,等等,而不需要使用库

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-09 09:33:04

    介绍一个很有趣的javascript特性--jsfuck

    https://www.jianshu.com/p/e7246218f424

  • Holyhe
    Holyhe
    前端开发工程师 · 2022-05-09 03:18:39

    零宽断言在safari浏览器上的兼容问题

    问题:

    代码:
    const reg = /(?<=<)[^>]+/
    
    控制台报错:
    SyntaxError: Invalid regular expression: invalid group specifier name
    

    原因分析:Safari不支持零宽断言

    那什么是零宽断言?

    用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧: 断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。

    正则零宽断言,一共4种 1、(?=xxx) 例:\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分 2、(?<=xxx) 例:(?<=\bre)\w+\b会匹配以re开头的单词的后半部分 3、(?!xxx) 例:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字 4、(?<!xxx) 例:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字

    在我上面所写的正则表达式中,就用到了 零宽断言 :?<=<

    解决:

    修改正则后即可:
     const reg = /<([^<>]*)>/
    
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-05-09 02:41:15
    1. 使用 new 创建对象时,new 运算符做了哪些事?
    • 创建一个新对象
    • 将构造函数的作用域赋给新对象(this 就指向了这个新对象)
    • 执行构造函数中的代码(初始化对象)
    • 返回新对象
  • yulu
    yulu
    前端开发工程师 · 2022-05-09 02:17:19

    浏览器渲染UI过程:

    • 浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree
    • 与此同时,进行CSS解析,生成Style Rules
    • 接着将DOM Tree与Style Rules合成为 Render Tree
    • 接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标
    • 随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来
  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-06 05:43:29

    闭包的变量是存在栈中还是堆中?

    闭包的变量其实存放在堆中的scope中,以此保证闭包变量不会被回收

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-06 03:12:10

    HTTP有哪些⽅法?

    • HTTP1.0定义了三种请求⽅法:GET,POST和HEAD⽅法

    • HTTP1.1新增了五种请求⽅法:OPTIONS,PUT,DELETE,TRACE和CONNECT

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-05-06 03:11:40

    伪类与伪元素的区别

    伪类用于当已有的元素处于某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。

    伪元素用于创建一些不在文档树中的元素,并为其添加样式。它们允许我们为元素的某些部分设置样式。比如说,我们可以通过::before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-05-05 00:46:21

    可视化理解代码块的调用栈,执行上下文

    https://pythontutor.com/visualize.html#mode=edit

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-05-04 03:54:06

    Canvas 和 SVG 的区别:

    • Canvas 是使用 JavaScript 程序绘制动态生成的,SVG 是使用 XML 文档描述来绘图。从这点来看:SVG 更适合用来做动态交互,而且 SVG 绘图更容易编辑,只需要增加或移除相应的元素就可以了。
    • SVG 是基于矢量的,所以它能够很好的处理图形大小的变大。Canvas 是基于位图的图像,他不能改变大小,只能缩放显示
    • Canvas 支持的颜色比 SVG 多
  • yulu
    yulu
    前端开发工程师 · 2022-04-29 01:16:24

    实现不可变数据有三种主流的⽅法:

    • 深克隆,但是深克隆的性能⾮常差,不适合⼤规模使⽤
    • Immutable.js,Immutable.js是⾃成⼀体的⼀套数据结构,性能良好,但是需要学习额外的API
    • immer,利⽤Proxy特性,⽆需学习额外的api,性能良好
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-04-27 05:27:30

    script 标签中 defer 和 async 的区别有:

    • script :会阻碍 HTML 解析,只有下载好并执行完脚本才会继续解析 HTML。

    • async script :解析 HTML 过程中进行脚本的异步下载,下载成功立马执行,有可能会阻断 HTML 的解析。

    • defer script:完全不会阻碍 HTML 的解析,解析完成之后再按照顺序执行脚本。

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-04-27 01:16:54
    1. CSS 盒模型分为: 标准盒模型IE 盒模型。 标准盒模型:只包含 content 。IE 盒模型:content + padding + border ** 。** 可以**通过 <b>box-sizing</b> ** 来改变元素的盒模型: content-box :标准盒模型(默认值);box-sizing: border-box :IE 盒模型。
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-04-26 05:46:05

    async/await 和 Promise 的区别有:

    • async/await 是 Promise 的语法糖
    • async/await 使用同步的写法来执行异步回调
    • 执行 async 函数,返回的一定是 Promise 对象
    • await 相当于 Promise 的 then
    • try...catch 可捕获异常,代替了 Promise 的 catch
  • ininitluo
    ininitluo
    前端开发工程师 · 2022-04-25 06:48:48

    『每日工具』- https://qwerty.kaiyi.cool/

  • xavierluo
    xavierluo
    前端开发工程师 · 2022-04-24 02:44:17

    判断JS 数据类型的方法有:

    • typeof :能准确判断基本类型,函数, 对引用类型(null、对象、数组)不能精确判断,因为都返回 object
    • instanceof:只能判断引用类型 ,其内部运行机制是判断在其原型链中能否找到该类型的原型
    • Object.prototype.toString.call():所有数据类型都是能判断的,还有 Error 对象,Date 对象等
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-04-23 03:15:34

    JavaScript 共有 8 种数据类型,分别为: UndefinedNullBooleanNumberStringObjectSymbolBigInt

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-04-21 01:30:53

    6分钟 幼稚园小朋友也能看到的kafka消息队列。

    https://www.bilibili.com/video/BV1vx411f7hA?spm_id_from=333.337.search-card.all.click

  • sourceliu
    sourceliu
    前端开发工程师 · 2022-04-06 01:14:43

    开发人员的百科全书:

    https://devdocs.io/

  • wendylin
    wendylin
    前端开发工程师 · 2022-03-29 08:14:49

    🍁 HTTP/HTTPS向服务端传递数据的5种基本方式:

    • url param:把参数写在url中;
    • query:通过url中 ? 后面的用 & 分隔的字符串传递数据;
    • form-urlencoded:通过form表单提交数据,和query传递的区别只是放在了body里,指定content-type: application/x-www-form-urlencoded;
    • form-data:通过boundary分割内容,需要指定content-type: multipart/form-data,这种方式适合传输单个/多个文件;
    • json:现在最常用的数据传输方式,通常指定content-type: application/json;
  • vitoliu
    vitoliu
    前端开发工程师 · 2022-03-21 03:49:16

    pnpm 在安装依赖时使用了 Hard Link(硬链接) 机制,该机制和的区别 Symbolic link(软连接)是:

    • 软链类似快捷方式,删除了原文件,快捷方式或软链就无法找到对应的文件了。
    • 硬链接除非将所有原文件、硬链接删除,否则该文件就一直存在,也就不会释放内存。
  • wendylin
    wendylin
    前端开发工程师 · 2022-03-15 06:53:37

    服务端渲染(SSR),其实就是由浏览器做的一些事情,我们放到了服务端去做。

    🍃优缺点:

    优点:首屏渲染快,利于SEO、可以生成缓存片段,生成静态文件、相对客户端渲染而言节能

    缺点:服务端压力较大

  • ininitluo
    ininitluo
    前端开发工程师 · 2022-03-14 02:08:48

    常数枚举只能使用常数枚举表达式并且不同于常规的枚举的是它们在编译阶段会被删除。 常数枚举成员在使用的地方被内联进来。 这是因为常数枚举不可能有计算成员

    const enum Directions {
        Up,
        Down,
        Left,
        Right
    }
    
    let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
    
    

    编译后

    var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
    
  • yulu
    yulu
    前端开发工程师 · 2022-03-12 14:38:06

    实现Comet的手段主要有两个:长轮询和HTTP流。

  • yinanchen
    yinanchen
    前端开发工程师 · 2022-03-12 09:39:07

    vue3组件通信方式有:

    • props,$emit
    • provide,inject
    • vuex,pinia
    • expose,ref
    • 事件总线(eventbus,mitt)
    • 作用域插槽slot
    • getcurrentInstance(不推荐)
  • xavierluo
    xavierluo
    前端开发工程师 · 2022-03-08 06:12:12

    前端离线存储的方案有:

    • localStorage
    • indexDB
    • Application Cache
    • Cache Storage
    • Service Workers
    • WebSQL(已废弃)
  • wendylin
    wendylin
    前端开发工程师 · 2022-03-03 07:48:58

    ts里type和interface的区别?🤔 type:不仅可以用来表示基本类型,还能用来表示对象类型 interface(接口):仅限于描述对象类型😜