值的基本类型有:undefined、NUll、Boolean、Number、String。这些类型分别在内存中占据固定大小的空间,它们的值存储在栈空间中。我们通过值来访问。(1)值类型:数值、布尔值、null、undefined。(2)引用类型:对象、数组、函数。如果分配了引用类型的值,则必须在堆内存中为该值分配空间。由于这类值的大小不固定(对象有很多属性和方法),所以它们不能存储在栈内存中。但是内存地址大小是固定的,所以内存地址可以保存在栈内存中。简而言之,堆内存存放的是引用值,栈内存存放的是固定类型的值。“引用”是指向对象实际位置的指针。注意这里的引用指向一个具体的对象,而不是另一个引用。这里的对象可以是字符串对象、数字对象、数组对象等复制变量值看下面的例子:来自综上所述,可以得出结论:在变量拷贝方面,基本类型和引用类型也是有区别的。基本类型复制值本身,而引用类型复制地址。传递参数在ECMAScript中,所有的函数参数都是按值传递的,js是没有引用传递的,如果有引用传递,那么函数中的变量就是全局变量,也可以被外部访问。但这显然是不可能的。执行环境和范围执行环境是javascript中最重要的概念之一。执行环境定义了可以访问其他数据的变量或函数。全局执行环境是最外围的执行环境。在网络浏览器中,全局执行环境是窗口对象。因此,全局变量的所有函数都创建为窗口的属性和方法。当执行环境中的代码执行完毕,环境被破坏,变量和函数被保存其中也被摧毁。如果是直到所有程序执行完毕或网页完成,全局环境才会被破坏。去掉var的局部变量传参也是局部变量函数体也包含函数,只有这个函数才能访问内层的函数可以通过如下方式访问:另一个范围示例:当代码为在一个环境中执行,会形成一个叫做作用域链的东西。其目的是保证在执行环境中对具有访问权限的变量和函数进行有序访问(指按规则级别访问)。作用域链的前端,即执行环境的变量对象作用域变量,在函数中没有声明或者声明时不带var,就是全局变量,具有全局作用域。窗口对象的所有属性都具有全局范围;在代码的任何地方都可以访问,在函数内部用var声明和修饰的变量是局部变量,只能在函数体内使用。函数的参数虽然不用var,但仍然是局部变量。Noblock-levelscope//ifstatement:for循环语句。变量查找在变量查找中,访问局部变量比全局变量更快,因此不需要向上查找作用域链。下面的例子:>everyeach环境可以向上搜索作用域链来查找变量和函数名;但是没有环境可以通过向下搜索范围链进入另一个执行环境。这里,如果去掉varname="trigkit4",那么就会弹出"Jack"内存问题。JavaScript有一个自动垃圾回收机制。一旦不再使用数据,可以将其设置为“null”以释放引用周期。一个很简单的例子:一个DOM对象被一个Javascript对象引用,同时又引用了同一个或其他Javascript对象,这个DOM对象可能会造成内存泄漏。当脚本停止时,对该DOM对象的引用将不会被垃圾回收。要打破循环引用,需要为引用DOM元素的对象或对DOM对象的引用分配值null。当闭包在闭包中引入闭包外的变量时,这个对象在闭包结束时不能被垃圾回收(GC)。vara=function(){varlargeStr=newArray(1000000).join('x');返回函数(){返回largeStr;}}();DOM泄漏当原来的COM被移除时,子节点Point引用在被移除之前无法被回收。varselect=document.querySelector;vartreeRef=select('#tree');//在COM树中,leafRef是treeFre的子节点varleafRef=select('#leaf');varbody=select('body');body.removeChild(treeRef);//#tree不能回收,因为treeRef还在//解决方法:treeRef=null;//tree不能回收,因为叶子结果leafRef仍然是leafRef=null;//现在#tree可以被释放了。Timersmeter(计时)定时器泄漏定时器也是产生内存泄漏的常见地方:for(vari=0;i<90000;i++){varbuggyObject={callAgain:function(){varref=this;varval=setTimeout(function(){ref.callAgain();},90000);}}buggyObject.callAgain();//虽然想回收,定时器还是buggyObject=null;}调试内存Chrome自带的内存调试工具可以很容易检查内存使用和内存泄漏,在Timeline->Memory中点击record。
