js的变量和作用域

JS变量,作用域
多次:保存数据的容器
变量名:$_字母,数字,数字不能开头
关键字:if for
保留字:class
基本类型的值是不可修改的,引用类型是可以修改的
基本类型不是修改,而是覆盖
没有办法给基本类型添加属性
当基本类型调用方法的时候,会去找它的包装对象

内存:
栈:有序排列的,分成每个小房间,没有办法扩建
堆:相当于小别墅,大小是不固定的,可以自己扩建一些东西
栈内存是固定大小的空间,堆内存是空间不固定的,无序的
基本类型:不可以修改:保存在栈内存中
引用类型:可以修改,保存在堆内存中,地址保存在栈内存中,但是数据保存在堆内存中

一、基本数据类型:
byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0
short:短整型,在内存中占16位,即2个字节,取值范围-32768~32767,默认值0
int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0
long:长整型,在内存中占64位,即8个字节-263~263-1,默认值0L
float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0
double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0
char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空
boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false
二、引用数据类型:
类、接口类型、数组类型、枚举类型、注解类型。

变量相等的比较:
1.基本类型和本类型比较直接==就好了
2.当比较引用类型的时候,比较的是他们的地址
引用类型,只有指向同一个引用才相等

或者使用遍历/循环

复制变量的值:
基本类型的值的复制,两个值互不干涉
但是引用类型的话由于是使用地址,所以一个改变另外一个也改变

参数传递和类型检测:
参数传递,调用的时候传进去的参数叫实参
自己在里面写的叫形参
对于参数只有按值传递

检测:
‘string’
true
undefined
null
[]
{}
function
RegExp
typeof返回类型

instanceof:前面的是后面的实例
只能和引用类型连用,不可以和基本类型

全局作用域和局部作用域
变量的作用域:
就是变量起作用的区域和范围
变量在哪个范围起作用
1.变量的生命周期
全局变量:所有都走完
函数作用域:只有函数执行时
2.访问到变量
局部作用域主要指函数作用域

var name = ‘Xm’;
function fn(argument){
    var sex=‘male’;
}

name:全局作用域,他在全局都可以访问到
sex:局部作用域
js中没有块级作用域
变量对象:

var name=‘xm’;
function fn(argument){
    var sex =‘male’;
    function fn2(argument){
        var age=18;
    }
}

fn本身是在全局作用域中
但是fn内部是它的局部作用域

name=window.name
fn=window.fn

不存在的属性不会报错,只不过会告诉你undefined

作用域链

var name=‘xm’;
function fn(){
    var name =‘xh’;
    var sex=‘male’;
    function fn2(){
        var name=‘xhei’;
        var age=18;
    }
}

使用作用域链从内到外查找
内层速度优于外层速度
查找变量的方法

延长作用域链

with(person){
    …修改内容
}

相当于直接修改了person中的内容,相当于person.什么什么

js解析机制:
预解析
1.var变量:undefined
参数当作局步变量
2.函数
3.变量变量同名无所谓
函数变量:函数
函数函数:第二个函数
4.代码块有的不解析

在当前作用域下,js在运行之前都会去进行预解析,预解析会把带有var 和 function 的关键字声明,并在内存中安排好,进行预解析,然后再逐行读取代码(注意预解析只会发生在var 定义的变量和function上)。

逐行解析代码

变量和函数冲突
按照函数走

函数函数冲突,按照后面的走

//examp5
var a=1
function fn(){
    console.log(a)
    a=2
}
fn()
console.log(a)

/**

  • 全局作用域
  • 预解析:
  • 查找函数声明
  • fn:function fn(){
  • console.log(a)
  • a=2
  • }
  • 查找变量声明
  • var a=1 => a:undefined
  • 函数内的作用域
  • 预解析:
  • 查找函数参数
  • 查找函数声明
  • 查找变量声明
  • 执行阶段:
  • fn() => console.log(a) => fn内没有定义a,就访问全局的a
  • fn() => a=2
  • console.log(a) => 访问你全局a
  • 打印结果:
  • 1
  • 2

*/
————————————————

// examp6
var a=1
function fn(a){
    console.log(a)
    a=2
}
fn()
console.log(a)

/**

  • 全局作用域
  • 预解析:
  • 查找函数声明
  • fn:function fn(a){
  • console.log(a)
  • var a=2
  • }
  • 查找变量声明
  • var a=1 => a:undefined
  • 函数内的作用域
  • 预解析:
  • 查找函数参数
  • a:undefined
  • 查找函数声明
  • 查找变量声明
  • 执行阶段:
  • fn() => console.log(a) => 访问fn内的a,未传参数
  • console.log(a) => 访问你全局a
  • 打印结果:
  • undefined
  • 1

*/
————————————————

// examp7
var a=1
function fn(a){
    console.log(a)
    a=2
}
fn(a)
console.log(a)

/**

  • 全局作用域
  • 预解析:
  • 查找函数声明
  • fn:function fn(a){
  • console.log(a)
  • a=2
  • }
  • 查找变量声明
  • var a=1 => a:undefined
  • 函数内的作用域
  • 预解析:
  • 查找函数参数
  • a:undefined
  • 查找函数声明
  • 查找变量声明
  • 执行阶段:
  • fn(a) => console.log(a) => 访问fn内的变量a,参数a访问全局变量a,赋值给fn内的变量a
  • console.log(a) => 访问你全局a
  • 打印结果:
  • 1
  • 1

*/
————————————————

垃圾收集机制
1.离开作用域的值将被记录为可回收,将在垃圾收集期间删除
2.标记清除是目前最主流的垃圾收集算法
3.标记清除就是给不用的值加标记,然后回收其内存
4.引用计数算法可能因为循环引用的的问题而得不到释放
5.当变量不用的时候,可以手动接触

释放无用的数据,会瘦内存
自动

手动(原理:找出没用的数据,打上标记,释放其内存,周期性执行)
标示无用数据的策略:
标记清除:

环境中的变量

引用计数:

跟踪记录每个数据的引用次数,。
比如Netscape
问题:循环引用

IE
JS: DOM

BOM

内存管理
内存管理:web浏览器<桌面应用程序
null:解除引用
局部变量离开作用域,自动的解除引用

var arr=[…]:比如这个全局变量一直存在,我们可以手动结局它,用=null

你可能感兴趣的:(前端,作用域)