升级打怪-精读javascript高级程序设计(第四章)

变量,作用域和内存问题

  • 理解基本类型和引用类型的值
  • 理解执行环境
  • 理解垃圾收集

基本类型和引用类型的值

动态属性

  • 定义基本类型和引用类型的方式类似
  • 操作基本类型和引用类型的方式不同
    • 基本类型,无法动态添加属性
    var name=“tom”;
    name.age=27;
    console.log(name.age);//undefined
    
    • 引用类型值可以动态添加属性
    var person = new Object();
    person.name="tom";
    console.log(person.name);//tom
    

复制变量值

操作:从一个变量向另一个变量复制基本类型和引用类型

  • 基本类型的值,保存的是变量的副本,两个变量完全独立,改变其中一个,不会影响另一个
var num1=5;
var num2=num1;
var num2=6;
//互不影响
console.log(num1);//5
console.log(num2);//6
  • 引用类型的值,保存的是对象指针的副本,改变其中一个,会影响另一个
var obj1=new Object();
var obj2=obj1;
//有影响
obj1.name="tom";
console.log(obj2.name);//"tom"

传递参数

按值传递

值”的含义:
这里的值,指的是,复制传进来的对象的地址,把这个复制值赋给参数

引用传递的含义:
直接将变量本身的地址传进去,直接把传进来的对象的地址传给参数

参数传递的过程:

  • 把传进来的对象的地址复制一份
  • 把这个复制出来的值传给参数
  • 参数和传进来的对象访问的是一个地址,对参数进行操作会表现在对象上

结合代码进行理解:

function setName(obj) {
    obj.name = 'XX'; // 对obj进行操作会表现在person上
    obj = new Object(); // 这里obj的引用改变了,如果传递的是引用,那么person的地址也会改变,也就是说,接下来对obj的操作,也会表现在person上
    obj.name = 'YY';
}
let person = new Object();
setName(person);

检测类型

typeof
  • 非常适合检测基本类型
	console.log(typeof "123");//string
    console.log(typeof 456);//number
    console.log(typeof false);//boolean
    console.log(typeof undefined);//undefined
  • 对引用类型检测有点鸡肋
 	console.log(typeof null);//object
    console.log(typeof {});//object
instanceof
  • 适合引用类型检测
	 let arr=[];
    console.log(arr instanceof Array);//true

    let reg=/^\d/
    console.log(reg instanceof RegExp);//true

执行环境及作用域

示例:

var color=“bule”;
function changeColor(){
	var anotherColor=“red”;
	function swapColors(){
		var tempColor=anotherColor;
		anotherColor=color;
		color=tempcolor;
		//这里可以访问color,anotherColor和tempColor
	}
	这里可以访问color,anotherColor,但不能访问tempColor
	swapColor();
}
//这里只能访问color
changeColor()

分析执行环境

  • window
    • color
    • changeColor
      • anotherColor
      • swapColors
        • tempColor
  • 内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量核函数
  • 这些环境都是线性的,有次序的,每个环境都可以向上搜索作用域链,查询变量和函数;但任何环境不能通过向下搜索作用域链而进入另一个执行环境。

延长作用域链

  • try-catch语句的catch快
  • with语句

没有块级作用域

声明变量
  • 使用var 声明变量会被自动添加到最接近的环境中,在函数中,最接近的环境是函数环境
function(num1,num2){
	var sum=num1+num2;
	return sum;
}
var result=add(10,20);//30
console.log(sum);//由于sum不是有效的变量,因此会导致错误
  • 初始化变量时没有使用var声明,该变量就会被添加到全局环境
function(num1,num2){
	var sum=num1+num2;
	return sum;
}
var result=add(10,20);//30
console.log(sum);//30
查询标识符

示例

var color=“bule”;

function getColor(){
return color;
}
console.log(getcolor());//"bule"

查询过程

  • 搜索getColor,查找color,没有继续向上搜索
  • 搜索全局对象,查找到color,所以搜索结束。

垃圾收集

标记清除

定义

当变量进入环境时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。当变量离开环境时,则将其标记为“离开环境”。

标记清除算法分为标记和清除两个阶段.这个算法假定设置一个叫做根(root)的对象(在 Javascript 里,根是全局对象).垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象,然后对这些对象进行标记……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象.之后进入了清除阶段,标记的对象会与内存中的对象进行比较,然后清除内存中那些没有标记的对象

  • 标记阶段,它将遍历堆中所有对象,并对存活的对象进行标记;
  • 清除阶段,对未标记对象的空间进行回收.

引用计数

定义

跟踪记录每个值被引用的次数,当声明了一个变量并将一个引用类型赋给该变量时,则这个值的引用次数就是1.如果同一个值又被赋给另一个变量则该值的引用次数加1.相反这个值的引用的变量又取得另一个值.则这个值的引用次数减1.

  • 最大的问题:循环引用是对象A中包含一个指向对象B的指针而对象B中包含一个指向对象A的引用
function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值