浏览器的作用是什么,浏览器有什么用

首页 > 经验 > 作者:YD1662022-10-26 07:36:22

第二步,执行到addAll调用时,生成addAll函数的执行上下文,压入上下文,并执行addAll函数内部的可执行代码

浏览器的作用是什么,浏览器有什么用(5)

第三步,执行到add 函数调用,生成add 函数的执行上下文,压入调用栈

浏览器的作用是什么,浏览器有什么用(6)

执行上下文栈.png

执行add 函数内部的可执行代码,return 结果,然后add函数执行上下文销毁,弹出调用栈

第四部,执行addAll后续可执行代码,return 结果,addAll函数上下文销毁,弹出调用栈,最后只剩下全局执行上下文,伴随页面整个生命周期

问题: 栈溢出(递归函数)

(三)作用域、作用域链、闭包1. 作用域:是指变量和函数可以被访问的范围

var 、 let、const的区别:

  1. var:
    -- 在javascript解析时, 声明和初始化提升,声明之前访问不报错,值为undefined;
    -- 存放在执行上下文中的变量环境中
    -- 可以多次声明同一个变量,后一个值会覆盖之前的值;
    -- 不支持块级作用域
  2. let :
    -- 用来声明一个变量,在解析时,声明会提升,但是初始化不会提升,声明之前访问报错;
    -- 存放在执行上下中的词法环境中
    -- 同一作用域内不能多次声明;
    -- 支持块级作用域
  3. const :
    -- 用来声明一个常量,不能再次修改
    --声明会提升,但是初始化不会提升,声明之前访问报错;
    -- 存放在执行上下中的词法环境中
    -- 同一作用域内不能多次声明;
    -- 支持块级作用域

function foo(){ var a = 1 let b = 2 { let b = 3 var c = 4 let d = 5 console.log(a); //1 console.log(b); //3 } console.log(b) ;//2 console.log(c); //4 console.log(d); //报错:d is not defined } foo()2. 作用域链:变量查找沿着各作用域一层层向外部引用指向的执行上下文查找,形成一个链条,即作用域链条

函数的作用域由词法作用域决定
词法作用域:是指作用域是函数声明的位置来决定的,和函数怎么调用无关

3. 闭包:

当函数执行完毕时,函数体内的定义的变量会随着函数执行上下文立即销毁,但是当外部函数包含内部函数,且内部函数使用了外部函数中定义的变量,这些变量就不会销毁,仍然保存在内存,这些变量和内部函数就形成了闭包

闭包的形成条件:

  1. 外部函数里有内部函数
  2. 内部函数中使用了外部函数中定义的变量

function foo() { var myName = "小白"; var age = 18; function sayHello(){ console.log (`你好,我的名字是:${myName},今年${age}`) } return sayHello; } let hello = foo(); hello() // myName和age就是foo函数的闭包

问题:内存泄露( 该回收的内存未被及时回收 )

(四)Javascrip的垃圾回收机制1. Javascript的内存机制2. Javascript的垃圾回收机制

数据被使用之后,不再需要了,就称为垃圾数据,垃圾数据要及时销毁,释放内存空间,否则会内存泄漏。

(1)栈内存回收

当Javascript代码执行时,记录当前执行状态的指针(称为 ESP),指向当前执行上下文的指针,当前函数代码之前完毕,指针下移指向下一个要执行的函数执行上下文,当前执行上下文弹出调用栈进行销毁,这个过程就是该函数栈内存回收的过程

function foo(){ var a = 1 var b = {name:"极客邦"} function showName(){ var c = 2 var d = {name:"极客时间"} } showName() } foo()

浏览器的作用是什么,浏览器有什么用(7)

调用栈.png

(2)堆内存回收
垃圾回收器:

第一步,标记堆内存中活动对象和非活动对象

第二步,回收非活动数据所占据的内存
在所有的标记完成之后,统一清理内存中所有被标记为可回收的对象

第三步,做内存整理

(五)浏览器的事件循环机制

每个渲染进程都有一个主线程,处理以下事件:

消息队列和循环机制保证了页面有条不紊地运行

1. 任务队列:是一种数据结构,用来放要执行的任务,先进先出

同步任务:直接进入主线程执行的任务,只有前一个任务执行完毕,才能执行后一个任务
异步任务:以回调函数实现,先在其他的任务队列中排队,等待同步任务执行完成,该任务才会进入主线程执行,分为宏任务、微任务

宏任务队列:宏任务执行队列,回调函数里要执行的任务

微任务队列:JavaScript 执行一段脚本,V8 引擎会首先创建一个全局执行上下文,同时也会创建一个专为V8 引擎内部使用的微任务队列

(1)宏任务:宿主环境即浏览器分配的任务

宏任务 主要有以下几种:

  1. setInterval、setTimeout
    -- setTimeout回调函数的真正执行时间>=设定时间,原因是受消息队列中其他任务执行时间的影响
  2. XMLHttpRequest
(2)微任务:JavaScript 引擎发起的任务,执行时机为当前宏任务结束之前

Javascript脚本执行本身就也是一个宏任务,宏任务中又包含同步任务、微任务、宏任务

console.log(1); setTimeout(()=>{ console.log(3); Promise.resolve(4).then((data) => { console.log(data) }) setTimeout(() =>{ console.log(5) },0) }, 0) Promise.resolve(2).then((data) => { console.log(data) }) //执行结果:1, 2, 3,5

微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列
微任务早于宏任务执行
微任务的执行时长会影响到当前宏任务的时长

微任务主要有:

  1. MotutaionObserver
  2. Promise
    (1) Promise的三种状态
    pending(待执行状态)、fulfilled(执行成功状态)、rejected(执行失败状态)

(2)执行过状态不可逆,不会再变
要么pending ->fulfilled
要么pending -> rejected

(3)Promise实现原理:
- 回调函数延迟绑定(微任务)
- 回调函数返回值穿透,then回调函数中的返回值,可以穿透到最外层
- 错误“冒泡”,通过链式调用then、catch,不论在哪一层出错,都会“冒泡”至catch

//封装一个函数,简单模拟promise function MyPomise(executor) { let _this = this; let _onResolve = null; this.then = function (onResolve) { _onResolve = onResolve; } this.resolve = function (value) { //此处用setTimeout模拟延迟绑定回调任务,也是微任务出现的原因 setTimeout(() => { _onResolve(value) }, 0) } executor(this.resolve, this.reject); } let demo = new MyPomise((resolve, reject) => { resolve(200) }) demo.then((data) => { console.log(data) })

(4)Promise.resolve(value):返回一个以给定值解析后的Promise对象

Promise.resolve(value)方法的参数分成四种情况:

-- 参数是一个 Promise对象的实例 ,直接返回这个 实例

-- 参数是一个thenable对象(即带有then方法),Promise.resolve()返回的是一个执行then方法之后的Promise对象,并且采用执行之后的状态

let thenable = { then: function(resolve, reject) { resolve(200) } } let p1 = Promise.resolve(thenable); //200,因为p1已经是fulfilled状态,因此直接then,可以获取到返回值 p1.then((data) => { console.log(data) })

-- 参数是一个普通值或对象,则直接返回新的 Promise 对象,状态为fulfilled(值为参数本身)

-- 参数为空,直接返回一个fulfilled状态的 Promise 对象,(值为undefined)

(5)链式调用时,
then回调函数执行成功,返回的是一个fulfilled状态的promise,会进入后面的then
then执行失败,返回的是一个rejected的promise,会进入后面的catch
catch回调函数执行成功,返回的也是一个fulfilled状态的promise,进入后面的then
catch执行失败,返回的是一个rejected的promise,进入后面的catch

  1. async/await

async function foo() { console.log(1); let a = await 100; // await之后的代码相当于then函数里的代码 console.log(a); console.log(2); } console.log(0); foo(); console.log(3); //执行顺序:0,1,3,100,2

浏览器的作用是什么,浏览器有什么用(8)

上一页123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.