• 面试-interview100


    Ajax Fetch axios

    三者都是用于网络请求,但是不同维度

    • ajax是一个技术统称(用某个技术实现网络请求就是ajax) 当web1.0的时候只能是读报,2.0就是ajax可以交互 评论
    • ajax

    ajax: Asynchronous Javascript and XML
    
        用javascript异步形式去操作XML
    ajax流程步骤:
    
    
    第一步:
    
        var xhr = XMLHttpRequest();//这是个api
    
         //  创建一个ajax对象,标准浏览器下。
    
            ie6以下,ActiveXObject('Microsoft.XMLHTTP');
    
            用异常错误处理机制来解决对象兼容问题。
    
    
    第二步:
    
        xhr.open('get','1.txt',true);
    
        //open方法参数:
    
            1,打开方式
    
                get问题:
        
                    1,缓存:必须关闭浏览器再打开才刷新,
            
                    解决方法给url后面给一个现在时间或者随机数就解决问题
    
                    2,乱码,编码encodeURI
    
                post问题:
    
                    1,post方式,数据放在send(username=betrs&age=21)方法里面作为参数传递
    
                    2,post方式没有缓存问题
    
            2,地址
    
            3,是否异步
    
                true异步:非阻塞,前面的代码不会影响后面的代码的执行
    
                false同步:阻塞,前面的代码会影响后面的代码的执行
    
    
    设置请求头:
    
        POST : 方式传递数据时要设置请求头
    
        xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
    
        //声明发送数据的编码类型
    
    
    
    第三步:
    
        xhr.send();
    
        //提交,发送请求
        
    
    第四步:
    
        xhr.onreadystatechange= function(){
    
        //等待服务器返回内容
    
            if(xhr.readystate == 4){
    
                if(xhr.status == 200){
                    
                    alert(xhr.responseText);
                
                }else{
    
                    alert('出错了,Error:'+xhr.status);
                };
                
            };
        };
        
        onreadystatechange:当readystate的状态值改变的时候触发
    
        readystate: ajax工作状态,该属性一共有四个值
    
            0:(初始化)还没有调用open()方法
    
            1:(载入)以调用send()方法,正在发送请求
    
            2:(载入完成)send()方法完成,已收到全部响应内容
    
            3:(解析)正在解析响应内容
    
            4:(完成)响应内容解析完成,可以在客户端调用了
    
        status:服务器状态,http状态码
    
        responseText: ajax请求返回的内容就被存放到这个属性下面,   内容是字符串
    
        responseXML:返回XML形式内容
    
    当用responseText 获取到数据后,前端显示的是字符串,需要转成数组,方法如下:
    function ajax1(url, successFn) {
                const xhr = new XMLHttpRequest()
                xhr.open("GET", url, false)
                xhr.onreadystatechange = function () {
                    // 这里的函数异步执行,可参考之前 JS 基础中的异步模块
                    if (xhr.readyState == 4) {
                        if (xhr.status == 200) {
                            successFn(xhr.responseText)
                        }
                    }
                }
                xhr.send(null)
    }
    
    • 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
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    fetch

    • fetch 一个具体api 这个之前是 XMLHttpRequest 更加简洁,易用,支持promise
    function ajax2(url) {//使用fetch Api实现ajax
                return fetch(url).then(res => res.json())
    }
    
    • 1
    • 2
    • 3

    axios

    是一个请求的第三方库

    axios是通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样。

    简单来说: ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装。

    axios是ajax ajax不止axios。

    jq的ajax

    $.ajax({
    
        url:"jq.php", //连接服务器
        
        type:"POST", //传输方式
        
        async:false,
    
        dataType:'json',
    
        data:{username:"hello"},//传送数据
    
        success:function(data){ //执行回调函数
    
            alert(data);
        }error:function(error){
            
            console.log(error);
            
        };
        
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    // 异常错误处理机制

    try{
        //代码尝试执行这个块中的内容,如果有错误,则会执行catch{},并且
            传入错误信息参数    
    
    }catch(e){
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    //表单数据的提交

    action:数据提交的地址,默认是当前页面
    
    method:数据提交的方式,默认是get方式
    
        1,get
            把数据名称和数据值用=连接,如果有多个的话,那么他会把
    
            多个数据组合用&进行连接,然后把数据放到url?后面,传到指定页面。
    
            url长度限制的原因,我们不要通过get方式传递过多的数据
        
        2,post       
               enctype:提交的数据格式,默认application/x-www-form-urlencoded
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    parse :可以把字符串转换成对应的对象

    stringify :可以把一个对象转换成对应的字符串

    节流与防抖

    防抖和节流?防抖和节流大概的思路?用在什么地方?
    防抖
    在这里插入图片描述

    你先抖动着啥时候 停止了 在执行下一步
    一个搜索输入框,等输入停止之后,再触发搜索,不停的话是不会搜索

     <p>debounce</p>
    搜索 <input id="input1">
        
        <script>
            function debounce(fn, delay = 200) {
                let timer = 0//触发函数记录
             //返回一个函数
                return function () {
                //连续触发就一直清除之前的timer,不是连续触发了 最后一个再执行  看图
                // 点第2个的时候 第一个这个setTimeout 还没执行
                    if (timer) clearTimeout(timer)
                    //每次触发函数都会有个记录
                    timer = setTimeout(() => {
                        fn.apply(this, arguments) // 透传 this 和参数
                        timer = 0//还原0
                    }, delay)
                }
            }
    
            const input1 = document.getElementById('input1')
            input1.addEventListener('keyup', debounce(() => {
                console.log('发起搜索', input1.value)
            }), 300)
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    节流
    在这里插入图片描述

    <p>throttle</p>
        <div id="div1" draggable="true" style="width: 100px; height: 50px; background-color: #ccc; padding: 10px;">
            可拖拽
        </div>
    
        <script>
            function throttle(fn, delay = 100) {
                let timer = 0
    
                return function () {
                    if (timer) return
    
                    timer = setTimeout(() => {
                        fn.apply(this, arguments)
                        timer = 0
                    }, delay)
                }
            }
    
            const div1 = document.getElementById('div1')
            div1.addEventListener('drag', throttle((e) => {
                console.log('鼠标的位置', e.offsetX, e.offsetY)
            }))
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    rem em vw vh

    em

    相对于当前字体的大小;

    rem

    根据响应式匹配 适配手机屏幕
    不同的手机像素下可以设置html{font-size:110px;}根元素的字体大小

    vw vh

    vw 屏幕宽度1%
    vh 屏幕高度1%

    什么不能使用箭头函数

    对象方法

    对象原型

    构造函数

    动态上下文回调函数

    vue 生命周期 methods

    请描述TCP三次握手与四次挥手

    • 先建立连接
    • 再传输内容
    • 网络连接是tcp协议,传输内容是HTTP协议

    tcp连接3次握手

    比喻:第一次问张三在不在家;第二次张三说我在家;第三次我跟张三说你等着我马上过去;这时候张三才会等着你;

    • client发包,server接受.Server:有Client要找我---------------1.SYN---------->
    • Server发包,Client接受;Client:Server已经收到信息了<-----------------2.SYN+ACK-----------
    • client发包,server接受.Server:Client要准备发送了----------------3.ACK--------------------->

    中间连接建立,数据传输;

    四次挥手-关闭连接
    比喻:告诉张三我没有东西了;张三告诉我说好的我知道了;张三把手头活搞完了告诉我说我这传输好了;我说好的我这边接受完毕了,可以了关闭了;

    • client 发包,Server接受: server:Client请求结束-----FIN------------>
    • server发包,Client接收; client:Server收到,我等它关闭;<-------------2.ACK------------
    • Server发包,client接收; Client:Server此时可以关闭连接了;<----------------FIN-------------
    • client发包,Serve接收;Server:可以关闭了----------------------ACK------>

    for of 与 for in 的区别

    for of 遍历value for in 遍历index key

           const arr = [10, 20, 30]
            for (let val of arr) {
               console.log(val)// 10 20 30
            }
    
            const str = 'abc'
    	       for (let c of str) {
    	             console.log(c)// abc
    	       }
    //遍历参数
             function fn() {
                 for (let arg of arguments) {
                    console.log(arg)
                }
            }
            // fn(100, 200, 'aaa')
     
    //遍历DOM节点
             const pList = document.querySelectorAll('p')
            for (let p of pList) {
                console.log(p)
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    for…in 与 for…of 区别

    适用与不同数据类型
    遍历对象:for…in可以,for…of不可以
    遍历Map Set :for…of可以 for…in不可以
    遍历generator:for…of可以,for…in不可以

             const obj = {
                name: '双越',
                city: '北京'
            }
            for (let val of obj) {
                console.log(val) // 错误的
            }
    
      const set = new Set([10, 20, 30])
         for (let n of set) {
             console.log(n)
       }
       const map = new Map([
                ['x', 100],
                ['y', 200],
                ['z', 300]
            ])
            for (let n of map) {
                console.log(n)
            }
    
            function* foo() {
                yield 10
                yield 20
                yield 30
            }
            for (let n of foo()) {
                console.log(n)
            }
    
    • 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

    for…in

    用于可枚举enumrable数据,如对象,数组,字符串;得到key

    for…of

    用于可迭代Iterator数据,如数组,字符串,Map,Set ;得到Value
    Iterator里面有next()方法

    for…await…of

      function createPromise(val) {
                return new Promise((resolve) => {
                    setTimeout(() => {
                        resolve(val)
                    }, 1000)
                })
    }
    
            (async function () {
            // 这一开始全部调用的话 不会延迟执行
                const p1 = createPromise(100)
                const p2 = createPromise(200)
                const p3 = createPromise(300)
    
                const res1 = await p1
                console.log(res1)
                const res2 = await p2
                console.log(res2)
                const res3 = await p3
                console.log(res3)
    
                const list = [p1, p2, p3]
                // Promise.all(list).then(res => console.log(res))
                for await (let res of list) {
                    console.log(res)
                }
    
                // ---------------------- 分割线 ----------------------
    //延迟调用 1s后打印100 2s后打印200  3s后打印300 
                 const res1 = await createPromise(100)
                // console.log(res1)
                const res2 = await createPromise(200)
                // console.log(res2)
                 const res3 = await createPromise(300)
                // console.log(res3)
    
                const arr = [10, 20, 30]
                 for (let num of arr) {
                  const res = await createPromise(num)
                     console.log(res)
                 }
            })()
    -------------------
    const sleep = (timeountMS) =>
          new Promise((resolve) => {
            setTimeout(resolve, timeountMS);
          });
    async function () {
       await sleep(1000)
       //1s后执行
       $("#orderStatus").text("门票打印完成");
    }
    
    
    
    • 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
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    offsetHeight-offsetWidth

    -clientWidth-clientHeight

    -scrollWidth-scrollHeight

      #container {
                width: 300px;
                height: 200px;
                padding: 20px;
                margin: 30px;
                border: 5px solid #ccc;
                box-sizing: border-box;
                overflow: auto;
                background-color: #fff;
            }
       const container = document.getElementById('container')
           //padding+content+border
            console.log('offsetHeight', container.offsetHeight)//200
            console.log('offsetWidth', container.offsetWidth)//300
            
            //padding+content
            console.log('clientWidth', container.clientWidth)//290
            console.log('clientHeight', container.clientHeight)//190
            
            //padding+实际内容尺寸
            console.log('scrollWidth', container.scrollWidth)//290
            console.log('scrollHeight', container.scrollHeight)//190      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    HTMLCollection和Nodelist有什么区别?

    Node和Element

    DOM是一棵树,所有节点是Node;

    Node是Element的基类
    node

          <p id="p1"><b>node</b> vs <em>element</em><!--注释--></p>
    
            const p1 = document.getElementById('p1')
         
            //Text(node vs ) Comment (<!--注释-->)不归element管
            console.log(p1.children instanceof HTMLCollection)//true
            console.log(p1.children instanceof NodeList)// false      
            console.log(p1.childNodes instanceof NodeList )//true
    
            p1.children {0:b,1:em}
    
            p1.childNodes{0:b,1:text,2:em,3:comment}
    
    
            class Node {}
    
            // document
            class Document extends Node {}
            class DocumentFragment extends Node {}
            
            // 文本和注释
            class CharacterData extends Node {}
            class Comment extends CharacterData {}
            class Text extends CharacterData {}
    
            // elem
            class Element extends Node {}
            class HTMLElement extends Element {}
            class HTMLDivElement extends HTMLElement {}
            class HTMLInputElement extends HTMLElement {}
           
    
    • 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
    • 获取Node 和Element 的返回结果可能不一样

    • 如elem.childNodes和elem.children不一样

    • 前者会包含Text 和Comment节点,后者不会

    扩展:类数组->数组

    const arr1=Array.from(list);

    const arr2=Array.prototype.slice.call(list);

    const arr3=[…list]

    computed 与 watch

    • computed 用于计算产生新的数据

    • watch 用于监听现有的数据

    *computed 有缓存 methods 没有缓存

    计算属性默认仅能通过计算函数得出结果。当你尝试修改一个计算属性时,
    你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的
    属性,你可以通过同时提供 getter 和 setter 来创建:
    export default {
      data() {
        return {
          firstName: 'John',
          lastName: 'Doe'
        }
      },
      computed: {
        fullName: {
          // getter
          get() {
            return this.firstName + ' ' + this.lastName
          },
          // setter
          set(newValue) {
            // 注意:我们这里使用的是解构赋值语法
            [this.firstName, this.lastName] = newValue.split(' ')
          }
        }
      }
    }
    现在当你再运行 this.fullName = 'John Doe' 时,setter 会被调用而 this.firstName 和 this.lastName 会随之更新。
    
    • 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

    vue 组件通讯的方式

    • prop 和$emit
    • 自定义事件
    • $attr
    • $parent
    • $refs
    • provide/inject
    • Vuex
      ---------------------------prop–emit
      vue3
      子组件
    emits:['showMsg']
    methods:{
       clickHandle(){
           this.$emit('showMsg','hello word')
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    -----------------------自定义事件

    Vue2 :new Vue()=>event  on off event
    
    Vue3  引入第三方自定义事件 event-emitter
    
    • 1
    • 2
    • 3

    ---------------------------$attrs 透传
    类似多个参数 $props

    <template>
        <p>Level1</p>
        <Level2
            :a="a"
            :b="b"
            :c="c"
            @getA="getA" 
            @getB="getB"
            @getC="getC"
        ></Level2>
    </template>
    
    <template>
        <p>Level2</p>
        <Level3
            :x="x"
            :y="y"
            :z="z"
            @getX="getX"
            @getY="getY"
            @getZ="getZ"
            v-bind="$attrs"  //把level1的abc@getA @getB @getC 都塞给了C 
        ></Level3>
    </template>
    
    <template>
        <p>Level3</p>//当只有 一个标签的时候 会继承属性 a b c inheritAttrs: false, 如果有Helloword 就不用写了
        <HelloWorld msg="hello 双越" ref="hello1"/>
    </template>
    
    
    • 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

    ----------------------------$parent

    this. p a r e n t 获 取 父 组 件 t h i s . parent获取父组件 this. parentthis.refs 获取子组件

    直接调用父级的方法

    this.$parent.getX()

    直接调用子组件的方法

    console.log(this.$refs.hello1.name)

    ----------------------------provide/inject

    多层级传递

    --------------level1
    provide: {
         info: 'aaa'
    }
    ---------------level3
    <template>
        <p>Level3 {{info}}</p>
    </template>
    
    <script>
    export default {
        name: 'Level3',
        inject: ['info']
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    vuex mutation action的区别

    • mutation: 原子操作,必须同步代码;
    • action:可包含多个mutation;可包含异步代码;

    js严格模式有什么特点

    开启严格模式
    ‘use strict’ //全局开启
    function fn(){
    ‘use strict’ //某个函数开启
    }

    • 全局变量必须先声明
    • 禁止使用with
    • 创建eval 作用域
    • 禁止this指向window
    • 函数参数不能重名
    ------------------全局变量必须声明
    n=10
    ---------------------禁止使用with
    const obj={x:100,y:200}
    with(obj){
            console.log(x,y)
    }
    ------------------创建eval 作用域
    var x=20;
    eval(`var x=30;console.log(x)`)//30
    console.log(x)//20
    
    -----------------禁止this指向window
    fn()
    function fn(){
      console.log(this)//严格模式是未定义  
    }
    -------------- 函数参数不能重名
    function fn(a,a,c){}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    http跨域请求时 为何发送option请求

    • 浏览器的同源策略
    • 同源策略一般限制Ajax网络请求,不能跨域请求server
    • 不会限制

    JSONP :

    a网页 通过 script 请求b网页 b网页直接通过字符串 返回a网页当js去执行
    在这里插入图片描述

    CORS

    服务端设置
    在这里插入图片描述

    option

    • option请求,是跨域请求之前的预检查
    • 浏览器自行发起,无需我们干涉
    • 不会影响实际功能

    先看看支持哪些请求方式

    垃圾回收

    什么是垃圾回收? 标记清除,从window根开始遍历,找到保留,找不到清除

    //执行完之后 会回收
    function fn(){
        const a="aa"
    }
    fn()
    //全局引用的 不会被回收
     function fn2() {
                const obj = { x: 100 }
                window.obj = obj
    }
    fn2()
    
    function getDataFns() {
    //只要这个 data在外面有应用 就不会销毁
                const data = {} // 闭包
                return {
                    get(key) {
                        return data[key]
                    },
                    set(key, value) {
                        data[key] = value
                    }
                }
            }
            const { get, set } = getDataFns()
            set('x', 100)
            get('x')
    
    • 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

    闭包是内存泄漏吗?

    不是;只有非预期情况是泄漏;闭包是预期的;

    闭包数据不能被垃圾回收,

    vue 内存泄漏场景

    • 被全局变量,函数引用,组件销毁时未清除
    • 被全局时间,定时器引用,组件销毁时未清除
    • 被自定义事件引用,组件销毁时未清除
    <script>
    export default {
      name: 'Memory Leak Demo',
      data() {
        return {
          arr: [10, 20, 30], // 数组 对象
        }
      },
      methods: {
        printArr() {
            console.log(this.arr)
        }
      },
      mounted() {
          window.addEventListener('resize', this.printArr)
          // 自定义事件也是这样
      },
      // Vue2 - beforeDestroy
      beforeUnmount() {
          window.removeEventListener('resize', this.printArr)
      },
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    WeaMap

         const wMap = new WeaMap() // 弱引用
            function fn1() {
                const obj = { x: 100 }// weakMap引用一定会销毁
                wMap.set(obj, 100) // weakMap 的 key 只能是引用类型
            }
        fn1()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    浏览器和nodejs的时间内循环有什么区别?

    浏览器循环

    • js是单线程(无论在浏览器还是node.js)
    • 浏览器中Js执行和DOM渲染共用一个线程(可以理解成一个人干2件事)
    • 异步(宏任务与微任务)
    宏任务 ,setTimeout setInterval网络请求
    微任务,如promise  async/await
    微任务在下一轮DOM渲染之前执行,宏任务在之后执行
    console.log('start')//1
            setTimeout(() => {
                console.log('timeout')//4
            })
            Promise.resolve().then(() => {
                console.log('promise then')//3
            })
     console.log('end')//2
     -----------微任务 渲染页面之前触发  宏任务是页面之后触发
       const p = document.createElement('p')
            p.innerHTML = 'new paragraph'
            document.body.appendChild(p)
            const list = document.getElementsByTagName('p')
            console.log('length----', list.length)
    
            console.log('start')
            // 渲染之后
            setTimeout(() => {
                const list = document.getElementsByTagName('p')
                console.log('length on timeout----', list.length) // 2
                alert('阻塞 timeout')
            })
            // 渲染之前
            Promise.resolve().then(() => {
                const list = document.getElementsByTagName('p')
                console.log('length on promise.then----', list.length) // 2
                alert('阻塞 promise')
            })
            console.log('end')
    
    • 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

    单线程和异步(异步是单线程的解决方案)
    在这里插入图片描述

     console.log('start')
            setTimeout(() => {
                console.log('timeout')
            },1000)
            Promise.resolve().then(() => {
                console.log('promise then')
            })
            console.log('end')
    
            // ajax(url, fn) // 300ms
    
            // Event Loop 继续监听... 如果ajax300ms之后响应,那就是300ms之后加入宏任务;
            
            //setimeout 1000ms之后 是1000ms放入宏任务 
             
            // 宏任务 MarcoTask Queue
            // () => {
            //     console.log('timeout')
            // }
            // fn
    
            //js是单线程 所以是 先同步-->微任务--->DOM渲染-->宏任务
            // DOM 渲染
    
            // 微任务 MicroTask Queue
            // () => {
            //     console.log('promise then')
            // }
    
    • 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

    nodejs异步

    • Nodejs同样使用ES语法,也是单线程,也需要异步;
    • 异步任务也分:宏任务+微任务
    • 它的宏任务和微任务,分不同类型,也有不同优先级
    console.info('start')
    setImmediate(() => {//宏任务
        console.info('setImmediate')4
    })
    setTimeout(() => {
        console.info('timeout')3
    })
    Promise.resolve().then(() => {
        console.info('promise then')2
    })
    // process.nextTick(() => {
    //     console.info('nextTick')//1
    // })
    console.info('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    数据驱动视图

    • props,data的数据变化,会生成虚拟vDOM,vNode
    • ,然后通过diff比较vNode与oldVnode
    • 更新DOM

    for foreach

    在这里插入图片描述

    o(n) 时间复杂度
           const arr = []
            for (let i = 0; i < 100 * 10000; i++) {
                arr.push(i)
            }
            const length = arr.length
    
            console.time('for')
            let n1 = 0
            for (let i = 0; i < length; i++) {
                n1++
            }
            console.timeEnd('for') // 3.7ms
    
            console.time('forEach')
            let n2 = 0
            arr.forEach(() => n2++)
            console.timeEnd('forEach') // 15.1ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    请用一句话概括RESTFUL?

    是一种web服务的架构风格。
    看 Url 就知道要什么
    看 http method 就知道干什么
    看 http status code 就知道结果如何

    Vue2+Webpack+ES6 兼容低版本浏览器(IE9)解决方案

    解决方式:安装 “babel-polyfill” 即可。

    命令:npm install --save-dev babel-polyfill

    在入口main.js文件引入:import ‘babel-polyfill’

    最后一步,在build文件夹下找到webpack.base.conf.js.修改入口方式:

    entry: {
    app: [“babel-polyfill”, “./src/main.js”]
    }

    最后,再依赖一个插件解决ES6/ES7高级语法兼容
    npm install --save-dev babel-preset-es2015-ie

    如果根目录下缺少文件.babelrc,新建一个,如下:
    {
    “presets”: [

    [“env”, {
    “modules”: false,
    “targets”: {
    “browsers”: [“> 1%”, “last 2 versions”, “not ie <= 8”]
    }
    }],
    “stage-2”
    ],
    “plugins”: [“transform-runtime”],
    “env”: {
    “test”: {
    “presets”: [“env”, “stage-2”],
    “plugins”: [“istanbul”]
    }
    }

  • 相关阅读:
    opencv用自适应直方图均衡化函数cv2.createCLAHE()提高对比度
    Navicat只导出数据,不导出表结构方法
    python高级面试题
    C语言实例|使用C程序优雅地杀掉其它程序进程
    Rust6.1 Writing Automated Tests
    大数据:Shell的操作(2)
    Hbase数据库安装部署
    EPLAN学习笔记1:连接定义点和电位定义点
    CDN工作原理
    系统架构设计师学习笔记——企业信息化战略与实施_重点备忘录
  • 原文地址:https://blog.csdn.net/weixin_50402587/article/details/124891773