JavaScript学习笔记—— 4. 变量、作用域和内存问题

  1. ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值,其中基本类型值是简单的数据段,而引用类型值指的是那些可能由多个值构成的对象;
  2. 对于5种基本类型数据:undefined, null,boolean,number和string,采用按值访问,因为可以操作保存在变量中的实际的值;
  3. 对于引用类型的值而言,JavaScript并不能直接访问内存中的位置,也就是说不能直接操作对象的内存空间,在操作对象时,实际上是在操作对象的引用而非实际的对象。
  4. 在从一个变量向另一个变量复制基本类型值和引用类型值的时候,也存在不同:
    • 如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上(所以对新创建的变量的值的操作,不会影响原先的变量);
    • 当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。实际上这个值的副本是一个指针,指向存储在堆中的一个对象,所以结果是两个变量实际上引用同一个对象,所以改变其中一个变量,将对另一个变量也产生同样的影响。
  5. ECMAScript中的所有函数的参数传递,都是按值传递的。即:把函数外部的值复制给函数内部的参数。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。
  6. instanceof: result  =  variable instanceof constructor;
    • alert(person instanceof Object); //变量person是Object么
    • alert(person instanceof Array); //变量person是Array么
  7. 作用域链(scope chain):保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终是当前执行的代码所在环境的变量对象,如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象。下一个变量对象来自包含(外部)环境,而再下一个对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
  8. 使用var声明的变量会自动添加到最接近的环境中。
  9. 基本类型值和引用类型值具有以下特点:
    • 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
    • 从给一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;
    • 引用类型值是对象,保存在堆内存中;
    • 包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向这个值的一个副本;
    • 从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象;
    • 确定一个值是哪一种基本类型可以使用typeof操作符,而确定一个值是哪一种引用类型可以使用instanceof操作符、
  10. 关于执行环境:
    • 执行环境有全局执行环境(也称为全局环境)和函数执行环境之分;
    • 每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;
    • 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;
    • 全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;
    • 变量的执行环境有助于确定应该何时释放内存;
  11. 关于JavaScript的垃圾收集例程:
    • 离开作用域的值将被自动标记为可以回收,因此在垃圾收集期间被删除;
    • “标记清除”是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后在回收内存;
    • “引用计数”垃圾收集算法是跟踪记录所有值被引用的次数,JavaScript引擎目前都不再使用这种算法;
    • 解除变量的引用(比方说:var globalVar = createdVar(“things”); globalVar = null;)有助于消除循环引用的现象,并且有益于垃圾收集。为了确保有效地回收内存,应该及时接触不再使用的全局对象、全局对象属性以及循环引用变量的引用。
时间: 2024-11-03 21:14:53

JavaScript学习笔记—— 4. 变量、作用域和内存问题的相关文章

JavaScript学习笔记——js变量的布尔值

typeof(1): numbertypeof(NaN): numbertypeof(Number.MIN_VALUE): numbertypeof(Infinity): numbertypeof("123"): stringtypeof(true): booleantypeof(window): objecttypeof(Array()): objecttypeof(function(){}): functiontypeof(document): objecttypeof(null)

php学习笔记0001 变量作用域

<?php/*2015-8-6php学习笔记0001函数之外声明的变量拥有 Global 作用域,只能在函数以外进行访问.函数内部声明的变量拥有 LOCAL 作用域,只能在函数内部进行访问. */$x = 5;function ast(){ /* 声明局部变量 输出结果为6 */ $x = 6; echo $x;}function beli(){ /* 没有声明局部变更 函数内部无法访问全局变量 编译正常 调用报错 */ echo $x;}ast();//输出6//beli();//会报错ech

第一百零六节,JavaScript变量作用域及内存

JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. 一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈

javascript学习笔记---ECMAScript-判断变量类型

判断类型之前,先要清楚有哪些类型. (理理思路:程序由数据和方法构成,数据由简单数据和复杂数据构成) 即类型有: 数据(简单数据:boolean,string,num,undefined,null.复杂数据:object), 方法(function) 万能的typeof,神一样的方法 typeof(1);// num typeof("hello");// string   typeof(false);// boolean var vFlag; typeof(vFlag);// unde

javascript学习笔记---ECMAScript语法(变量)

变量声明关键字var: var i = 1: var t = "asd"; var test1 = "hi", test2 = "hello"; 声明变量不一定要初始化, var i;//ok 另一方面在使用变量前若未加关键字var,则此变量为全局变量(此特性需特别记住). 变量名字: 变量名需要遵守两条简单的规则: 第一个字符必须是字母.下划线(_)或美元符号($) 余下的字符可以是下划线.美元符号或任何字母或数字字符 命名变量规则: Came

javascript学习日记之变量的作用域

``` 很显然第一个弹出框并没有如我所想弹出的global而是undefined 这是为什么呢? 其实由于函数作用域特性 函数域始终优于全局域 同名的局部变量会覆盖掉全局变量 而第一次调用alert的时候scope还没正式定义 所以为undefined 以上代码可以理解为: ``` function f(){ var scope; alert(scope); var scope ="local"; alert(scope); }; f(); //等价与函数内变量的声明'提前'至函数体顶

javascript变量作用域与内存

第四章 变量作用域与内存基本类型 5种Undefined Null Boolean Number String 两种变量类型 基本类型与引用类型注意:String 再其他语言中是引用类型,再javascri中为基本类型即:这五种基本类型是按值访问的 引用类型是按照引用访问的 动态的属性对于一个引用类型,一个引用变量被赋值后,可以为其添加属性,也可以删除与修改其属性var o = new object();o.name = "qi"; //可以为引用变量添加属性 变量的复制基本类型的复制

JavaScript学习笔记【3】数组、函数、服务器端JavaScript概述

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 数组 函数 服务器端JavaScript概述 数组 数组是动态的:根据需要它们会增长或缩减,并且在创建数组时无须声明一个固定的大小或在数组大小变化时无须重新分配空间. 数组可能是稀疏的:索引不一定要连续的,它们之间可以有空缺. 通常,数组的实现是经过优化的,用数字索引来访问数组元素一般来说比访问常规的对象属性要快很多. 数组继承自Array.prototype中的属性,它定义了一套丰富的数组操作方法. 如果省略数组直接量中的某个

javascript学习笔记---ECMAScriptECMAScript 对象----定义类或对象

使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 原始的方式 因为对象的属性可以在对象创建后动态定义(后绑定),类似下面的代码: var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };不过这里有一