《JavaScript 高级程序设计(第3版)》学习笔记:第4章 变量、作用域和内存问题(补充)

4.1 基本类型和引用类型

基本类型有5种:undefined、null、boolean、number、string  占据固定内存空间,保存在栈内存中

引用类型的值即对象  保存在栈内存中 按引用访问

4.1.1 动态的属性

只能给引用类型动态的加属性,不能给基本类型加。

var person = new Object(); 
person.name = "Nicholas"; 
alert(person.name); //"Nicholas" 

var name = "Nicholas"; 
name.age = 27; 
alert(name.age); //undefined 

4.1.2 复制变量值

基本类型和引用类型均为值复制。区别看图:

《JavaScript 高级程序设计(第3版)》学习笔记:第4章 变量、作用域和内存问题(补充)_第1张图片

图4-1为基本类型复制

《JavaScript 高级程序设计(第3版)》学习笔记:第4章 变量、作用域和内存问题(补充)_第2张图片

图4-2为引用类型复制

4.1.3 传递参数

基本类型和引用类型全部为值传递。

在向参数传递基本类型是,被传递的值会被复制给一个局部变量(即命名参数,ECMAScript中及arguments对象的元素)

传递引用类型时,把被传的对象在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数外部。

function addTen(num) { 
 num += 10; 
 return num; 
} 
var count = 20; 
var result = addTen(count); 
alert(count); //20,没有变化
alert(result); //30 

function setName(obj) { 
 obj.name = "Nicholas"; 
} 
var person = new Object(); 
setName(person); 
alert(person.name); //"Nicholas" 

思考一下下面的代码,可以说明对象是按值传递的(若为按引用传递则person会被修改为指向其name属性为grey的新对象)

function setName(obj) { 
 obj.name = "Nicholas"; 
 obj = new Object(); 
 obj.name = "Greg"; 
} 
var person = new Object(); 
setName(person); 
alert(person.name); //"Nicholas

4.1.4 检测类型

之前第三章提到检测基本类型可以typeof操作符,但是对于引用类型来讲所有都会返回object

那么如何知道引用类型到底是什么类型的对象呢?就要用到 instanceof 操作符了。

result = variable instanceof constructor

alert(person instanceof Object); // 变量 person 是 Object 吗?
alert(colors instanceof Array); // 变量 colors 是 Array 吗?
alert(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?

如果是,则返回true;

不是,则返回false。

注:如果是检测基本类型,则返回false,因为基本类型不是对象。

4.2 执行环境与作用域

可能因为自己对js的了解太浅薄,所以这一节不是很理解,在此写下自己的一些大概印象,之后再补充,如果有不对的地方希望指正。

执行环境相当于一个范围,在这个范围中有在这个环境中定义的变量和函数,这些保存在于执行环境一一对应的变量对象中。

在执行环境中的代码执行完毕后,该环境就会被销毁,保存在其变量对象中的内容也被销毁。

全局执行环境是最外围的执行环境,当关闭网页或浏览器时才会被销毁。

每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入环境栈中,执行之后被弹出。

在代码在一个环境中执行时,会创建变量对象的一个作用域链,用途是保证执行环境有权访问的所有变量和函数的有序访问。

作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即 arguments 对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止(如果找不到标识符,通常会导致错误发生)。

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(); 

《JavaScript 高级程序设计(第3版)》学习笔记:第4章 变量、作用域和内存问题(补充)_第3张图片

图4-3 上面代码的作用域链

 

待续

你可能感兴趣的:(《JavaScript 高级程序设计(第3版)》学习笔记:第4章 变量、作用域和内存问题(补充))