JavaScript高级编程设计(第三版)——第四章:变量作用域和内存问题
系列文章目录
第二章:在html中使用javaScript
第三章:基本概念
第四章:变量作用域和内存问题
第五章:引用类型
目录
系列文章目录
前言
一、基本数据类型和引用类型的值?
1.数据类型
2.赋值
3.传参
4.检测数据类型
二、执行环境及作用域
1.执行环境和作用域概念
2.延长作用域链
3.没有块级作用域
4.垃圾收集
4.1.标记清除法
4.2引用计数法
总结
前言
这本书是我刚入行的时候我师傅推荐给我的,当时只想获得实现的满足感,而一直没有深入学习。随着页面实现了更多后,发现学好javascript非常的有必要,这也是这个系列出现的缘由~
我将分章节学习并记录(第一章简介我就不记录了,有兴趣自己去看看),如果内容太多也会分为上下两小节。
学习过程中也会拓展一下相应内容,思考一些问题,感兴趣就继续往下看看吧~
这一章主要记录一些基本数据类型如何检测、作用域及垃圾回收的一些方法,这一块在面试的时候常常会被问道~
一、基本数据类型和引用类型的值?
1.数据类型
第三章提到基本数据类型有:null nudefined string boolean number(es6还有syblom),引用类型有object
2.赋值
这里我们要明白他们存放位置,基本数据类型存放在栈里面,引用数据类型在栈里面存放指针,指针指向队里面的内存。
所以,当我们进行赋值的时候,如下:
根据上面的图我们可以看清区别:基本数据类型会开启一个新内存赋值,引用类型会开启一个新的内存存指针。
3.传参
传参最常见于函数,当我们将变量当作参数传递给函数的时候。
对基本数据类型来说,参数是函数的一个局部变量,他的变化不会改变全局变量,如下:
function add(a){a +=20
}
var age = 80
add(80)
console.log(age)//这里输出80
对引用类型来说,他的变化会改变原始引用值(因为引用地址都相同,所以会改变),如下:
function add(obj){obj.age="18"
}
var obj = {
name:"lily"
}
add(obj)
console.log(obj.age)//这里输出18
虽然这样会改变引用值,但是并不代表是引用的地址,如下:
function add(obj){obj.age="18"obj = new Object()obj.age="80"
}
var obj = {
name:"lily"
}
add(obj)
console.log(obj.age)//这里输出18,obj并不会将后面的内存赋值上面,后面的只是一个局部变量,函数的参数还是外面的obj
4.检测数据类型
如何检测类型呢,这里提供三种方法:
- typeof(),适用于基本数据类型,当检测null和对象的时候返回object
- instanceof,适用于引用类型,返回true false ,如:array instanceof Array,值得注意的是,因为引用类型都是object的实例,所以检测引用类型是否为object的时候始终返回object
- object.protoype.tostring.call()来检测,适用于所有类型,返回值为[object 类型]
二、执行环境及作用域
1.执行环境和作用域概念
首先我们知道JavaScript是单线程的语言,我们的语言会按照编码顺序一步一步的执行,执行环境中有一个变量对象,变量对象包括函数和变量。
我们有全局执行变量,就是我们常说的window对象,可以访问他。在我们浏览器关闭或页签关闭的时候全局执行变量才会销毁。
当我们执行的时候遇见了函数,首先会将他放入环境栈里面,等待改函数执行完毕后弹出栈。
我们一步一步执行的时候,会创建变量对象的一个作用域链,我们可以理解为函数内部找不到该变量则向外层执行环境会寻找,直到windows变量。这样形成的一个链路叫作用域链。这里值得注意的是,内部变量可访问内部执行环境,但外部执行环境不能访问内部变量
2.延长作用域链
作用域分为全局作用域和局部(函数)作用域,通常我们执行完后就会移除。但有的时候我们需要延长作用域链,我们只需要在作用域前端添加一个变量对象就可以了啦,可以使用with或try catch中的catch块。
with在我们第三章就说过,它可以将指定对象添加到作用域链上,如下:
function add(){var name = "lily"with(location){//将location变量对象添加到作用域链前端var url = href}retrun url
}
try catch会创建一个 新的变量对象
try{
console.log("成功")
}
.catch(err){var a = "报错啦"console.log(a)
}
在catch块中将变量对象添加到作用域前端,从而延长作用域链
当然,除了这两种方法,我们还可以使用eval()这个内置对象来延迟那个作用域链,如下:
function add(str){eval(str)//eval会将字符串解析为js,从而将变量对象添加到作用链前端,延长作用域链
}
add("var a= 0")
3.没有块级作用域
这个标题很不理解哈,其他语言不是说{}里面的都是块级作用域吗?在JavaScript中我们陈伟执行环境。作用域也可以叫全局作用域和局部(函数)作用域,但不能说{}里面包裹的就是块级作用域,为什么这样说呢?如下:
//if语句
if(true){
var a ="你好"}
console.log(a)//输出:你好//for语句for(var i=0;i<10;i++){
...}
console.log(i) //输出10
看到上面这两个语句了嘛,我们都是在{}内部的,但是呢,在{}外部访问也是能访问的,所以这也证实了JavaScript没有块级作用域。
当然,我们在函数内部定义的变量不管是var let const ,在全局执行环境中式无法访问的,但是如果没有用标识符定义,则会将这个变量沿着作用域链查找,直到找个这个标识符的变量(定义这个变量的地方),如果查找到window还没找到,则将这个变量挂载到window上(全局变量)。
4.垃圾收集
我们前面说了,当代码一步一步的执行的时候,会将变量分配内存,当我们变量不在使用得时候,则弹出栈,让内存空出来,这就是垃圾回收机制,这样保证了我们性能和速度。
关于垃圾回收的方法有两种:标记清除法和引用计数法。
4.1.标记清除法
执行代码的时候,将变量进行标记,将正在执行环境中的变量和环境中的变量去除标记,将没有标记的变量清除掉,这就是标记清除法。
4.2引用计数法
当我们声明和一个变量或赋值的时候,计数为1,如果又被赋值给另一个变量计数为2,每次被赋值或引用则加1;如果包含这个值得变量被重新赋值,则减1,直到为0时,就会被清除。
但是这个方法如果存在于循环体内,被重复得引用,那他永远都不能被清除,而回导致内存得不到回收,所以不建议用这个方法。
最后,为了得到更好得性能,所以最好在不用该数据得时候将其设置为null,这样下次垃圾回收得时候,就会清除掉,释放内存。
总结
以上就是今天要讲的内容,本文简单介绍了基本数据和引用数据得值,作用域和作用域链,内存及垃圾回收机制。
JavaScript高级编程设计(第三版)——第四章:变量作用域和内存问题相关推荐
- 读书笔记 - js高级程序设计 - 第四章 变量 作用域 和 内存问题
5种基本数据类型 可以直接对值操作 判断引用类型 var result = instanceof Array 执行环境 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对 ...
- UNIX环境高级编程(第三版)关于apue.h的用法
UNIX环境高级编程(第三版)中的例子用到apue.h这个头文件,但是书里面写的地址已经不能访问. 经过一番查找之后,找到如下解决方案: 1.到www.apuebook.com上下载第2版的源码,也可 ...
- JavaScript高级程序设计 第四章---变量 作用域 内存
第四章-变量 作用域 内存 关键字:变量 作用域 内存 本章内容 通过变量使用原始值与引用值 理解执行上下文 理解垃圾回收 4.1 原始值与引用值 ECMAScript 变量可以包含两种不同类型的数据 ...
- JavaScript高级编程设计(第三版)——第三章:基本概念
系列文章目录 第二章:在html中使用javaScript 第三章:基本概念 第四章:变量作用域和内存问题 目录 系列文章目录 前言 一.语法 1.标识符 2.关键字和保留字 二.数据类型 1.nul ...
- javascript高级程序设计(第三版)学习摘录下
第十章 DOM 1001.每一段标记都可以通过树中的一个节点来表示:HTML 元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,而注释则通过注释节点表示. ...
- javascript 高级程序设计(第三版)读后归纳
第4章 变量.作用域和内存问题 复制变量值 基本类型值复制(如:Number.String .Boolean.Null和Undefined),分配新的位置 引用类型值(如:对象类型Object typ ...
- JavaScript高级程序设计(第三版)学习笔记1~5章
第2章,在html中使用JavaScript Html引入外部js脚本 <script type="text/javascript" src="test.js&qu ...
- JavaScript高级编程设计(第三版)——第二章:在html中使用javaScript
系列文章目录 第三章:基本概念 目录 系列文章目录 前言 一.javaScript是什么? 1.有两种引入方式 1.1 嵌入式 1.2 外部引入 1.3 noscript标签 标签 1.4文档模式 2 ...
- JavaScript高级程序设计(第三版)学习笔记22、24、25章
第22章,高级技巧 高级函数 安全的类型检测 typeof会出现无法预知的行为 instanceof在多个全局作用域中并不能正确工作 调用Object原生的toString方法,会返回[Object ...
最新文章
- date转换成string hive_[转] String to Date conversion in hive - 在 Hive 中各种字符串转换成日期格式...
- Kali Firefox
- 此处不允许使用分组函数_Excel中使用Vlookup函数实现数据分组
- heroku服务器_如何在Heroku上使用Express服务器部署React应用
- Spring Boot + Security + Thymeleaf + Activiti 快速开发平台项目
- PHP 生成csv的遇到的分隔符问题
- 程序员面试金典——17.4无判断max
- (原創) 有限狀態機FSM coding style整理 (SOC) (Verilog)
- Xcode6 - 更改项目Copyright
- hosts文件是什么? 以及在各个系统中(Windows、Mac、Linux)的hosts文件在哪里?
- windows10 系统共享文件端口修改
- 蓝牙技术|AirPods Pro 2 支持蓝牙 LE Audio 技术带来的 5 大好处
- 4.3 人工智能典型岗位的能力要求
- 深入理解Kotlin协程suspend工作原理(初学者也能看得懂)
- PyCharm使用cxfreeze的方法
- javaScript搜索框
- 逻辑学探幽 Part1
- 雅思作文模板.html,2015雅思小作文模板「万能」
- 【查看】 - 内网(局域网)ip 、公网(外网)ip - ipconfig 、 tracert
- java 课件ppt_《java语言入门》PPT课件.ppt