Javascript学习笔记:变量、作用域、内存、预解析、垃圾收集

1.变量

基本类型:数字、字符串、布尔值、undefinednull
引用类型:[数组]{对象}
区别:基本类型的值不能修改(可以通过覆盖的形式进行变更),引用类型的值可以修改(可以改变其本身的值)
基本类型为什么可以调用方法?类似于’string’.replace(‘s’,’’)?
基本类型调用方法时会找到其包装类(数字的包装类是Number,字符串的包装类为String),调用其包装类的属性和方法,其本身并没有属性和方法。
变量在内存中如何保存?
基本类型保存在栈内存(有序,固定大小)中,引用类型保存在堆内存(无序、不固定大小)中,其地址保存在栈内存中(因为地址大小固定)
在这里插入图片描述
两种变量访问方式
按值访问、按引用访问
变量相等的比较
基本变量比较值,值相等即相等。
引用类型比较,引用指向同一块内存才相等。
变量值的复制
基本类型直接使用变量名进行赋值操作即可复制值。
引用类型复制需要遍历属性进行复制。
如何检测数据类型?
使用typeof()方法
使用引用名 instanceof 类名判断,注意此方法只能判断引用类型

2.作用域

2.1 全局作用域

函数体外的变量叫做全局变量,在全局作用域中均可访问。

2.2 局部作用域:函数作用域

函数体内的变量叫做局部变量,只能在其所处的函数作用域内访问。

2.3 作用域链

在这里插入图片描述
在这里插入图片描述

2.4 延长作用域链

延长作用于链就是在全局作用域(window作用域)中创造一个小的作用域,以达到延长作用域链的效果。不推荐使用。
在这里插入图片描述
在这里插入图片描述

2.5 JS解析机制:预解析

在这里插入图片描述
打印结果为undefined

JS的解析过程:
(1)预解析
查找window作用域下的所有var变量,并给这些变量赋默认值undefined。再查找function关键字,直接将函数加载(不赋值、不解析,只声明)
预解析是,函数名和变量名冲突时,保留函数;两个函数名冲突,保留最后出现的函数。
(2)逐行解读代码
遇到函数会跳过(因为预解析时已经声明),知道遇到函数调用的语句。
看几个问题加深理解:
问题1:

console.log(a);
var a=1;
//undefined
console.log(a);
a=1;
//报错,因为无法预解析a

问题2:

console.log(a);
var a=1;
console.log(a);
function a(){
	console.log(2);
}
console.log(a);
var a=3;
console.log(a);
function a(){
	console.log(4);
}
console.log(a);
a();

解析过程:

~~var a=undefined;//a=3那一行~~ 
a是一个函数//log(4)的那一个函数
---预解析完成---
a()
1
函数跳过
1
3
函数跳过
3
遇到函数调用语句:a不是函数,因此报错

问题3:

<script>
	console.log(a)
</script>
<script>
	var a=1;
</script>

报错,因为两个script标签分别预解析,即第一个标签内预解析完之后(打印之后),才解析第二个标签。

<script>
	var a=1;
</script>
<script>
	console.log(a)
</script>

打印1,因为a是一个全局变量。
问题4.1:

var a=1;
function fn(){
	console.log(a);
	var a=2;
}
fn();
console.log(a);

打印结果:

undefined
1

解析过程:

a=undefined
fu()
	a=undefined
---预解析完成---
a=1
fn()跳过
fn(),根据作用域链,打印函数体内部的a,即undefined
打印全局变量a=1

问题4.2:

var a=1;
function fn(){
	console.log(a);
	a=2;
}
fn();
console.log(a);

打印结果:

1
2

解析过程:

a=undefined
fu()
	函数内部的a为全局变量,没有var,因此不做预解析
---预解析完成---
a=1
fn()跳过
fn(),根据作用域链,此时函数体内部没有预解析的a,因此打印的是全局变量a=1
	函数体内,全局变量被赋值为2
打印全局变量a=2

问题4.3:

var a=1;
function fn(a){
	console.log(a);
	a=2;
}
fn();
console.log(a);

打印结果:

undefined
1

解析过程:

a=undefined
fu(a)对参数进行预解析 参数a=undefined
	函数内部的a此时为参数
---预解析完成---
a=1
fn(a)跳过
fn(a),根据作用域链,打印函数体内部的参数a,即undefined
	函数体内,参数被赋值为2
打印全局变量a=1

问题4.4:

var a=1;
function fn(a){
	console.log(a);
	a=2;
}
fn(a);
console.log(a);

打印结果:

1
1

解析过程:

a=undefined
fu(a)对参数进行预解析 参数a=undefined
	函数内部的a此时为参数
---预解析完成---
a=1
fn(a)跳过
fn(a),根据作用域链,a=1作为参数被传入函数体内部
	打印参数a=1
	函数体内,参数被赋值为2
打印全局变量a=1

3. JS垃圾收集机制

目标:释放无用数据,回收内存
原理:找出没有用的数据,打上标记,释放其内存;周期性执行
标识无用数据的策略:
标记清除:离开作用域的变量将被清除。
引用计数:引用次数变为0即可回收内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值