ECMAScript中包含两种不同数据类型的值:
1)基本类型值:
1.Undefined,Null,Boolean,Number和String.他们的值在内存中占有固定大小的空间,因此可以把它们的值保存在栈内存中,对于保存基本类型值 的变量,是按值访问的,因为 我们操作的是它们实际保存的值。
2.创建一个变量并为其赋值,不能为其添加属性和方法。
3.向另一个变量复制基本类型的值,比方说将变量num1的值复制给num2,则两个值是完全独立,包括以后参与任何操作都不会相互影响。
ex: var num1=5;
var num2=num1;(则num2的值为5)
4.传递参数 ECMAScript 中所有函数的参数都是按值传递的,其实也就是说把函数外部的值传递给函数内部的参数,基本类型值的传递如同基本类型变量的复制一样。
ex: function addTen(num){
num+=10;
return num;
}
var count=20;
var result=addTen(count);
alert(count); //20 (count的值不会受到函数内部的影响)
alert(result); //30
2)引用类型值:
1.Object类型,它的内存地址(指针)是保存在栈内存中,值保存在堆内存中,通过内存地址再顺藤摸瓜地找到保存在堆中的值 ,称之为按引用访问。
2.创建一个变量为其赋值,对于引用类型的值,我们可以为其添加属性和方法
ex: var person= new Object();
person.name='paul';
alert(person.name); //'paul'
3.向另一个变量复制引用类型的值,比方说将变量obj1的值复制给obj2,将obj1栈中的值(指针)复制一份到obj2空间中,obj1与obj2实际上将引用同一个对象,所以他们的值 会相互影响。
ex: var obj1=new Object();
var obj2=obj1;
obj1.name="Nicholas";
alert(obj2.name) //"Nicholas"
4.可以把ECMAScript的参数想像成局部变量,为了说明所有函数的参数都是按值传递的,我们来看个例子,
ex:function setName(obj){
obj.name="Nicholas";
obj= new Object(); //当在函数内部重写obj时,这个变量引用 的就是一个局部对象了
obj.name="Greg"; //接上,此局部对象会在函数执行完立即被销毁
}
var person=new Object();
setName(person);
alert(person.name); //"Nicholas" (如果是按引用类型传递的话,此处得到的结果应该为Greg)
检测类型:
使用typeof操作符可以检测基本数据类型,包括:string、number、boolean、undefined、object(对于引用类型值,其只会返回object,并不会得到其是什么类型的对象)
所以呢,ECMAScript提供了instanceof操作符(示例如下),如果使用instanceof来检测基本类型的值,则该操作符始终会返回false
ex: result=variable instanceof constructor
alert(person instance of Object) //所有引用类型的值都Object的实例,因此,在检测一个引用类型值和Object构造函数时,instanceof操作符始终会返回true.
执行环境及作用域:
内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数,每个函数都可以向上搜索作用域链,以查询变量和函数名;但任何环境不能 通过向下搜索作用域链而进入另一个执行环境,另函数参数也被当作变量来对待,因此其访问规则与执行环境中的其他变量相同。
ex: var color= "blue";
function changeColor(){
var anotherColor= "red";
function swapColors(){
var tempColor=anotherColor;
anotherColor=color;
color=tempColor;
//tempColor只能在此环境中访问到,可访问父执行环境,即changeColor及全局环境中的所有变量
}
//可访问全局变量color及自己环境内的变量
}
//全局环境
没有块级作用域
在其他C类语言中,由花括号封闭的代码块都有自己的作用域,但在ECMAScript中...,我们可以看一下以下的例子
ex: if(true){
var color="blue";
}
alert(color); //"blue"(可以访问到color)
ex:for(var i=0;i<10;i++){
dosomething(i)
}
alert(i); //10 即使在for循环结束后,也依旧会存在于循环外部的执行环境中。
声明变量
在使用var关键字声明变量时,这个变量将被自动添加到距离最近的可用环境中,对于函数而言,这个最近的环境就是函数的局部环境,如果变量在未经声明的情况下被初始化, 那么该变量会被自动添加 到全局环境。
ex: function add(num1,num2){
var sum=num1+num2;
return sum;
}
var result=add(10,20); //30
alert(sum) //发生错误,如果有声明变量,则得到的结果为"undefined"
ex: function add(num1,num2){
sum=num1+num2;
return sum;
}
var result=add(10,20); //30
alert(sum) //30 但是我们不建议这样做,一定要在初始化变量之前对其进行声明。
查询标识符
ex: var color="blue";
function getColor(){
return color;
}
alert(getColor()) //"blue"
为了确定color的值,将开始一个两步的搜索过程,首先,搜索getColor()的变量对象,在没有找到的情况下,搜索继续到下一个变量(全局环境的变量对象),然后在那里找到了名为color的标识符,搜索过程宣告结束 。如果局部环境中存在着同名标识符,就不会使用位于父环境中的标识符
ex:var color="blue";
function getColor(){
var color="red";
return color;
}
alert(getColor()); //"red"