你对JavaScript掌握多少?讲解Js框架结构

时间: 2019-08-29阅读: 422标签: 框架

对于任何一个程序员来说,最关注的两个问题无非就是:时间复杂度和空间复杂度。第一部分介绍了 V8 为改进 JavaScript 执行时间所做的速度提升和优化,第二部分则将着重介绍内存管理方面的知识。这篇文章,小编简要概述了编程语言的一般工作机制,并深入探讨了 V8 引擎的管道。第二部分将介绍一些更重要的概念,这些概念是每一个 JavaScript 程序员都必须了解的,并且不仅仅和 V8 引擎有关。


内存堆


Orinoco 的 logo:V8 的垃圾回收器

每当你在 JavaScript 程序中定义了一个变量、常量或者对象时,你都需要一个地方来存储它。这个地方就是内存堆。

当遇到语句 var a = 10 的时候,内存会分配一个位置用于存储 a 的值

可用内存是有限的,而复杂的程序可能有很多变量和嵌套对象,因此合理地使用可用内存非常重要。

和诸如 C 这种需要显式分配和释放内存的语言不同,JavaScript 提供了自动垃圾回收机制。一旦对象/变量离开了上下文并且不再使用,它的内存就会被回收并返还到可用内存池中。

在 V8 中,垃圾回收器的名字叫做 Orinoco,它的处理过程非常高效。这篇文章有相关解释


标记与清除算法


标记和清除算法

我们通常会使用这种简单有效的算法来判定可以从内存堆中安全清除的对象。算法的工作方式正如其名:将对象标记为可获得/不可获得,并将不可获得的对象清除。

垃圾回收器周期性地从根部或者全局对象开始,移向被它们引用的对象,接着再移向被这些对象引用的对象,以此类推。所有不可获得的对象会在之后被清除。

内存泄漏

虽然垃圾回收器很高效,但是开发者不应该就此将内存管理的问题束之高阁。管理内存是一个很复杂的过程,哪一块内存不再需要并不是单凭一个算法就能决定的。

内存泄漏指的是,程序之前需要用到部分内存,而这部分内存在用完之后并没有返回到内存池。


下面是一些会导致你的程序出现内存泄漏的常见错误:

全局变量:如果你不断地创建全局变量,不管有没有用到它们,它们都将滞留在程序的整个执行过程中。如果这些变量是深层嵌套对象,将会浪费大量内存。

var a = { ... }var b = { ... }function hello() { 
 c = a; // 这是一个你没有意识到的全局变量} 

如果你试图访问一个此前没有声明过的变量,那么将在全局作用域中创建一个变量。在上面的例子中,c 是没有使用 var 关键字显式创建的变量/对象。

事件监听器:为了增强网站的交互性或者是制作一些浮华的动画,你可能会创建大量的事件监听器。而用户在你的单页面应用中移向其他页面时,你又忘记移除这些监听器,那么也可能会导致内存泄漏。当用户在这些页面来回移动的时候,这些监听器会不断增加。

var element = document.getElementById('button'); 
element.addEventListener('click', onClick) 

Intervals 和 Timeouts:当在这些闭包中引用对象时,除非闭包本身被清除,否则不会清除相关对象。

setInterval(() => { 
 // 引用对象}// 这时候忘记清除计时器// 那么将导致内存泄漏! 

移除 DOM 元素:这个问题很常见,类似于全局变量导致的内存泄漏。DOM 元素存在于对象图内存和 DOM 树中。用例子来解释可能会更好:

var terminator = document.getElementById('terminate');var badElem = document.getElementById('toDelete'); 
terminator.addEventListener('click', function() {memory 
 badElem.remove();}); 

在你通过 id = ‘terminate’ 点击了按钮之后,toDelete 会从 DOM 中移除。不过,由于它仍然被监听器引用,为这个对象分配的内存并不会被释放。

var terminator = document.getElementById('terminate'); 
terminator.addEventListener('click', function() { 
 var badElem = document.getElementById('toDelete'); 
 badElem.remove();}); 

badElem 是局部变量,在移除操作完成之后,内存将会被垃圾回收器回收。


调用栈

栈是一种遵循 LIFO(先进后出)规则的数据结构,用于存储和获取数据。JavaScript 引擎通过栈来记住一个函数中最后执行的语句所在的位置。

function multiplyByTwo(x) { 
 return x*2;}function calculate() { 
 const sum = 4 + 2; 
 return multiplyByTwo(sum);} 
calculate()var hello = "some more code follows" 

1.引擎了解到我们的程序中有两个函数

2.运行 calculate() 函数

3.将 calculate 压栈并计算两数之和

4.运行 multiplyByTwo() 函数

5.将 multiplyByTwo 函数压栈并执行算术计算 x*2

6.在返回结果的同时,将 multiplyByTwo() 从栈中弹出,之后回到 calculate() 函数

7.在 calculate() 函数返回结果的同时,将 calculate() 从栈中弹出,继续执行后面的代码


栈溢出


在不对栈执行弹出的情况下,可连续压栈的数目取决于栈的大小。如果超过了这个界限之后还不断地压栈,最终会导致栈溢出。chrome 浏览器将会抛出一个错误以及被称为栈帧的栈快照。

递归:递归指的是函数调用自身。递归可以大幅度地减少执行算法所花费的时间(时间复杂度),不过它的理解和实施较为复杂。

下面的例子中,基本事件永远不会执行,lonley 函数在没有返回值的情况下不断地调用自身,最终会导致栈溢出。

function lonely() { 
 if (false) { 
 return 1; // 基本事件 
 } 
 lonely(); // 递归调用} 


为什么 JavaScript 是单线程的?

一个线程代表着在同一时间段内可以单独执行的程序部分的数目。要想查看一门语言是单线程的还是多线程的,最简单的方式就是了解它有多少个调用栈。JS 只有一个,所以它是单线程语言。

这样不是会阻碍程序运行吗?如果我运行多个耗时的阻塞操作,例如 HTTP 请求,那么程序必须得在每一个操作得到响应之后才能执行后面的代码。

为了解决这个问题,我们需要找到一种可以在单线程下异步完成任务的办法。事件循环就是用来发挥这个作用的。


事件循环

到现在为止,我们谈到的内容大多包含在 V8 里面,但是如果你去查看 V8 的代码库,你会发现它并不包含例如 setTimeout 或者 DOM 的实现。事实上,除了运行引擎之外,JS 还包括浏览器提供的 Web API,这些 API 用于拓展 JS。


总结:

关于制作一门编程语言,其实还有很多内容,并且语言的实现在这些年也是不断变化的。我希望这两篇博客可以帮助你成为一名更好的 JS 程序员,并且接受 JS 中那些晦涩难懂的内容 。对于诸如“V8”,“事件循环”,“调用栈”这样的术语,你现在应该熟悉了。

大部分的学生(比如我)是从一个新的框架起步,之后再去学习原生 JS。现在他们应该熟悉代码背后发生的事情了,反过来,这将帮助他们写出更好的代码。

原文 http://developer.51cto.com/art/201909/603752.htm
站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/5586

合理使用CSS框架,加速UI设计进程

现在的网站风格已经与它们很早之前的样子有了很大的不同。如果现在再回过头去看有些公司最初的网站UI,我想大多数互联网用户都很难认得出来。所以也多亏了网页设计技术的创新,现在网站不仅仅是只能显示信息

前端工程师必须了解的主流前端框架

现在前端工程师的工作已经不想几年前那样,仅仅写一些页面调整一下样式就可以拿到高薪了。由于前端技术的发展,以及企业对前端工程师的要求越来越高,现在前端工作也越来越复杂。不过只要掌握目前比较流行的主流框架

常用的十大 NodeJS 框架

Node.js 是基于 Chrome V8 javascript 引擎构建的开源、跨平台运行时环境。事件驱动的非阻塞I/O 模型使,NodeJS 能开发极其轻便且高效的 Web 应用程序。客户端 和 服务端 脚本中使用相同的语言

React 还是 Vue:选哪个?

毫无疑问,React 和 Vue 的目标市场非常相似:两者都是基于组件的轻量级库,都是用来构建仅关注视图层的用户界面。两者都可以用在简单的项目中,也可以使用顶尖的工具链扩展到复杂的应用程序上。于是乎,许多 Web 开发人员都在犹豫到底该用哪个框架。它们之间有明显的差距吗?

vue和angular如何选择?

如今,已有许多开发人员开始使用Vue.js来取代Angular和React.js。那么对于Angular和Vue.js,开发者该如何选择呢?下面本篇文章就来给大家介绍一下,希望对大家有所帮助。vue是一个渐进式的框架,是一个轻量级的框架,也不算是一个框架

node.js后端框架介绍

Node.js有许多框架可以选择,包括老牌的express,koa,新晋的egg,nest等等,Express是一款基于node.js以及ChromeV8引擎,快速、极简的JS服务端开发框架,它提供了用来开发强壮的web/移动应用,以及API的所有功能

ReactJS 与 VueJS:两种最流行的前端 JS 框架之战

如果有人问你将在 2020 年选择哪种框架进行开发,你的答案将是什么?很明显,你主要有两个选择: React.Js 和 Vue.Js!但是,如果你需要选择一个怎么办?好吧,两个最受欢迎的框架 React Js 和 Vue.Js 之间的战斗是真实的

最受程序员欢迎的20 个CSS框架

本文为大家搜罗了 20 款截至目前最受程序员欢迎的前端CSS框架,其中有的霸榜已久,也有不少后起之秀,有的是单纯的 CSS 框架,也有的结合了 JavaScript 以提供更丰富的功能

值得探索的 8 个机器学习 JavaScript 框架

Deeplearn.js是Google发布的一个开源的机器学习JavaScript库,可用于不同的目的,例如在浏览器中训练神经网络,理解ML模型,用于教育目的等。你可以在推理模式中运行预先训练的模型

前端常用框架优缺点总结

JQuery是一个优秀的javascript框架 ,JQuery宗旨是Write Less Do More ,JQuery是轻量级的js库;Zepto.js针对移动端浏览器;Bootstrap用于开发响应式布局、移动设备优先的web项目

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广