JavaScript 3 变量及作用域
1.ECMAScript变量
包含两种不同类型的值:基本类型值和引用类型值。
基本类型值:简单的数据段(Undefined,Null,Boolean,Number,String)
引用类型值:多个值构成的对象(Object,Array,Data,RegExp,Function)
2.两种变量区别:
①属性和方法
可以为引用类型值添加属性和方法,基本类型值不能。例如:
var name = “Bill”;
name.age = 27;
alert(name.age); //undefined
var person = new Object();
person.name = “Bill”;
alert(person.name); //”Bill”
②复制变量值
a基础类型值的复制,创建一个新值,并将该值复制给新变量。该新值是实际数值。
var num1 = 5;
var num2 = num1;
注:num1与num2独立的,没有任何关系。
b引用类型值的复制,创建一个新值,并将该值复制给新变量。该新值是指针。
引用类型值保存的是指针,指向存储在堆中的对象。
var obj1 = new Object();
var obj2 = obj1;
obj1.name = “Bill”; //改的是对内存中的对象。
alert(obj2.name); //因为obj2的指针值与obj1一样,所以obj2.name也是”Bill”
注:obj1改变=>堆内存对象改变=>obj2改变,而不是obj1改变=>obj2改变。
3.两种变量相同点:传递参数
ECMAScript中所有函数的传递参数都是按值传递的。没有按引用传递这种方式。
注:所谓的按引用传递,是其他语言的一种方式,例如:
void swap(int& num){
num++;
}
调用时,int x=3; swap(x);结果x=4;
即:num是x的别称,任何时候都同步变化,对num的任何操作都作用于x。
a基本类型值
function add(num){
num+=10;
return num;
}
var count = 10;
var result = add(count);
alert(count); //10
alert(result); //20
注:connt与num没有关系,是独立的,只是某一时刻值相等罢了。
b引用类型值
function setName(obj){ //person的值(指针)与obj的值(指针)相等
obj.name = “Bill”; //改变了指针所指对象,所以person.name也变为”Bill”
obj = new Object(); //obj的值与person的值不在相等。
obj.name = “Grey”;
}
var person = new Object();
setName(person);
alert(person.name); //”Bill”
注:person与obj没有关系,是独立的,只是某一时刻值相等罢了。
4.检测变量类型
var x = “Bill” | alert(typeof x); | string |
var x = true; | alert(typeof x); | boolean |
var x = 12; | alert(typeof x); | number |
var x; | alert(typeof x); | undefined |
var x = null; | alert(typeof x); | object |
var x = new Object; | alert(typeof x); | object |
var x = new Object; | alert(x instanceof Object); | true |
var x = new Array; | alert(x instanceof Array); | true |
var x = new RegExp; | alert(x instanceof RegExp); | true |
5.执行环境与作用域
执行环境:函数有权访问的数据。
作用域链:来保证对执行环境有权访问的变量和函数的有序访问
var color = “blue”;
function changeColor(){
var anotherColor = “red”;
function swapColors(){
var temp = anotherColor;
anotherColor = color;
color = temp;
//可以访问color anotherColor temp
}
//可以访问color anotherColor
}
//可以访问color
解释:
以上代码涉及了3个执行环境:全局环境,changeColor()的局部环境,swapColors()的局部环境。
作用域链示意图:
规则:
1内层环境可以访问外层的数据,外层不能访问内层
2永远只能向上访问,不能向下访问
3在某环境中,为了读取/写入而引用一个标识符时,要通过搜索确定标识符意义。搜索是有次序的,通过作用域链,从本环境开始,逐级向上搜索,直到找到标识符为止(找不到会导致错误)。所以当全局变量与局部变量重名时,函数外用全局变量,函数内用局部变量。具体参见:JavaScript 3.1 补充:谈谈JS的全局变量跟局部变量(转载)