小红书阅读笔记~第四章(变量,作用域和内存问题)

本章重点

1.理解基本类型和引用类型的值。
2.理解执行环境
3.理解垃圾收集

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

ECMAScript: 它的变量包含了两种不同数据类型的值,基本类型值和引用类型值。
基本类型:基本类型的值指的是简单的数据段。我们在赋值给变量时,解析器必须确定这个值是基本类型值还是引用类型值。上一章说了五种基本数据类型:Undefined、Null、Boolean、Number、String。
引用类型:引用类型的值指的是那些可能由多个值构成的对象,是保存在内存中的对象。与其他语言不一样,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作时实际上是在操作对象的引用而不是实际的对象。所以,引用类型的值是按引用访问的。

在很多语言中,字符串以对象的形式来表示,因此被认为是引用类型的。ECMAScript放弃了这一传统。

动态的属性

定义基本类型值和引用类型值的方式是类似的:创建一个变量并为该变量赋值。如果这个值保存到变量中以后,对不同类型值可以执行的操作则大相径庭。对于引用类型的值,我们可以为其添加属性和方法。
例如:var person = new Object();
     person.name = "Nicholas";
     alert(person.name);       //*Nicholas*
创建了一个对象并将其保存在变量person中,然后,我们为该对象添加了一个名为name的属性,并将字符串值"Nicholas"赋给了这个属性。紧接着,又通过alert()函数访问了这个新属性。如果对象不被销毁或者这个属性不被删除,则这个属性将一直存在。

但是,我们不能给基本类型的值添加属性,尽管这样做不会当值任何错误。

例如:var name = "Nicholas";
     name.age = "4";
     alert(name.age);       //undefined
在这个例子中,我们为字符串name定义了一个名为age的属性,并为该属性赋值27.但在下一行访问这个属性时,发现该属性不见了。这说明只能给引用类型值动态地添加属性,以便将来使用。

复制变量值

除了保存的方式不同之外,在从一个变量向另一个变量复制基本类型值和引用类型值时,也存在不同。如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到新变量分配的位置上。
例如:var num1 = 5;
      var age = num1;

检测类型

我们想去检测一个变量是不是数据类型的话,第三章里边介绍过typeof,他是最佳的工具。typeof操作符是确定一个变量是字符串、数值、布尔值,还是undefined。如果变量是null或者object的话,则typeof操作符会返回object。
例如:var h = "huang";
     var j = true;
     var i = 54;
     var m;
     var o = null;
     var n = new Object();
     alert(typeof h);      //string
     alert(typeof j);      //number
     alert(typeof i);      //boolean
     alert(typeof m);      //undefined
     alert(typeof o);      //object
     alert(typeof n);      //object
一般我们想知道某个值是对象,而是想知道他是什么类型的对象。为此ECMAScript还为开发者提供了instanceof操作符。instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例。通俗来将就是判断一个实例对象是否由某个构造函数构造而来。
例如:result = obj instanceof constructor
     1.obj必须为引用类型,不能是基本类型。
     2.obj在其原型链中是否存在一个构造函数的 prototype 属性

执行环境及作用域

执行环境(有时也成为“环境”,有的地方也翻译为执行上下文)是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为。每个环境都会有与它相关的变量对象,环境中定义的所有的变量或函数都会保存在这个对象里。但是我们访问不到这个对象,只有解析器会在处理数据的时候使用它。
执行环境一般分为三种(书中说了比较推荐的两种):

1.全局执行环境:全执行环境被认为是window对象,因此所有全局变量和函数都作为window对象的属性和方法创建的。直到应用程序退出 —— 例如关闭网页或者浏览器 —— 这时才会被销毁。
2.函数执行环境:函数执行环境中的所有代码执行完,该环境会被销毁,保存在其中的所有变量和函数定义也随之销毁。
3.evel: (不建议使用,忽略);

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。在执行函数之后,栈将其环境弹出,把控制权返给之前的执行环境。ECMAScript程序中执行流就是这个机制来控制。

自己总结一下:
● js是单线程的;
● 同步执行,只有栈顶的环境处于执行中,其他上下文需要等待
● 全局环境只有唯一的一个,它在浏览器或页面关闭时出栈
● 函数的执行环境的个数没有限制
● 每次某个函数被调用,就会有个新的执行环境为其创建,即使是调用的自身函数,也是这样。

你可能感兴趣的:(小红书阅读笔记~第四章(变量,作用域和内存问题))