贵州建设厅网站,dede网站站内推广方法,wordpress主题no.7,金华品牌网站建设思维导图
本文为反复学习极客时间-《浏览器的工作原理与实践》-浏览器中的 JavaScript 执行机制章节中的一些思考与记录。 一些重要概念
变量提升
所谓的变量提升#xff0c;是指在 JavaScript 代码执行过程中#xff0c;JavaScript 引擎把变量的声明部分和函数的声明部分…思维导图
本文为反复学习极客时间-《浏览器的工作原理与实践》-浏览器中的 JavaScript 执行机制章节中的一些思考与记录。 一些重要概念
变量提升
所谓的变量提升是指在 JavaScript 代码执行过程中JavaScript 引擎把变量的声明部分和函数的声明部分提升到代码开头的“行为”。变量被提升后会给变量设置默认值这个默认值就是我们熟悉的 undefined。从概念的字面意义上来看“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面正如我们所模拟的那样。但这并不准确。实际上变量和函数声明在代码里的位置是不会改变的而且是在编译阶段被 JavaScript 引擎放入内存中。
执行上下文
分类
全局执行上下文函数执行上下文eval 执行上下文
调用栈
调用栈就是用来管理函数调用关系的一种数据结构在执行上下文创建好后 JavaScript 引擎会将执行上下文压入栈中通常把这种用来管理执行上下文的栈称为执行上下文栈又称调用栈
作用域 Scope
定义作用域是指在程序中定义变量的区域该位置决定了变量的生命周期。通俗地理解作用域就是变量与函数的可访问范围即作用域控制着变量和函数的可见性和生命周期。
分类-ES6 之前
全局作用域。全局作用域中的对象在代码中的任何地方都能访问其生命周期伴随着页面的生命周期。函数作用域。函数作用域就是在函数内部定义的变量或者函数并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后函数内部定义的变量会被销毁。
ES6 新增
块级作用域let/const
作用域链
在每个执行上下文的变量环境中都包含了一个外部引用用来指向外部的执行上下文我们把这个外部引用称为outer。当一段代码使用了一个变量时JavaScript 引擎首先会在“当前的执行上下文”中查找该变量如果在当前的变量环境中没有查找到那么 JavaScript 引擎会继续在 outer 所指向的执行上下文中查找把这个查找的链条就称为作用域链在 JavaScript 执行过程中其作用域链是由词法作用域决定的
词法作用域
指作用域是由代码中函数声明的位置来决定的词法作用域是静态的作用域通过它就能够预测代码在执行过程中如何查找标识符。词法作用域是代码阶段就决定好的和函数是怎么调用的没有关系
闭包
在 JavaScript 中根据词法作用域的规则内部函数总是可以访问其外部函数中声明的变量当通过调用一个外部函数返回一个内部函数后即使该外部函数已经执行结束了但是内部函数引用外部函数的变量依然保存在内存中我们就把这些变量的集合称为闭包。比如外部函数是 foo那么这些变量的集合就称为 foo 函数的闭包。
闭包是怎么回收的
如果引用闭包的函数是一个全局变量那么闭包会一直存在直到页面关闭但如果这个闭包以后不再使用的话就会造成内存泄漏如果引用闭包的函数是个局部变量等函数销毁后在下次 JavaScript 引擎执行垃圾回收时判断闭包这块内容如果已经不再被使用了那么 JavaScript 引擎的垃圾回收器就会回收这块内存。原则—如果该闭包会一直使用那么它可以作为全局变量而存在但如果使用频率不高而且占用内存又比较大的话那就尽量让它成为一个局部变量。
this
首先明确作用域链和 this 是两套不同的系统它们之间基本没太多联系
分类
1.全局执行上下文中的 this指向 window 对象 2.函数执行上下文中的 this
通过函数的 call/apply/bind 方法设置this 指向 call/apply/bind 方法中的第一个参数通过对象调用方法设置this 指向对象本身通过构造函数中设置this 指向 new 的实例对象
3.eval 中的 this
this 的设计缺陷以及应对方案
1.嵌套函数中的 this 不会从外层函数中继承
在函数中声明一个变量 self 用来保存 this使用 ES6 中的箭头函数这是因为 ES6 中的箭头函数并不会创建其自身的执行上下文所以箭头函数中的 this 取决于它的外部函数
2.普通函数中的 this 默认指向全局对象 window
如果要让函数执行上下文中的 this 指向某个对象最好的方式是通过 call 方法来显示调用。通过设置 JavaScript 的“严格模式”在严格模式下默认执行一个函数其函数的执行上下文中的 this 值是 undefined 下文对闭包和 this 做一些补充介绍。
闭包
1.闭包是什么
按照 MDN-closure 的描述 MDN-Closure 函数和对其周围状态lexical environment词法环境的引用捆绑在一起构成闭包closure。 也就是说闭包可以让你从内部函数访问外部函数作用域。 在 JavaScript 中每当函数被创建就会在函数生成时生成闭包。 2.闭包的常见产生方式
(1).函数作为返回值被返回
function create() {let a 100;return function() {console.log(a)}
}
let func create();
let a 200;
func(); (2).函数作为参数
function print(fn) {let b 200;fn();
}
let b 100;function fn() {console.log(b);
}
print(fn); (3).在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers或者任何异步中只要使用了回调函数实际上就是在使用闭包。
场景题
说明以下代码输出的结果,并解释原因
for (var i 1; i 5; i) {setTimeout(function timer() {console.log(i);}, i * 1000);
} 输出结果 6 6 6 6 6
原因 这里涉及到 JS 中 eventLoop 机制, 简单来说, 虽然循环中的五个函数是在各个迭代中分别定义的, 但是它们都被封闭在一个共享的全局作用域中, 因此实际只有一个i;并且延迟函数的回调在循环结束时才执行, 所以每次输出 6.
追问:如何改进代码,让输出数字1-5
1.立即执行函数
for (var i 1; i 5; i) {(function() {var j i;setTimeout(function timer() {console.log(j);}, j * 1000);})();
}
// 将上面代码进行一些改进:
for (var i 1; i 5; i) {(function(j) {setTimeout(function timer() {console.log(j);}, j * 1000);})(i);
}
// 在迭代内使用 IIFE 会为每个迭代都生成一个新的作用域, 使得延迟函数的回调可以将新的作用域封闭在每个迭代内部,
// 每个迭代中都会含有一个具有正确值的变量供我们访问! 2.给定时器传入第3个参数, 作为 timer 函数的第一个函数参数
for (var i 1; i 5; i) {setTimeout(function timer(j) {console.log(j);}, i * 1000, i)
} 3.块作用域
for (let i 1; i 5; i) {setTimeout(function timer() {console.log(i);}, i * 1000);
} 闭包的作用
可以访问另一个函数内部的局部变量让这些变量始终保持在内存中即闭包可以使得它诞生环境一直存在。同一个闭包机制可以创建多个闭包函数出来它们彼此没有联系都是独立的并且每个闭包函数可以保存自己个性化的信息。
this
极客时间-《浏览器的工作原理与实践》-[浏览器中的 JavaScript 执行机制]
11.this从JavaScript执行上下文的视角讲清楚this 《你不知道的JavaScript》(上卷) 中对 this 的相关介绍 判断this
可以参考 yck《前端面试手册》中的建议 学习小体会
笔者曾经几次打开《你不知道的 JavaScript》(上卷)翻了翻目录感觉里面的知识点都见过都知道呀就匆匆关上了放到一边。* 因为对闭包的理解存在一些疑问终于认真地看了这本书发现了其中魅力之处。作者的写作方式也让读者感到 interesting然后不禁发出和书中同样的感慨“妈妈快来看呀这就是闭包”。* 另外序言中 Shane Hudson 提到“想弄清楚事物的工作原理”让我意识到学习知识应该要有探索的精神不仅要知其然还要知其所以然。前段时间有些浮躁、有些急功近利看了一大堆面试题很多都是浅尝辄止流于表面。我想这应该是很多人都在走的路但我们不能一直这样面试题可以帮助我们完善知识体系查漏补缺但很多知识点都需要自己去针对性地学习、去实践别人几句话总结出来的答案更需要我们带着批判性精神去审视不能盲目吸收。* 如果你想从这篇文章中完全掌握闭包那么笔者只能说“小朋友你还是涉世未深~”。* 想想曾经的自己以为会背红宝书 P178 中对闭包的定义“闭包是指有权访问另外一个函数作用域中的变量的函数”就洋洋得意以为拿下了闭包这个大 BOSS。不管面试官听了作何感想反正现在看来是自己都说服不了自己。* 学东西还是得踏踏实实的现在能比较正确地理解和使用闭包首先得益于极客时间-《浏览器的工作原理与实践》-[浏览器中的 JavaScript 执行机制]章节让我以前很多模糊的概念有了清晰的认知。题外话这个课程真的是强推走过路过千万不要错过。然后是在一些技术博客上看到关于闭包的分析心中存有一些疑问于是再读《浏览器的工作原理与实践》对应内容但并未得到解答。看到评论区中有推荐《你不知道的 JavaScript》(上卷)作为补充学习的建议于是开始仔细阅读这本书有了今日的收获。* 所以笔者建议认真阅读《你不知道的 JavaScript》或者《浏览器的工作原理与实践》来理解闭包还可以参考 MDN 中对闭包的说明然后整理出自己的学习笔记。
最后
整理了75个JS高频面试题并给出了答案和解析基本上可以保证你能应付面试官关于JS的提问。 有需要的小伙伴可以点击下方卡片领取无偿分享