变量作用域及垃圾收集

变量作用域
全局变量:在js里定义在函数和代码块外部的叫做全局变量
局部变量:在对象体内定义变量的叫做局部变量
参数的传递
(1)基本类型传递的传递,传递的是值
例如:

var x=5
function fun(x){
  document.writeln("1:"+x+"
")//5 x=3 document.writeln("2:"+x+"
")//3 } fun() document.writeln("3:"+x+"
")//3

(2)引用数据类型的传递,传递的是地址
例如:

var emp={x:5}
var fun=function(emp){
document.writeln(emp.x+"
")//5 emp.x=3 document.writeln(emp.x+"
")//3 } fun(emp) document.writeln(emp.x+"
")//3

执行环境和作用域
作用域链:当代码在一个环境中执行时,会创建变量对象的yoga作用域链,用来保证对执行环境有权访问的所有变量和函数的有序访问
执行环境和作用域
作用域链:当代码在一个环境中执行时,会创建变量对象的yoga作用域链,用来保证对执行环境有权访问的所有变量和函数的有序访问
例如:

var a=11;
  function fun1(){
  var b=22;
  function fun2(){
      var c=33;
  document.writeln("fun2:"+a+","+b+","+c+"
") } fun2() document.writeln("fun1:"+a+","+b+"
") } fun1() document.writeln("全局:"+a+"
") 备注:在不同环境下,所访问到的变量环境也不相同

特殊情况 js没有块级作用域

  if(true){//if代码块
  var c="aaa"

}
document.writeln(c+"
")//可以访问if里面的变量 for(var i=1;i<=5;i++){//for 代码块 document.writeln(i) } document.writeln("循环外:"+i+"
")//可以访问for里面的变量

延长作用域链
虽然js里只有全局和局部函数,但是我们可以用其他方法延长作用域链

   function Emp(name,age){
this.name=name;
 this.age=age;
}
var p=new Emp("lilt",23)
document.writeln(p.name)//对象通过地址调用
function fun(){
 var c="qqq"
 return c
}
document.writeln(fun())//函数通过语句调用

特殊基本变量 参数管理器
别名叫做可变参数或者参数数组,用来获取函数里的形参
特点:
1.只能定义在函数体里,并且只能内部使用
2.可变参数是通过数组形式存储变量的
3.可变参数不可以用数组下的方法,不能用栈和队列的方法

  function fun(){
document.writeln(arguments.length)//获得数组长度
for(i=0;i

闭包(特殊的作用域)
闭包的表现形式是函数嵌套函数,是用来有权访问另一个函数作用域中变量的函数

function Emp(name,age){
  this.name=name;
  this.age=age;
  this.say=function(){//被嵌套的}
}
var a=11;
function fun1(){
  var b=22;
  function fun2(){//被嵌套的}
}

var p=new Emp();
p.say();//执行
var a=11;
function fun1(){
  var b=22;
  function fun2(){//被嵌套的}
  fun2();//执行
}

外部访问闭包 匿名函数的写法
执行方法一:

var a=fun(5)
var b=a(6)
执行方法二:

var v=fun(4)(6)
闭包的优缺点
优点:
1.可以通过闭包来访问全局和局部变量
2.可以通过闭包来实现私有变量
3.闭包的变量不会被垃圾回收机制回收
4.闭包变量会优先在内存中生成
缺点
1.闭包里的变量会一直保持在内存中,造成内存消耗过大
2.闭包可以调用到父类函数里的值,也可以随意更改,所以不安全
闭包和变量
例如1:

   function fun(){
 var x=[]
     for(i=0;i<=10;i++){
   x[i]=function(){
       return i;
     }
   }
    return x;
 }
  var z=fun();
  for(i=0;i

例如2:

for(i=1;i<=5;i++){
  setTimeout(function(){
    document.writeln(i)
  },1000)
}

解决方法:

  function fun(){
  var x=[]
  for(i=0;i<10;i++){
    x[i]=function(num){
      return function(){
        return num
      }
    }(i)
  }
  return x
}
var z=fun()
for(v in z){
      document.writeln(z[v]())
}
fun()

垃圾收集
js 具有自动垃圾回收机制,例如c c++就需要程序员手动回收垃圾。
实现原理:找出那些不再继续使用的变量,然后是否内存,js会按照一定的时间间隔,周期的执行这一操作。
变量回收的特点:
对于局部变量的回收,js会在一定周期里进行检测,因为局部变量只在函数执行过程中存在,所以在函数运行过程中,局部变量在栈或堆内存里分配空间,存储值,直到函数结束,js会自动释放他们的内存。
全局变量的定义会在浏览器关闭时,或者js检查代码发现此变量不再继续使用时才会回收。
在闭包里定义的变量,会一直保存在内存中,不会被垃圾回收机制进行自动回收。
垃圾回收机制方式
1.标记清除
当一个变量进入了环境,我们可以通过一个字段表示“进入环境”,当是进入环境时,表示内存正在占用并执行,如果当函数执行完毕时,我们可以把字段修改成”离开环境“,所以js检测到所有为“离开环境”的状态时,就进行垃圾回收
在五大主流浏览器之后的版本,在2008年之后,都是这样做的,只是时间间隔不一样。
2.引用计数
js定义了一个数字变量来跟踪值被引用的次数,当声明并赋值给一个变量时,js 就对这个次数加1,如果这个变量参与其他运算,或赋值给了新变量,在次数会累加;当这个变量被另一个值取代,则次数会减1,直到次数减到0时,js才会对其回收
在五大主流浏览器的低版本应用的
自己手动回收

var a=11;a=null;
var emp={}; emp=null;
function(){return null};
var fun=function(){}; var fun=null;

你可能感兴趣的:(面向对象)