zoukankan      html  css  js  c++  java
  • 精简《JavaScript高级程序设计》四 、变量,作用域,内存问题

    精简《JavaScript高级程序设计》四 、变量,作用域,内存问题

    第四章概况

    4.1基本类型和引用类型的值

    4.2执行环境及作用域

    4.3垃圾收集

    4.1基本类型和引用类型

    ES变量包含基本类型值引用类型值

    基本类型指的是简单的数据段,包括Undefined、Null、Boolean、Number、String

    引用类型值指的是那些可能由多个值构成的对象,包括Object,可以添加属性和方法

    ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型

    复制变量值

    对于基本类型而言,如果从一个变量向另一个变量复制,会在变量对象上创建一个新值,然后将该值复制到为新变量分配的位置

    var a = 1
    var b = a
    

    在这里插入图片描述

    对于引用类型而言,同样也会复制一份放到为新变量分配的空间中,不同的是这个值实际上是一个指针,指针指向存储在堆中的一个对象,复制结束后,两个变量实际上引用了同一个对象

    var obj1 = new Object()
    var obj2 = obj1
    obj1.name = "fur"
    console.log(obj2.name) //fur
    

    在这里插入图片描述

    传递参数

    注意:访问变量有按值和按引用两种方式,而参数只能按值传递

    传递基本类型时会把值复制给一个局部变量(命名参数),传递引用类型时会把这个值在内存在的地址复制给一个局部变量,因此这个局部变量的变化会反映函数外部

    function add(num){
    	num +=10
    	return num
    }
    var count = 20
    var result = add(count)
    console.log(result)//30
    console.log(count)//20
    

    因此基本类型不会印象函数外部的count变量,但是引用类型会改变

    function setNum(obj){
        obj.num =30
    }
    var count = new Object()
    count.num = 20
    setNum(count);
    console.log(count.num)//30
    

    很多人错误理解为引用类型的参数是引用传递,其实是按值传递的,再看修改后的代码

    function setNum(obj) {
    		obj.num = 30
    		console.log(obj) //Object { num: 30 }
    		obj = new Object()
    		obj.num = 40
    		console.log(obj) //Object { num: 40 }
    	}
    	var count = new Object()
    	count.num = 20
    	setNum(count);
    	console.log(count) //Object { num: 30 }
    	console.log(count.num) //30
    

    如果count是引用类型传递,那么count就会自动被修改为指向40,所以证明是值传递,实际上,函数内部重写obj,这个变量引用就是一个局部对象,函数执行完立即销毁。

    书里这个地方说得有点理所当然,所以又找了找别的解释:

    关键在于obj = new Object()则会个地方会覆盖obj保存的指向count的地址值,使其指向新地址,那么此时的obj已经是一个局部变量,而且地址的改变使你无论对它进行什么操作都不会影响到原来的obj上面来。

    在这里插入图片描述

    检测类型

    typeof:适用于检测基本类型

    instanceof:适用于检测引用类型

    var name = "fur"
    var u
    var n = null
    var o = new Object()
    console.log(typeof name)//string
    console.log(typeof u)//undefined
    console.log(typeof n)//object,这个需要注意
    console.log(typeof o)//object
    

    instanceof:适用于检测引用类型

    var arr = new Array()
    var o = new Object()
    console.log(arr instanceof Array)//true
    console.log(arr instanceof Object)//true  因为Object包括Array
    console.log(o instanceof Array)//false
    console.log(arr instanceof Object)//true
    

    4.2执行环境及作用域

    执行环境定义了变量或函数有权访问的其他数据,决定它们自身的行为,每个执行环境都有与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象里。

    作用域链:保证对执行环境有权访问的所有变量和函数的有序访问,即可以访问自己以及自己父级以上的变量

    通过代码说明

    var name = "fur"
    function changeName(){
    	if(name === "fur"){
    		name = "fur1"
    	}else{
    		name = "fur2"
    	}
    }
    changeName();
    console.log(name)//fur1
    

    由此,changeNamed的作用域链包括自己的变量对象和全局环境的变量对象。

    没有块级作用域,这个专指var,作用域只能限制在函数内,而无法像Java一样限制在块级内,但是ES6已经出现了let和count两种新的声明变量的方法,可以实现块级作用域,let可以修改,count不可修改

    4.3垃圾收集

    JavaScript具有自动垃圾收集机制

    原理:找到不再使用的变量,释放其内存,垃圾收集器会按照固定的时间间隔周期性执行,方式主要有标记清理

    标记清除:变量进入环境打上标记“进入环境”,离开环境打上标记“离开环境”

    管理内存

    接触引用:数据不在用,可以将其值设置为null,用于全局变量和对象,局部的离开执行环境会被自动解除引用。

    注意:解除引用不等于回收该值所占内存,还是需要等待垃圾收集器

    码字不易,有用的话点个赞鸭!

    精简《JavaScript高级程序设计》五、引用类型(上)

    回顾《JavaScript高级程序设计》目录篇

  • 相关阅读:
    UOS系统进入单用户模式解决su: 鉴定故障和sudo: /usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位
    统一UOS操作系统 修改源地址
    linux cmake error no version information available
    Linux error /usr/bin/ld: cannot find -lJsoncpp
    容器时代的持续交付工具---Drone:Drone使用
    容器时代的持续交付工具---Drone:Drone介绍与安装
    asp.net core 中灵活的配置方式
    View Components as Tag Helpers,离在线模板编辑又进一步
    asp.net core mvc中如何把二级域名绑定到特定的控制器上
    提供服务注册描述信息来简化服务注册方式
  • 原文地址:https://www.cnblogs.com/furfur-jiang/p/12238721.html
Copyright © 2011-2022 走看看