美文网首页
程序员的日常记录

程序员的日常记录

作者: 9ac64e1f7a99 | 来源:发表于2018-10-06 19:51 被阅读90次
(👍 赞) (⚡ 重要)(⭐ 我的博客文章)(💎 待理解)
  • 💎

  • 2018.10.06

    • 什么是事件循环
      • 所有任务都在主线程上执行,形成一个执行栈(ecs)
      • 主线程之外还存在一个任务队列(task queue),系统把异步任务放到任务队列中,然后主线程继续执行后续的任务
      • 当 ECS 中的所有任务执行完毕,系统就会读取任务队列,如果这个时候,异步任务已经结束了等待状态,将回调函数推入任务队列,就会从任务队列进入执行栈,恢复执行
  • 2018.10.05

  • 2018.10.04

    • 尾调用及其优化
      • 尾调用(Tail Call):某个函数的最后一步是调用另一个函数(调用之后不能再赋值,不能再进行运算)
      • 调用栈:函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数 A 的内部调用函数 B,那么在 A 的调用帧上方,还会形成一个 B 的调用帧。等到 B 结束,将结果返回到 AB 的调用帧才会消失。如果函数 B 内部还调用函数 C ,那就还有一个 C 的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。
      • 尾调用优化
        • 如果所有的函数都是尾调用,那么完全可以做到每次执行时调用帧只有一项,这将大大节省内存
        • 尾调用由于是函数的最后一步操作,不需要保留外层函数的调用帧,因为调用位置、内部变量等信息不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了
        • 注意:只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”
    • 阮一峰ES6 函数的扩展篇
      • 函数的 length 属性,表示预期传入的参数个数,某个参数指定默认值以后,预期传入的参数个数就不包含这个参数了(只计入默认值之前的参数个数),rest 参数也不计算在内
      • 箭头函数
        • 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象(在箭头函数中,this 是固定的,不会变化)。this 指向的固定化,并不是因为箭头函数有绑定 this 的机制,实际原因是箭头函数根本没有自己的 this,导致内部的 this 就是外层代码块的 this
        • 正式因为它没有 this,所以也就不能当做构造函数,即不能使用 new 命令,否则会报错
        • supernew.targetarguments 在箭头函数中是不存在的(指向外层函数的对应变量)
          • super keyword unexpected here
          • new.target expression is not allowed here
            function foo() {
              setTimeout(() => {
                console.log('args:', arguments);
              }, 100);
            }
            
            foo(2, 4, 6, 8)
            // 指向了外层函数的对应属性
            // args: [2, 4, 6, 8]
            
        • 不可以使用 arguments 对象,该对象在函数体内不存在。可使用 rest 替代
        • 不可以使用 yield 命令,即箭头函数不能当做 Generator 函数
        • 不适用箭头函数的场景
          • 定义函数的方法
            // 调用 cat.jumps() ,如果是普通函数,则正常执行
            // 但是箭头函数默认固定为创建的时候的 this(全局对象),会报错
            const cat = {
              lives: 9,
              jumps: () => {
                this.lives--;
              }
            }
            
          • DOM 中添加事件监听,动态绑定 this
            button.addEventListener('click', () => {
              // 这个 this 并没有指向 button 本身
              this.classList.toggle('on');
            });
            
    • 斐波拉契数列
      • js 尾调用实现
        function fibonacci(n, prev = 1, next = 1) {
            if (n <= 2) return next;
            return  fibonacci(n - 1, next, prev + next);
        }
        
      • 循环实现
        function fibonacci1(n) {
        
            if (n <= 2) return 1;
            var arr  = [1, 1];
            var temp;
            for(var i = 2; i < n; i++){
                temp = arr[0];
                arr[0] = arr[1];
                arr[1] = arr[1] + temp;
            }
            
            return arr[1];
        }
        
    • 事件冒泡、事件捕捉、事件委托(事件代理)
      • 事件捕捉是指从 document 一直到触发事件的那个节点,事件冒泡则相反,指的是触发事件的节点到 document
      • js中的事件委托或是事件代理详解
      • e.stopPropagation 可以阻止事件冒泡或者事件捕捉
      • 事件委托能减少由于大量绑定事件带来的性能损耗,同时对新加入的结点不需要额外绑定事件
      • 事件委托基于事件冒泡,所以不支持冒泡的事件无法进行委托
      • addEventListener('click', func, bool) addEventListener 的第三个参数,默认为false,表示使用冒泡,true表示事件捕捉
  • 2018.10.03

    • 页面重排与重绘(Reflow & Repaint)
      intro
      • reflow(重排):当涉及到 DOM 节点的布局属性发生变化时,就会重新计算该属性,浏览器会重新描绘相应的元素
      • repaint(重绘):当影响 DOM 元素可见性的属性发生变化(color、visibility等),浏览器会重新描绘相应的元素。重排必然会引起重绘
        - 浏览器渲染的大致流程:
        1. 渲染 HTML 文档,构建 DOM 树
        2. 解析 CSS 属性,构建 CSSOM 树
        3. 结合 DOM 树和 CSSOM 树,构建 render 树
        4. 在 render 树的基础上布局,计算每个节点的几何结构
        5. 把每个节点绘制在屏幕上
      • 一个页面可以简单的看成由两部分构成
        • DOM 节点,描述页面的结构
        • DOM 节点的属性,描述 DOM 节点如何呈现
      • reflow 发生在第4步, repaint 发生在第5步
      • 如何减少reflow、repaint
        • 避免 js 逐条更改样式,使用 className
        • 避免频繁操作 dom ,创建 documentFragment 或 div,在它上面应用 DOM 操作之后,添加到文档中
        • 在设置为 display: none 的元素上操作,最后显示出来
        • 避免频繁读取元素集合属性(scrollTop等)
        • 绝对定位具有复杂动画的元素。使其脱离文档流,避免引起父元素及其后续元素大量重排
    • 对 DOM 树进行深度优先和广度优先遍历
    • querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?
      • w3c 标准:querySelectorAll 属于 W3C 中的 Selectors API 规范,而 getElementsBy* 系列则是属于 W3C DOM 规范
      • 接收参数: querySelectorAll 接收的参数是一个 CSS 选择符(必须严格符合 CSS 选择器命名规范,否则会抛出异常 DOMException),getElementsBy* 的参数只能是单一的 className、tagName、name、id
      • 返回值:querySelectorAll 返回的是一个 Static Node List(页面 DOM 变动不会影响之前已经获取到的返回值),getElementsBy* 返回的是 Live Node List(之前的返回值会受到页面的 DOM 变动影响)
      • chrome 中的效果
        • document.querySelectorAll('a').toString(); // return "[object NodeList]"
        • document.getElementsByTagName('a').toString(); // return "[object HTMLCollection]"
        • Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
      • HTMLCollection 是属于 Document Object Model HTML 规范,而 NodeList 属于 Document Object Model Core 规范。
            var ul = document.getElementsByTagName('ul')[0],
                lis1 = ul.childNodes,
                lis2 = ul.children;
            console.log(lis1.toString(), lis1.length);    // "[object NodeList]" 11
            console.log(lis2.toString(), lis2.length);    // "[object HTMLCollection]" 4
        
        
      • NodeList 对象会包含文档中的所有节点,如 Element、Text 和 Comment 等。
      • HTMLCollection 对象只会包含文档中的 Element 节点。

相关文章

网友评论

      本文标题:程序员的日常记录

      本文链接:https://www.haomeiwen.com/subject/brohaftx.html