javaScript高级汇总

JavaScript高级

day01

1) 从输入url到渲染页面的整个过程
  1. dns解析, 把域名地址解析ip地址
  2. TCP链接: TCP三次握手 ===> 建立连接
    • 客户端发送服务端: 我准备好了, 请你准备一下
    • 服务端发送客户端: 我也准备好了, 请你确认一下
    • 客户端发送服务端: 确认完毕
  3. 发送请求(请求头/请求行/请求体)
    • 将请求报文发送过去
  4. 返回响应(响应头/响应行/响应体)
    • 将响应报文发送过来
  5. 解析渲染页面 (由浏览器内核进行解析)
    • 遇到HTML, 调用HTML解析器(HTML Parser), 解析成DOM树
    • 遇到CSS, 调用CSS解析器, 解析成CSSOM树(样式规则)
    • 遇见js, 调用JS解析器(js引擎), 解析js代码
      • 可能要修改元素节点, 重新调用HTML解析器, 解析更新DOM树
      • 可能要修改样式节点, 重新调用CSS解析器, 解析更新CSSOM树
    • 将DOM + CSSOM = render Tree(渲染树) 合并 形成渲染树
    • layout布局: 计算元素的位置和大小信息
    • render渲染: 将颜色/文字/图片等渲染上去
  6. 断开链接: TCP四次挥手
    • 客户端发送服务端: 请求数据发送完毕, 可以断开了
    • 服务端发送客户端: 请求数据接收完毕, 可以断开了
    • 服务端发送客户端: 响应数据发送完毕, 可以断开了
    • 客户端发送服务端: 响应数据接收完毕, 可以断开了
2) 浏览器的工作原理
  1. 输入服务器的地址之后返回 html文件
  2. 遇见link标签就下载css文件
  3. 遇见script标签就下载 javaScript文件
3) javaScript引擎 (V8引擎)

我们所编写的代码, 由 js引擎 翻译成机器代码, 然后由 CPU 来执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0IYFkhl3-1650093612801)(G:\js高级+vue3\js高级\images\javaScript引擎.png)]

4) V8 引擎的原理

javaScript源代码 ==> 解析(parse) ==> 成AST抽象语法树 ==> Ignition转换成 ==> bytecode字节码 ==> 转换成机器码 运行

day02

1) 执行上下文
var message = "Hello Global"

function foo() {
  console.log(message)    //Hello Global
}

function bar() {
  var message = "Hello Bar"
  foo()
}

bar()

foo() 执行 跟它的定义位置有关系, 跟它调用的位置没有关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tAKuDkxT-1650093612804)(G:\js高级+vue3\js高级\images\函数执行上下文栈.png)]

2) 基本数据类型和引用数据类型的区别(内存管理)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9RDkZtq5-1650093612806)(G:\js高级+vue3\js高级\images\基本数据类型和引用数据类型的区别.png)]

3) 垃圾回收
1. 引用计数法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVQzRl4G-1650093612808)(G:\js高级+vue3\js高级\images\引用计数法.png)]

2. 标记清除法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOsYrIXD-1650093612812)(G:\js高级+vue3\js高级\images\标记清除法.png)]

day03 闭包内存泄漏和this的四个绑定规则

1)闭包
产生闭包的条件: 1.函数嵌套 2.内部函数引用外部函数的局部变量  3.调用函数
闭包的作用:延长局部变量的生命周期 让函数外部操作函数内部的局部变量
闭包的应用举例一下:
	在elementUI中删除列表中某个商品的例子(带确定框)
2) call和apply的区别
function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this)
}

sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])

都会调用函数  apply是传递的数组
3) this 优先级

1.默认规则的优先级最低

  • 毫无疑问,默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this

2.显示绑定优先级高于隐式绑定

3.new绑定优先级高于隐式绑定

4.new绑定优先级高于bind

  • new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
  • new绑定可以和bind一起使用,new绑定优先级更高

new绑定 > 显示绑定(apply/call/bind) > 隐式绑定(obj.foo()) > 默认绑定(独立函数调用)

4) 伪数组转换成真数组
Array.from(arguments)
[...arguments]

day04

1) 面向对象怎么理解
把所用东西放到一个对象里面, 更好的描述一个事物,现实世界描述,面向对象编程
2) 工厂模式(缺点 看不到具体类型 都是Object类型)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1Rt6jKT-1650093612814)(./images/工厂模式.png)]

3) padStart进行填充(ES8)

某些字符串我们需要对其进行前后的填充,来实现某种格式化效果

我们简单具一个应用场景:比如需要对身份证、银行卡的前面位数进行隐藏:

const cardNumber = "321324234242342342341312"
const lastFourCard = cardNumber.slice(-4)
const finalCard = lastFourCard.padStart(cardNumber.length, "*")
console.log(finalCard)   // **************1312
4) 可选链(info.friend?.girlFriend?.name)
const info = {
  name: "why",
  friend: {
     girlFriend: {
       name: "hmm"
     }
  }
}
 console.log(info.friend.girlFriend.name)
 if (info && info.friend && info.friend.girlFriend) {
   console.log(info.friend.girlFriend.name)
 }

// ES11提供了可选链(Optional Chainling)
console.log(info.friend?.girlFriend?.name)

day05

1) Object.defineProperty()的原理
// 新增属性、删除属性Object.defineProperty是无能为力的
    let info = {
      name: "张三",
      age: 18
    }
    Object.keys(info).forEach(item => {
      let value = info[item]
      Object.defineProperty(info, item, {
        get() {
          console.log(`我读取了${item}的value`);
          return value
        },

        set(newValue) {
          console.log(`我修改了${item}的value`);
          value = newValue
        }
      })
    })
2) 浏览器的事件循环

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWnD5d0d-1650093612816)(./images/浏览器事件循环.png)]

js是单线程运行的

js通过事件循环机制来实现对js的单线程异步

异步要基于回调来实现

事件循环机制的2个重要部分

  1. 浏览器其他线程管理模块: 定时器/ajax/dom事件
  2. 保存待执行的回调函数的事件队列(Event queue)/任务队列(Task queue)
比如定时器是异步的,放到浏览器其他线程, 等2秒钟放到事件队列里面, 首先js引擎把前面同步的任务执行完成, 在执行定时器

宏任务和微任务

  1. 先执行 main Script 宏任务
  2. 在依次取出微队列中所有微任务
  3. 在取出宏队列中第一个宏任务执行
  4. 在依次取出微队列中的所有微任务执行
  5. 3, 4 步进行重复执行

day06

Underscore
  • 我们可以理解成lodash是underscore的升级版,它更重量级,功能也更多;
  • 但是目前我看到underscore还在维护,lodash已经很久没有更新了;
1). 防抖(如果频繁触发, 只执行最后一次) 只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数

就是根据定时器来操作, 触发了本次清除上一次的定时器

function debounce(fn, delay) {
  // 1.定义一个定时器, 保存上一次的定时器
  let timer = null

  // 2.真正执行的函数
  const _debounce = function(...args) {
    // 取消上一次的定时器
    if (timer) clearTimeout(timer)
    // 延迟执行
    timer = setTimeout(() => {
      // 外部传入的真正要执行的函数
      fn.apply(this, args)
    }, delay)
  }

  return _debounce
}
2). 节流(有规律的进行触发,比如间隔0.5s来进行操作)

定义两个个变量记录上一次时间,另外一个记录当前操作的时间, 根据这触发的时间, 减去上次的触发的时间; 只有大于等于了才触发下一次

function throttle(fn, interval, options) {
  // 1.记录上一次的开始时间
  let lastTime = 0

  // 2.事件触发时, 真正执行的函数
  const _throttle = function() {

    // 2.1.获取当前事件触发时的时间
    const nowTime = new Date().getTime()

    // 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      // 2.3.真正触发函数
      fn()
      // 2.4.保留上次触发的时间
      lastTime = nowTime
    }
  }

  return _throttle
}
3). rem进行深入理解
function setRem() {
    // 设计稿宽度为1440;屏幕宽度为1440时 1rem == 100px
    const size = document.documentElement.clientWidth * 100 / 1440;
    document.documentElement.style.fontSize = size + "px";
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.onresize = setRem;

day07 ES Module

1) 暴露和导入模式
  1. 分别暴露

    foo.js
    export const name = "张三"
    export const age = 18
    export function foo() {
      console.log("foo")
    }
    
    导入
    import {name, age, foo} from "./foo.js"
    
  2. 统一暴露

    foo.js
    let name = "zhangsan"
    let age = 18
    export {
    	name,
    	age
    }
    
    导入
    import {name, age} from "./foo.js"
    import * as foo from "./foo.js"
    
  3. 默认暴露

    export default {
    	name: "张三",
    	age: 18
    }
    
    导入
    export { default as user } from "./systemConfig/user"; 
    

day08

定时器的缺陷
1.定时器最大的优点,同时也是它最容易出错的一点:定时器所有任务都是由同一个线程来调度。

正是因此,定时器简单易用。同时这也导致了定时器所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务,即定时器的重叠。

2.定时器不会被自动销毁,即它所占内存无法被自动回收。如果不手动清除定时器,它会一直占用内存资源。更可怕的是,一旦使用定时器进行轮询,定时器所占的内存资源将会不断上升,若与定时器重叠问题一起出现,常导致页面卡顿。

所以,我们必须学会清除定时器。

{ default as user } from “./systemConfig/user”;




### day08

#### 定时器的缺陷

1.定时器最大的优点,同时也是它最容易出错的一点:定时器所有任务都是由同一个线程来调度。

正是因此,定时器简单易用。同时这也导致了定时器所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务,即定时器的重叠。

2.定时器不会被自动销毁,即它所占内存无法被自动回收。如果不手动清除定时器,它会一直占用内存资源。更可怕的是,一旦使用定时器进行轮询,定时器所占的内存资源将会不断上升,若与定时器重叠问题一起出现,常导致页面卡顿。

所以,我们必须学会清除定时器。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值