一、基本类型和引用类型的值
ECMAScript变量可能包含两种不同数据类型的值,基本类型值和引用类型值,基本类型值指的是简单的数据段,引用类型值是指那些可能由多个值构成的对象。
将一个值赋值给变量时,解析器必须确定这个值是基本类型值还是引用类型值,基本类型值是按值访问的,因为可以操作保存在变量中实际的值。
引用类型的值是保存在内存中的对象,与其他语言不通,javascript不允许直接访问内存中的位置,也就是说不能直接操作象的内存空间,在操作对象时,实际上是在操作对象的引用而不是实际的对象,引用类型的值是按引用传递的。String不是按引用传递的。
1、动态的属性
定义基本类型值和引用类型值的方式是类似的:创建一个变量并为该变量赋值,但是,当这个值保存到变量中以后,对不同类型值可以执行的操作则有很大差距,对于引用类型,我们可以为其添加属性和方法,也可以改变和删除其属性和方法:
var person = new Object()
person.name = "NICE";
alert(person.name);
以上代码创建了一个对象并将其保存在变量person中,然后我们为该对象添加了一个名为name的新属性并赋值。紧接着又使用alert来访问他,如果对象不被销毁或者这个属性不被删除,那么这个属性将会一直存在。
但是,我们不能给基本类型添加属性,尽管他不会报错。
2、复制变量值
除了保存的方式不同之外,从一个变量向另一个变量复制基本类型值和引用类型值时,也存在不同,如果从一个变量向另一个变量复制基本类型的值,也存在不同,如果从一个变量向另一个变量赋值基本类型的值,会在新变量对象上创建一个新值,然后把该值复制到为新变量的位置上。
当从一个变量向另一个变量复制引用类型的值的时候,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象,复制操作结束后,两个变量实际上引用的是同一个对象,因此改变其中一个对象,就会影响另外一个变量。
3、传递参数
ECMAScript中所有函数的参数都是按值传递的,也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递就和基本类型的复制一样,引用类型值的复制就和引用类型值的复制一样。
按共享传递,不会修改引用本身,但是会修改引用对象的属性。
4、检测类型
检测类型可以用typeof,如果变量值是一个对象或者null,那么typeof会返回object。
但是该操作符实际意义并不大,因为我们往往想知道这个对象是什么类型的对象而不是这个是否是对象,所以我们可以使用instanceof。
result = variable instanceof construcotr
如果变量时给定引用类型的实例,那么instanceof就会返回true。
根据规定,所有引用类型的值都是object的实例,因此,在检测一个引用类型值和object构造甘薯时,instanceof始终会返回true。
二、执行环境和作用域
执行环境是javascript中最为重要的一个概念,执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为,每一个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中,虽然我们编写的代码无法访问这个对象,但解析器在处理数据时都会在后台使用他。
全局执行环境是最外围的一个执行环境,根据ECMAScript实现所在的宿主环境不停,表示执行环境的对象也不一样。在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。(全局执行环境知道应用程序退出--例如关闭网页或者浏览器时才被销毁)。
每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行之后,栈将环境弹出,把控制权返回之前的执行环境。
当代码在一个环境中执行的时候,会创建该变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行代码所在环境的变量对象,如果这个环境是函数,则将其活动对象作用变量对象。活动对象在最开始只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含外部环境,而再将下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的变量对象始终都是作用域链中的最后一个对象。
标识符解析是沿着作用域链一级一级地搜索标识符的过程,搜索过程始终从作用域链的前端开始,然后逐级回溯。
三、没有块级作用域
例如:
if(true){
var color = "blue"
}
alert(color); // blue
在JavaScript中,if语句的变量声明会将该变量添加到当前的执行环境中,在使用if语句尤其要记得该差异。
for(var i =0; i < 10; i++){
dosomething(i)
}
alert(i) //10
1、声明变量
使用var声明的变量会自动被添加到最接近的环境中,在函数内部就会自动添加到函数的局部变量中,如果初始化变量时没有使用var声明,该变量会自动添加到全局环境中。
2、查修标识符