首页 > 编程语言 >前端进化笔记-JavaScript(三)

前端进化笔记-JavaScript(三)

时间:2023-06-08 16:48:42浏览次数:52  
标签:变量 作用域 前端 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声明的问题。

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

垃圾回收

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

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

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

性能提升

多使用const和let声明变量

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

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

静态分配:在函数中创建对象,如果函数不断使用,就会不断有对象内存需要回收,从而不断调用垃圾回收程序。可以在外部创建好对象,再将其以参数的形式传入函数,从而进行静态分配。

标签:变量,作用域,前端,JavaScript,笔记,对象,引用,上下文,函数
From: https://www.cnblogs.com/wlhxqtothetop/p/17400500.html

相关文章

  • Javascript常用正则表达式集合
    1.匹配正整数:/^[0-9]*[1-9][0-9]*$/2.匹配非负整数(正整数+0):/^\d+$/3.匹配中文:/^[\u4e00-\u9fa5]/4.匹配Email:/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/5.匹配网址URL:/^(f|ht){1}(tp|tps):\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?/6......
  • 小治同学的JAVAWEB学习笔记-Junit&反射&注解
    Junit单元测试Junit使用:白盒测试 步骤 1.定义一个测试类(测试用类) 建议: 测试类名:北侧是的类+Test 包名:XXX.XXX.XX.Test 2.定义测试方法:可以独立运行 建议: 方法名:test测试的方法名 返回值void 参数列表空参 3.给方法加@Test 判定结果 1.红......
  • 风尚云网微谈前端行业六大说
    风尚云网微谈前端行业,希望对新手小白有些帮助...个人见解,仅供参考,取长补短目录一:关于前端/大前端是什么?二:前端开发工程师是干什么的?三:2023年前端开发还值不值得学习?四:前端工程师需要会什么?五:关于最重要的前端开发薪资问题六:前端开发适合发展的城市一:关于前端/大前端是什......
  • 线段树合并学习笔记
    前言我是一个什么什么傻卵啊啊啊啊啊啊啊啊,连线段树合并都学不明白qaq正文权值线段树含义:是用来维护好多好多桶的线段树.桶是一个用来计数的东西.与普通线段树的区别普通线段树是用来维护区间和、积、最值等一系列的东西.权值线段树是用来维护某个区间内的数出现了......
  • SNMP学习笔记之SNMP报文以及不同版本(SNMPv1、v2c、v3)的区别
    SNMP学习笔记之SNMP报文以及不同版本(SNMPv1、v2c、v3)的区别本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1、v2c、v3)进行区别!四、SNMP协议数据单元在SNMP管理中,管理站(NMS)和代理(Agent)之间交换的管理信息构成了SNMP报文,报文的基本格式如下图1:        ......
  • [转]前端-WebAPI接口-FormData对象的使用(模拟表单用于发送数据及上传文件)
    一、概述FormData对象的使用:用一些键值对来模拟一系列表单控件:即把form中所有的元素的name与value组成一个queryString。异步上传二进制文件。二、使用创建一个空对象实例。 javascript复制代码varmyform=newFormData();使用已有的表单来初始化 ht......
  • 《大学物理实验上》期末笔记(三)作图法以及一些实验
    《大学物理实验上》期末笔记(三)作图法以及一些实验数据处理有多种方法,下面仅就作图法、逐差法作简单介绍。作图法就考试来说,结果不是最主要的,过程才重要。评分标准(共15分):图的题目——1分横坐标的物理符号与单位、还有分度选择——各1分,共3分纵坐标的物理符号与单位、还有分......
  • 在前端生成H5二维码海报
    海报图片生成前后端都能实现,个人喜欢在前端生成,主要是前端可以用html+css去实现海报样式,便于调试,对于熟悉前端代码的小伙伴来说再好不过。以下是在vue项目中的实现,非vue前端同理。思路及步骤:1.用html实现海报效果制作海报模板图,用js二维码库生成二维码,用CSS的绝对定位实现二......
  • 微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前
    文章目录一、前言二、前端代码wxml三、前端代码js四、后端java五、程序流程六、参考一、前言微信小程序开发笔记——导读大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机号码。但是,因为小程序用户的手机号码属于重要信息,为了安全,所以需要如下一系列较为复杂的方法和......
  • 微信小程序开发笔记 进阶篇⑥——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之后
    文章目录一、前言二、前端代码wxml三、前端代码js四、后端java五、程序流程六、参考一、前言微信小程序开发笔记——导读大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机号码。但是,因为小程序用户的手机号码属于重要信息,为了安全,所以需要如下一系列较为复杂的方法和......