JS和JAVA, C的最大区别之一就是JS的变量是无类型的。
使用关键字var声明变量,还可以用以下格式:
var i, sum;
如果仅仅是声明,而不进行初始化,变量的值为undefined.
用var关键字声明的变量是永久性的。
多次声明同一变量是合法无害的(注意下面的代码)
var a;
a=10;
var a;
alert(a);//返回10
如果试图读取一个未声明过的变量的值,js会生成错误。
如果试图对一个未声明过的变量赋值,JS会隐式的声明,而且这种隐式声明的变量将是全局变量,即使该变量在函数体内部声明的
与JAVA和C不同的是,只要在同一函数中声明的变量,整个函数内都是有效的,没有括号的限制。
注意以下两段代码,JS的tricky之处尽显无遗啊
var outter="outter!!"; function test(){alert(outter);//显示outter!! }
var outter="outter!!';
function test(){alert(outter); //显示undefinedvar outter = "inner!!"; }
由此可以看出,一旦函数内有和全局变量的同名局部变量,无论它声明的位置与否,进入函数体后该全局变量都将被隐藏。这TM就是要养成良好的习惯,把所有的变量都写在函数体的前面。
元数据对象在内存中分配固定大小的内存区域
引用类型对象在内存中没有固定大小
JS也使用垃圾回收技术。
垃圾回收的目标是不可达对象
JS解析器启动的第一件事,就是创建一个全局对象(global object),这个对象的属性包含所有的全局变量。解析器将初始化该全局变量的一些预置属性,比如Infinity,parseInt,Math等。在客户端JS中,Window对象将作为这个全局对象,window对象包括很多浏览器属性。
var outter = "outter!";function test(){alert(window.outter);//显示outter! }
全局变量是全局对象的属性,而局部变量就是call对象的属性。
当函数体被执行时,它的局部变量和函数参数都作为call对象的属性存储
当JS解析器开始执行一个函数时,它将为该函数创建一个执行上下文,该上下文的一个重要部分就是前面说的call对象,即变量定义的地方。注意!JS允许同时存在多个全局执行上下文,每一个上下文都可以拥有一个不同的全局对象。(这种情况下,全局对象实际上不是全局的),一个典型的例子是,不同的frame或者多个浏览器窗口中运行的JS,每个窗口都有一个单独的全局执行上下文。但是,可以使用某些链接访问到这些不同的全局对象,例如parent.frames[1]。这里有可能有安全问题,将在后面的内容中讲到
每个JS执行上下文都有一个scope chain相关联。这个scope chain包含一个对象列表。当JS代码需要查找某个变量X的值时(this process called variable name resolution),它开始寻找该列表中的第一个对象,如果该对象含有一个属性名字是X,就返回它的值,否则继续查找,直到全局对象(global object)。如果全局对象里面都找不到x,那么就返回undefined.
这实际上是一个调用链的后进先出模型,根对象是全局对象,然后根据调用顺序,依次PUSH进调用路径上的每一个CALL对象。