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 类和结构 ...
随机推荐
- 图书商城项目练习①管理后台Vue2/ElementUI
本系列文章是为学习Vue的项目练习笔记,尽量详细记录一下一个完整项目的开发过程.面向初学者,本人也是初学者,搬砖技术还不成熟.项目在技术上前端为主,包含一些后端代码,从基础的数据库(Sqlite).到 ...
- VisionPro学习笔记(2)——图像转换工具ImageCovertTool
众所周知,VisionPro是一款功能强大的机器视觉软件,用于开发和部署机器视觉应用程序.其中ImageConvertTool是其中一个重要的工具,用于图像转换和处理.本文将介绍如何使用ImageCo ...
- 解读XML - Foreach循环
<foreach item="item" index="index" collection="supplyIdAry" open=&q ...
- 楠少音乐盒(PC端)突破校园网限制
楠少音乐盒 突破校园网限制 最近在将音乐盒从web迁移到PC端,过程中的记录 在我们学校,工作时间内(周一至周五为工作日,下午上班时间)校园网都会拦截一些与工作无关的网站,例如购物.炒股.游戏.音乐等 ...
- 浅析华为云Astro的5大关键能力技术
摘要:本文以技术方案视角,对华为云Astro低代码平台的一些核心功能进行简要介绍. 背景介绍 低代码开发基于可视化开发的概念,结合了云原生和多终端体验技术,它可以在大多数业务场景中,帮助企业显著的提升 ...
- Code Generate V2.0 代码生成器
Code Generate 代码生成器 系统首页 使用说明 系统默认会根据SQL生成字段信息 className.fieldList.classComment 如下所示: 建表语句 CREATE TA ...
- SpringBoot整合Websocket,实现作为客户端接收消息的同时作为服务端向下游客户发送消息
SpringBoot整合Websocket 1. SpringBoot作为服务端 作为服务端时,需要先导入websocket的依赖 <dependency> <groupId> ...
- 【持续更新】C++ 并不完全是 C 的超集!
一些容易被忽略的 C 与 C++ 的不兼容特性 头文件和命名空间 C 标准库头文件名在 C++ 中通常去除扩展名,并加上 c 前缀,如: stdio.h -> cstdio stdlib.h - ...
- netstat 某连接的 Recv-Q(接收队列)达到500多万字节的内核参数排查
思路: cat proc文件系统下的 sys/net 目录下所有文件,根据结果降序排序(如果打印前xx,可能会漏掉关键信息,在定位问题时需要注意,慎用过滤),根据结果使用 grep -rn xxx 找 ...
- 安装.NET Framework4.5以上版本受阻怎么办?
安装和卸载 .NET Framework 受阻疑难解答 - .NET Framework | Microsoft Learn Windows RT 8.1.Windows 8.1 和 Windows ...