JS深入学习笔记 - 第三章.变量作用域与内存
1.原始值和引用值
ECMScript变量包含两种不同类型是数据:原始值和引用值。
原始值:最简单的数据。有6中原始值:Undefined、Null、Boolean、Number、String和Symbol。原始值是按值访问。
引用值:由多个值构成的对象。三大引用类型:1.object 2.Array类型 3.Function类型。引用值是保存在内存中的对象,由于js不允许直接访问内存位置,所以对引用值的访问是访问该对象的引用而非对象本身。
这里可以类比java中的基本数据类型和引用数据类型。
2.复制
通过变量把一个原始值复制到另一个另一个变量时,原始值会在内存中增加一个值,赋值为新的变量,如num2上
let num1 = 5
let num2 = num1
此时修改num1 的值,猜一猜会不会对num2有影响?
let num1 = 5;
let num2 = num1;
num1 = 545454;
console.log(num2);//5
答案是不会的,因为在上面提到了,num1与num2对应的是两个独立的值。

但是如果是引用值呢?
let arr1 = [1,2]
let arr2 = arr1
arr1.push(6)
console.log(arr2)//(3) [1, 2, 6]
欸?arr2也改变了呢,是什么原因呢?
原因是这里的复制的值实际上是一个指针,它指向存储在堆内存中的对象。他们指向的是同一个值。

那如果传递是对象呢?
//对象
function setName(obj) {
obj.name = "zooey";
}
const person = new Object();
setName(person);
console.log(person.name); //zooey
此时对象类型person复制给obj,看起来很像是引用类型的改变,
但是事实上,对象仍然是按值传进函数的,但是obj是按照引用访问的person,怎么?你不信?
//对象
function setName(obj) {
obj.name = "zooey";
obj = {
name: "anan",
};
console.log(obj.name);//anan
}
const person = new Object();
setName(person);
console.log(person.name); //zooey
看吧,的确是没有改掉吧,确实是按值引用。
令人觉得很复杂,对吧。
object对象本身是按值访问的,而对象的属性则是按照引用访问的
3.确定类型
1.typeof
最适合用来判断变量是否是原始类型。更确切的说它是判断一个变量是否是字符串、数值、布尔值或者undefined的最好的方式。
et str = "absce";
let num = 12;
let boo = true;
let und = undefined;
let obj = { name: "aaa" };
console.log(typeof num); //number
console.log(typeof str); //string
console.log(typeof boo); //boolean
console.log(typeof und); //undefined
console.log(typeof obj); //object
但是,typeof对引用值的作用不大
2.instanceof
按照定义,所有引用值都是Object的实例,因此通过instanceof操作符检测任何引用值和Object构造函数都会返回true。
类似的,如果用instanceof检测原始值,则始终会返回false,因为原始值不是对象。
let arr = [1, 23, 4];
let fun = () => {
console.log("i am function");
};
class Myclass {
constructor() {
name;
}
}
function Cons() {
return "sss";
}
console.log(typeof arr); //object
console.log(typeof fun); //function
console.log(typeof Myclass); //function
console.log(typeof Cons); //function
console.log(arr instanceof Array); //true
console.log(fun instanceof Function); //true
console.log(Myclass instanceof Function); //true
console.log(Cons instanceof Function); //true
4.执行上下文和作用域
1.什么是执行上下文(以下简称上下文)?
变量和函数的上下文决定了它们可以访问哪些数据,以及他们的行为。
每个上下文都有一个关联 变量对象(variable object),而这个上下文中定义的所有变量和函数都存在于这个对象上。虽然没办法通过代码真正的访问它。
2.什么是全局上下文?
最外层的上下文。在浏览器中,全局上下文就是我们常说的window对象,因此,所有通过var定义的全局变量和函数都会成为window对象的属性和方法
3.上下文什么时候销毁?
上下文在其所有的代码都执行完毕后会被销毁,包括定义在它上面的所有变量和函数。
全局上下文在应用程序退出前才会被销毁,比如关闭页面或者退出浏览器。
4.上下文的执行流程
每个函数调用都有自己的上下文。当代码执行流进入到函数时,函数的上下文被推到一个上下文栈上,在函数执行文之后,上下文栈会弹出该函数上下文,将控制器泛黄之前的执行上下文。ECMAScript程序的执行流就是通过这个上下文栈进行控制的。
上下文中代码在执行的时候,会创建变量对象的一个作用域链(scope chain),这个作用域链决定看各级上下文中代码在访问变量和函数时的顺序。代码正在执行的上下文的变量对象始终位于作用域的最前端。
5.标识符解析在上下文中的寻找规则
代码执行时的标识符解析时通过沿着作用域链逐级搜索标识符名称完成的。搜索过程始终从作用域链的最前端开始,然后逐级往后,直到找到标识符。(如果没有找到则会报错)
let name = "zooey";
function getName() {
let myname = "anan";
if (name === "zooey") {
name = myname;
} else {
name = "zooey";
}
}
getName();
console.log(name); //anan
在这个例子中,函数getName的作用域链包含两个对象“一个是他自己的变量对象myname,一个是全局上下文的变量对象name,之所有能够访问color,就是因为可以在作用域链中找到它。
此外,局部作用域中定义的变量可以用于在局部上下文中替换全局变量。
总结一下:
类似于java的局部变量和全局变量,
局部上下文中的变量只能在本作用域中使用
全局上下文中的变量可以在全局使用
如果包含嵌套关系,那么父作用域中的变量,子作用域也可以使用 。
即,内部上下文可以通过作用域链访问外部上下文中的一切,但外部上下文无法访问内部上下文中的任何东西。
每个上下文都可以到上一级上下文中去搜索变量和函数,但任何上下文都不能去下一级上下文中去搜索。
(此处举一个不恰当的例子,儿子可以继承父亲的房子,换掉父亲的凳子椅子,但是父亲不能继承儿子的房子,换掉儿子的家具,儿子会生气的~)
注意:函数参数(实参)被认为是当前上下文中的变量,因此也跟上下文中的其他变量遵循相同的访问规则。
JS深入学习笔记 - 第三章.变量作用域与内存的更多相关文章
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
- The Road to learn React书籍学习笔记(第三章)
The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...
- Spring学习笔记 - 第三章 - AOP与Spring事务
原文地址:Spring学习笔记 - 第三章 - AOP与Spring事务 Spring 学习笔记全系列传送门: Spring学习笔记 - 第一章 - IoC(控制反转).IoC容器.Bean的实例化与 ...
- 《DOM Scripting》学习笔记-——第三章 DOM
<Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...
- [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设
[HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...
- Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件
Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布局.界面切换 [本章]Qt 学习笔记 - 第三章 - Qt的三驾马车之一 ...
- JavaScript高级编程学习笔记(第三章之一)
继续记笔记,JavaScript越来越有意思了. 继续... 第三章:JavaScript基础 ECMAScript语法在很大程度上借鉴了C和其它类似于C的语言,比如Java和Perl. 大小写敏感: ...
- python学习笔记——第三章 串
第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...
- Java 学习笔记 ------第三章 基础语法
本章学习目标: 认识类型与变量 学习运算符的基本使用 了解类型转换细节 运用基本流程语法 一.类型(基本类型) 所谓基本类型,就是在使用时,得考虑一下数据用多少内存长度存比较经济,利用程序语法告诉JV ...
- c#高级编程第七版 学习笔记 第三章 对象和类型
第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...
随机推荐
- JavaWeb编程面试题——Spring Web MVC
引言 面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待.不以刷题进大厂为目的,而是以学习为目的.这里的知识点会持续更新,目录也会随时进行调整. 关注公众号:编 ...
- JavaScript学习笔记 - 语法篇 - 一句废话没有版
写在前面: 绝不废话!放心食用 JavaScript语法很简单,可以直接在控制台调试理解 目录 1.变量和常量 2.数据类型 3.字符串 3.1 模板字符串 3.2 字符串的部分常用函数 4.数组 5 ...
- 洛谷 P4859 已经没有什么好害怕的了
题目描述 学姐 4 了. 有 \(n\) 个糖果和 \(n\) 个药片,它们要进行一一配对.每个糖果或药片都具有互不相同的能量值,要求配对后,糖果比药片能量高的对数,比剩下的对数恰好多 \(k\),求 ...
- React基本引入和JSX语法
1.1 React介绍 1.1.1. 官网 英文官网:https://reactjs.org/ 中文官网: https://react.docschina.org/ 1.1.2. 介绍描述 用于动态构 ...
- Vortex Indicator 构建交易策略
更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 今天的文章,我们将为大家介绍一个与DMI(Directional Movement Index)类似,判 ...
- CentOS上安装Redis的两种方式
今天小编给大家介绍下,如何在CentOS上安装Redis.通常有两种方式:第一种是通过下载源码并编译来安装,第二种是通过仓库直接安装.相较而言,第二种方式更直截了当,但小编更倾向第一种. 一.通过源码 ...
- Nginx TCP 负载均衡:stream 模块配置
工作上遇到需要用nginx做负载均衡,参考了前同事留下的作业顺利搞定,感觉这块很有意义写篇文档记录. 参考:nginx tcp负载均衡(Stream模块)配置说明 参考:利用nginx进行TCP负载均 ...
- HashMap源码的阅读笔记
注释部分 Hash table based implementation of the <tt>Map</tt> interface. This * implementatio ...
- 清理MySQL的binlog日志
前言 MySQL的binlog是以二进制形式打印的日志,没设置自动删除的话,时间长了就会占用大量存储空间.删除MySQL的binlog日志有两种方法:自动删除和手动删除. 自动删除 永久生效:修改My ...
- .NET Core多线程 (2) 异步 - 上
去年换工作时系统复习了一下.NET Core多线程相关专题,学习了一线码农老哥的<.NET 5多线程编程实战>课程,我将复习的知识进行了总结形成本专题. 本篇,我们来复习一下异步的相关知识 ...