• 面经总结 (一)


    输出题

    console.log(a)
    function a (){ }
    var a = 1
    console.log(a);
    答案:function a(){}
     1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    原因:函数提升优于变量提升,但函数和var重名,只留函数。因此第一个a是function 后来a覆盖掉了function 因此 第二个console是1

      const obj = {}
      console.log(obj?.a)
      undefined
    
    • 1
    • 2
    • 3

    css方面

    新的伪类选择器

    函数式伪类选择器

    :has () 如果作为参数传递的任何选择器(相对于给定元素的:范围)至少匹配一个元素,则:has() CSS伪类表示一个元素。

    仅匹配<a>的亲儿子img:
    a:has(> img)
    
    • 1
    • 2

    :not()CSS伪类表示与选择器列表不匹配的元素。由于它阻止选择特定项目,因此它被称为否定伪类。

    :not
    p:not(.irrelevant) {
        font-weight: bold;
    }
    
    • 1
    • 2
    • 3
    • 4

    flex

    flex1

    实际上是flex-grow、flex-shrink和flex-basis三个属性的缩写。它相当于flex: 1 1 0。

    flex-grow 若被赋值为一个正整数, flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的可用空间(available space)。如果有其他元素也被允许延展,那么他们会各自占据可用空间的一部分。如果我们给元素设定 flex-grow 值为 1,容器中的可用空间会被这些元素平分。它们会延展以填满容器主轴方向上的空间。flex-grow 属性可以按比例分配空间。如果第一个元素 flex-grow 值为 2,其他元素值为 1,则第一个元素将占有 2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有 1/4(各 50px)。

    flex-shrink属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间,那么可以把 flex 元素flex-shrink属性设置为正整数来缩小它所占空间到flex-basis以下。与flex-grow属性一样,可以赋予不同的值来控制 flex 元素收缩的程度 —— 给flex-shrink属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。

    flex-basis 定义了该元素的空间大小(the size of that item in terms of the space)属性定义了在分配多余空间之前,项目占据的主轴空间。flex 容器里除了元素所占的空间以外的富余空间就是可用空间 available space。 该属性的默认值是 auto 。此时,浏览器会检测这个元素是否具有确定的尺寸。所有元素都设定了宽度(width)为 100px,所以 flex-basis 的值为 100px。如果没有给元素设定尺寸,flex-basis 的值采用元素内容的尺寸。这就解释了:我们给只要给 Flex 元素的父元素声明 display: flex ,所有子元素就会排成一行,且自动分配小大以充分展示元素的内容。 当一个元素同时被设置了 flex-basis (除值为 auto 外) 和 width (或者在 flex-direction: column 情况下设置了height) , flex-basis 具有更高的优先级。

    flex交叉轴

    align-items和align-self属性控制我们的弹性项目在交叉轴上的对齐方式,如果是,则沿列向下对齐,如果是flex-direction,则沿row行对齐。flex-directioncolumn
    我们在最简单的 flex 示例中使用了交叉轴对齐。如果我们添加display: flex到一个容器中,子项都变成了排列成一排的弹性项。它们都将拉伸到与最高项目一样高,因为该项目定义了交叉轴上项目的高度。如果您的 flex 容器设置了高度,那么无论项目中有多少内容,项目都会拉伸到该高度。

    类型转换

    [] == false
    true
    
    • 1
    • 2

    原因:隐士转换为调用原型tostring方法,空数组toString之后值为空字符串,再由空字符串和false比较

    不使用promise.all,并保证失败状态也正确返回实现并行下载

            const p1 = new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('p1')
                }, 1000);
            })
            const p2 = new Promise((resolve,reject)=>{
                setTimeout(() => {
                    reject('errorp2')
                }, 1000);
            })
            const p3 = new Promise((resolve,reject)=>{
                setTimeout(() => {
                    resolve('p3')
                }, 1000);
            })
         
            class promise{
                resArr = []
                index = 0
                promiseArr = []
                cb = null
                constructor(...args){
                    this.cb = args.shift()
                    this.promiseArr.push(...args)
                    this.run()
                }
                run(){
                    this.promiseArr.forEach(pro=>{
                        pro.then(res=>{
                            this.resArr.push(res)
                            this.returnRes()
                        }).catch(res=>{
                            this.returnRes()
                            this.resArr.push(res)
                        })
                    })
                }
                returnRes(){
                    ++this.index
                    if(this.index === this.promiseArr.length){
                            this.cb(this.resArr)
                    }
                }
            }
            const p = new promise(function(res){
                console.log(res);
            },p1,p2,p3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    webpack

    webpack分块 SplitChunks插件 已经内置该插件。
    Webpack 将根据这些条件自动拆分块:

    可以共享新块或模块来自node_modules文件夹
    新块将大于 20kb(在 min+gz 之前)
    按需加载块时的最大并行请求数将低于或等于 30
    初始页面加载时的最大并行请求数将低于或等于 30

    nextTick

    为什么v-if + nextTick才能刷新页面
    而直接this.xxx = false this.xxx=true 就无法重新刷新组件,
    原因是如果直接this.xxx = false this.xxx = true vue会把这两次数据更新进行合并,并不会立即就重新渲染页面,而用了this.nextTick,vue会将this.xxx = false后放入队列中去执行,然后页面就会渲染v-if的值变为false了然后最后执行nextTick里的回调,因此必须用nextTick

    迭代器迭代协议

    在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。

    迭代协议

    可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 for…of 结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如 Array 或者 Map,而其他内置类型则不是(比如 Object))。

    要成为可迭代对象, 一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性:

    属性
    [Symbol.iterator]一个无参数的函数,其返回值为一个符合迭代器协议的对象。

    当一个对象需要被迭代的时候(比如被置入一个 for…of 循环时),首先,会不带参数调用它的 @@iterator 方法,然后使用此方法返回的迭代器获得要迭代的值。

        const obj = {
            name:'asd',
            age:1243,
            job:'前端开发'
        }
        let index = 0
        obj[Symbol.iterator] = function() {
            const obj = this
            const values = Object.values(obj)
            return { // 只返回一次元素,字符串 "bye",的迭代器对象
                next: function() {
                    if(index <= values.length-2){
                        return{
                            value:values[index++],
                            done:false
                        }
                    }else{
                        return{
                            value:values[index],
                            done:true
                        }
                    }
                },
            };
        };
        const iterator =  obj[Symbol.iterator]()
        console.log(iterator.next())
        console.log(iterator.next())
        console.log(iterator.next())
    输出结果:{value: 'asd', done: false}
    {value: 1243, done: false}
    {value: '前端开发', done: true}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    模块

    esm和coomenjs规范区别
    CommonJS使用exports导出模块,require导入模块

    具体规范如下:

    1. ESM输出的是值的引用,而CJS输出的是值的拷贝
    2. CJS的输出是运行时加载,而ESM是编译时输出接口;
    3. cjs可以当作表达式使用 esm必须放在当前文件夹的顶层
  • 相关阅读:
    Codeforces Round #832 (Div. 2)
    springboot自动扫描添加的BeanDefinition源码解析
    Springboot处理Long类型传给前端导致精度丢失问题
    Java 网站开发入门指南:如何用java写一个网站
    eclipse如何安装server
    认识nginx
    反转单链表
    wireshark打开tcpdump抓的包 vwr: Invalid data length runs past the end of the record
    JavaEE 初阶篇-深入了解网络通信相关的基本概念(三次握手建立连接、四次挥手断开连接)
    AAPT: error: resource android:attr/lStar not found
  • 原文地址:https://blog.csdn.net/m0_47195133/article/details/126936434