前端进化笔记-JavaScript(三)

这篇具有很好参考价值的文章主要介绍了前端进化笔记-JavaScript(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

人类在白色的底色上描绘图画,地球在黑色的底色上创造生命。


变量、作用域与内存

JavaScript的变量可以说是独树一帜。只需要一个(或两个等)关键字(const,let)就可以创建变量,创建时不考虑变量的类型,这是其他语言少有的强大功能。当然强大的功能总是伴随着问题。

原始值:Undefined,Null,Boolean,Number,String,Symbol。它们都是按值访问的,因此我们操作的就是储存在变量中的实际值。

引用值:保存在内存中的对象。引用值是按引用访问的(类似指针),我们操作的实际上是引用而不是对象本身。

两者的不同:

  1. 原始值没有属性,引用值有,但如果使用new关键字,就会为原始值创造对象,从而使他们可以获得属性。(实际上字符串原始值,即使不用构造函数创建也有length等属性和方法。但是想要添加属性和方法就必须要使用包装类型对象)
  2. 原始值在复制的时候会获得一个独立的副本,而引用值只是复制了这个引用,它们指向同一个对象。(类似指针那样理解)

传递参数

ECMAscript中所有的函数参数都是按值传递的,也就说明函数内的参数和函数外的变量没有什么关系,只是值的赋值。即使是引用值也只是传值(虽然他的赋值是传址的),这里我的理解是传入指针本身的内容而非指向的地址本身。实际上,函数内部的参数是一个局部变量。
下面的例子,可以帮助我们理解这个问题:

function setName(obj){
  obj.name = 'jake';  //obj这个"指针"指向的地址(假设地址为1,则person的地址也为1)的name为jake,则1地址内的name被修改
  obj = new Object(); //obj不再指向1,而是指向其他地址(假设为2),1中的name值obj取不到了
  obj.name = 'james'; //2中的name为james,与1无关,也就与person无关
}

let person = new Object();
setName(person);
console.log(person.name);//jake
console.log(obj);//obj没有定义,他在函数执行结束的时候就被销毁了

instance用来确定对象的类型

上下文与作用域

执行上下文

红宝书中对于执行上下文的解释并没有那么深入,我在学习的过程中也在网上阅读了一些相关文章,对于JavaScript的执行上下文逻辑有了一点浅显的理解。日后在对js有更深入了解之后,会详细介绍,现在先简单说一下我的理解,如果后续发现不严谨的地方会随时修改,也欢迎指正。

执行上下文本质是一个变量对象,包含了上下文中定义的所有变量和函数。JavaScript在运行代码之前,会对整个代码进行一次扫描,进行一些配置(提升,配置全局上下文等),在配置全局上下文的时候,会将整个代码的变量和函数声明全部放入其中,但不会进行语句操作(赋值等),同时,全局上下文会永远放在执行上下文栈的最底部。在完成这些后,才会运行每一个语句。当代码执行流进入函数时,就会创建函数上下文,当然它也是个对象,它会将当前函数中的变量和函数声明放入其中,同时它也会被放入执行上下栈中。函数上下文和全局上下文的一些操作是相通,如果函数中还有函数,那就是不断往上下文栈中push的套娃过程。当函数执行完毕,它的上下文就会被销毁。因此外部无法访问内部的变量,但是内部却可以访问外部的。

当你在函数内部使用变量时,如果它并没有在该函数内部定义,那么JavaScript引擎会帮你找该函数的外层函数,这样一层层的找下去直到最外层。这和对象中属性和方法的搜索机制很像(一个是作用域链一个是原型链)。作用域链就是把上下文栈串了起来,前面的内部的(栈上层的)上下文,可以使用后面的外部的(栈下层的)上下文中的一切,反之则不行。

除了上面两种执行上下文外,eval()调用内部存在第三种上下文(在这里就不细说了)。还有一些语句会在作用域链前端临时添加一个上下文。

  • try/catch语句中的catch块:在前端创建一个新的对象,包含要抛出的错误对象声明
  • with语句:在前端添加指定对象

作用域

变量如果不使用任何关键字声明,会被添加到全局上下文。

  1. var的函数作用域声明
    使用var会将变量自动添加到最近的执行上下文中。
  2. let的块级作用域声明
    作用域由最近一对花括号界定(对于for循环等,在循环条件中let声明的对象,{}内可以使用)
  3. const的常量声明(也是块作用域)
    使用const声明变量时必须同时进行初始化。并且此变量不允许修改,但如果变量是对象,则对象中的属性或方法可以修改。这个特点让我联想到Vue中的props配置,同样是不允许修改,但是如果props传递了对象,则可以通过v-model对这个对象内部进行修改。不知道是Vue开发者留下的问题,还是原生js的const声明的问题(现在看来关系不大,虽然两者看起来还挺像)。
  • 这个问题今天面试官给我做了部分解释:不允许修改是因为方便数据的维护,一个父组件会有多个子组件,如果多个子组件同时修改数据会导致数据紊乱。虽然没有解释Vue开发人员为什么留下一个小“漏洞”。(这个问题等我入职的时候再问(手动狗头))
  • 写上面这句话的时候,我又觉得和OS中独木桥类问题有些类似。多个线程走一个独木桥时,必须通过原语保证过桥顺序不乱,当只有当一个线程放开对桥的使用时,下一个线程才可以上桥。这个方法就实现了多个线程过一个桥的方法。如果组件也可以自由修改props数据,那就要采取类似方法,保证修改时没有其他组件正在使用,也不允许其他组件“插队”。

无论JavaScript是否对变量声明进行提升,都不建议在变量未声明的时候就使用变量。

垃圾回收

对代码中不再使用的变量进行及时销毁,释放其内存。其中的关键就是对于变量的追踪与标记。浏览器的发展史上主要使用过两种标记策略:标记清理和引用计数

标记清理:这也是JavaScript最常用的垃圾回收策略。使用标记方法对不再使用的变量进行标记。

引用计数:变量每次被引用,值+1,当没有变量引用该变量时(值为0),则进行回收。如果两个对象对彼此互相引用,则会造成循环引用的问题

性能提升

多使用const和let声明变量

共享和删除:避免“先创建再补充”式的动态属性赋值,在构造函数中一次性声明所有属性,同时避免delete动态删除属性,而是将不在使用的属性值设置为null

内存泄漏:闭包中的回调会引用外部的变量,导致外部变量一直被引用无法回收。

静态分配:在函数中创建对象,如果函数不断使用,就会不断有对象内存需要回收,从而不断调用垃圾回收程序。可以在外部创建好对象,再将其以参数的形式传入函数,从而进行静态分配。文章来源地址https://www.toymoban.com/news/detail-480771.html

到了这里,关于前端进化笔记-JavaScript(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端学习心得笔记之三(JavaScript篇)

    JavaScript一种运行在客户端(浏览器)上的解释性弱语言,是前端的重中之重,在计算机刚刚兴起的那个时代,这个由十天仓促编成的语言发展到现在也是令人吹嘘。 文件引用 在一个单独的js文件中也可以编写JavaScript代码,然后在HTML文件使用script标签进行引用以下为演示 m

    2024年04月23日
    浏览(31)
  • web前端javascript笔记——(13)事件(1)

    鼠标/键盘属性 altKey               返回当事件被触发时,“ALT”是否被按下。 button               返回当事件被触发时,哪个鼠标按钮被点击 clientX               返回当事件被触发时,鼠标指针的水平坐标。 clientY               返回当事件被触

    2024年01月25日
    浏览(28)
  • web前端javaScript笔记——(11)DOM

    属性                                     此事件发生在何时 onabort 图像的加载被中断。 onblur                                   元素失去焦点。 anchange                                 域的内容被改变 onclick  当用户点击某

    2024年01月19日
    浏览(27)
  • 前端学习笔记:JavaScript基础语法(ECMAScript)

    此博客参考b站:【黑马程序员前端JavaScript入门到精通全套视频教程,javascript核心进阶ES6语法、API、js高级等基础知识和实战教程】https://www.bilibili.com/video/BV1Y84y1L7Nn?p=76vd_source=06e5549bf018e111f4275c259292d0da 这份笔记适用于已经学过一门编程语言(最好是C语言)的同学,如果你没有

    2024年02月16日
    浏览(24)
  • 【JavaEE初阶】前端第四节.JavaScript入门学习笔记

    作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:Java测试开发 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!! 前言 一、前置知识  1、JS 和 HTML 和 CSS 之间的关系 1.2 JS 的书写形式 1.2.1 内嵌式 1.2.2 行内式  1.2.3 外部式 1.2.4 扩展 1.2

    2024年02月08日
    浏览(29)
  • 前端基础(CSS)——css介绍 & 常用样式 & 案例—进化到Bootstrap——进化到Element-UI(未完待续)

    css是什么,层叠样式表, css作用:让html网页有布局,变漂亮 参考w3school 以p标签为例, 序号 位置 优先级 1 写在p标签内 最高 2 写在style内 第二 3 写在link内 最低 (1)标签选择器—div{} 标签选择器,选择html文档中所有的div,对所有的div进行设置 (2)id选择器----#div01{} 符号

    2024年02月08日
    浏览(31)
  • 【视频笔记】解密RWKV线性注意力的进化过程

    from: https://www.bilibili.com/video/BV1zW4y1D7Qg/?spm_id_from=333.999.0.0vd_source=21cce77bb69d40a81e0d37999f2da0c2 手动实现,可以看出 时间复杂度 O ( n 2 ) O(n^2) O ( n 2 ) 调用库函数 权重 衰减 权重 迭代 记录

    2024年02月12日
    浏览(19)
  • 读千脑智能笔记11_保存人类遗产

    1.1.1.1. 这是一个力图寻找宇宙其他地方智能生物存在证据的研究项目 1.1.1.2. SETI计划旨在寻找含有某种模式的无线电信号,表明该信号是由一个智能生物发出的 1.1.1.3. 即使我们无法与外星生物沟通,但知道他们存在或曾经存在,就已令我们激动不已 1.1.1.4. 了解其他智能生

    2024年02月19日
    浏览(12)
  • 读千脑智能笔记12_阻止人类灭绝

    1.1. 宇宙中唯一知道这些的物体,唯一知道宇宙存在的物体,是我们的大脑 1.2. 如果没有关于某个事物的知识,我们能说这个事物就一定存在吗? 1.2.1. 我们的大脑扮演着这样一个独特的角色,这很令人着迷 1.3. 30%的大脑,即旧脑,是由许多不同部分组成的 1.3.1. 旧脑区域

    2024年02月19日
    浏览(13)
  • 读千脑智能笔记10_人类智能存在的风险

    1.4.1.1. 人类大脑中有30%的部分进化得更早,并创造了我们的原始欲望和行为 1.4.1.2. 大脑中的新皮质发明了强大到可以改变整个地球的技术,然而控制这些技术的人类行为往往是由自私且短视的旧脑所主导的 1.4.1.3. 人类的血统可追溯到数十亿年前 1.4.1.3.1. 在跨度如此之大的

    2024年02月19日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包