JavaScript高级程序设计笔记 - 第四章 变量 做用域 内存问题

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

  • 基本类型: 简单的数据段
  • 引用类型: 指那些可能有多个值构成的对象, 指保存在内存中的对象

4.1.2 复制变量值

  • 除了保存的方式不一样以外,在从一个变量向另外一个变量复制基本类型值和引用类型值时,也存在不一样
  1. 基本类型: 若是从一个变量向另外一个变量复制基本类型的值,会在变量对象上建立一个新值,而后把该值复制到为新变量分配的位置上 javascript

    基本类型复制

  2. 引用类型: 当从一个变量向另外一个变量复制引用类型的值时,一样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不一样的是,这个值的副本其实是一个指针,而这个指针指向存储在堆中的一 个对象。复制操做结束后,两个变量实际上将引用同一个对象。所以,改变其中一个变量,就会影响另 一个变量 前端

    引用类型复制

4.1.3 传递参数

  • 传递基本类型
function addTen(num) {
        num += 10
        return num;
    }
    var count = 20
    var result = addTen(count)
    console.log(count) // 20, 没有变化
    console.log(result) // 30
复制代码
  • 传递引用类型
function setName(obj) {
        obj.name = "Nicholas"
    }
    var person = new Object()
    setName(person);
    console.log(person.name) // "Nicholas"
复制代码
// 为了证实对象是按值传递的
    function setName(obj) {
        obj.name = "Nicholas"
        obj = new Object()
        obj.name = "Greg"
    }
    var person = new Object()
    setName(person);
    console.log(person.name) // "Nicholas"
复制代码

4.1.4 检测类型

  • typeof: 检测基本数据类型, string, number, boolean, undefined,object(对象, null)
  • instanceof: 检测引用类型, 什么类型的对象, 全部引用类型的值都是 Object 的实例

4.2 执行环境及做用域

  • 执行环境定义了**函数和变量有权访问的其余数据, 每一个执行环境都有与之对应的变量对象**, 环境中定义的变量和函数都定义在这个对象中
  • 全局环境是最外层的执行环境, 在web浏览器中被认为是**windows**对象,由于全部的全局变量和函数都做为window 对象的属性和方法,执行环境中的代码执行完毕后,该环境被销毁,其中的全部变量和函数定义也随之销毁
  • 每一个函数都有本身的执行环境, 当执行流进入某个函数时, 函数的执行环境就会就会进入环境栈, 函数执行完毕后,环境出栈, 把控制权交给以前的执行环境
  • 当代码在某个环境中执行, 会建立变量对象的**做用域链, 做用域链保证对执行环境有权访问的全部变量和函数的有序访问, 做用域链的前端始终是当前执行环境的变量对象,最后一个对象是全局环境中的变量对象**, 若是这个环境是函数,则将其活动对象做为变量对象. 活动对象最开始只包含arguments对象(全局环境不存在)
var color = 'blue'
    function changeColor() {
        if (color === 'blue') {
            color = 'red'
        } else {
            color = 'blue'
        }
    }
    changeColor()
    console.log(color)
    
    // changeColor() 函数中包含本身的变量对象和全局环境的变量对象
复制代码
var color = "blue";
        function changeColor(){
            var anotherColor = "red";
            function swapColors(){
                var tempColor = anotherColor;
                anotherColor = color;
                color = tempColor;
                    // 这里能够访问color、anotherColor和tempColor 
        }
            // 这里能够访问color和anotherColor,但不能访问tempColor
            swapColors();
    }
    // 这里只能访问color 
    changeColor();
复制代码

函数的做用域链图 java

4.2.1 延长做用域链

当执行流进入下列任何一个语句时,做用域链就会获得加长:web

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

这两个语句都会在做用域链的前端添加一个变量对象,对with语句来讲,会将指定的对象添加到做用域链中.对catch语句来讲,会建立一个新的变量对象,其中包含的是被抛出的错误对象的声明windows

4.2.2 没有块级做用域

javascript没有块级做用域浏览器

if (true) {
        var color = "blue"
    }
    console.log(color) // blue
    // javascript中, if 语句中的变量声明会将变量添加到当前的执行环境中
复制代码
function func() {
        if (true) {
            var color = "blue"
        }
        console.log(color) 
    }
    func() // blue
    console.log(color) // error
    // color 添加到了func执行环境中,并无添加到window执行环境中
复制代码
for (var i = 0; i < 10; i++) {
        ......
    }
    console.log(i) // 10
复制代码
  • 声明变量 var 声明的变量会被添加到最近的环境中,在**函数内部就是最近的环境就是局部环境; 在with语句中就是函数环境, 若是初始化变量没有使用var则被添加到全局环境**中
function add(num1, num2) {
        var sum = num1 + num2
        return sum
    }
    var result = add(10, 20) // 30
    console.log(sum) // error
复制代码
function add(num1, num2) {
        sum = num1 + num2
        return sum
    }
    var result = add(10, 20) // 30
    console.log(sum) // 30
复制代码
  • 标识符查询 在某个环境中为了读取或者写入而引入一个标识符,必须经过搜索来肯定该标识符的意思, 搜索过程从当前做用域前端开始逐步向上查找直至全局做用域为止
var color = 'blue'
    function getColor() {
        return color
    }
    console.log(getColor()) // 'blue'
复制代码

搜索过程以下 函数

搜索过程以下
相关文章
相关标签/搜索