作用域
表示变量可以发挥作用的域 能够对某个变量寻址(调用 赋值)正常访问的域
作用域变量寻址规则
1.javascript 有作用域概念
script是 全局域
函数是 局部域 ,if() for()这些控制流程语句 不构成作用域
函数内的变量 是 局部变量
2.局部内可以访问全局变量,局部外不可以访问局部内的私有变量
3.私有变量 是指 在当前局部作用域下 声明的变量,如果没有声明变量符 就不是当前作用域的私有变量
4.在调用没有声明的变量的的时候,会向上一级作用域寻找声明 一直找到 全局作用域为止
5.变量的访问 优先访问自己作用域内的局部变量,自己作用域找不到,向上寻找调用
6.如果一个变量 在局部作用域中直接使用 但是没有声明 并且向上一直寻找到 全局作用域 也没有 var 声明,js引擎会在全局作用域进行隐式声明
`function fn(){
var x = y = 10
}
fn()
console.log(y)
console.log(x)
`
var x = y = 0
可以拆分为
var x
y = 10
x = y
x为局部作用域的私有变量
y没有声明 向上层作用域寻找
y是通过隐式声明的全局变量
JavaScript引擎会对代码进行预解析
规则如下:
1.寻找所有的声明 并提升【提升到当前作用域的最前面】(形如这样的都是声明语句 1.变量声明var 2.函数声明function fn(){}; 先提升变量 再提升函数)
2.按照顺序 执行所有的 执行语句
3.一层一层的作用域进行解析 先解析全局作用域 然后解析局部作用域
`var x = 10;
function fn(){
console.log(x);
var x = 20;
}
fn();`
因为函数内部的声明提到的 当前作用域 的前面
作用域链
1.作用域嵌套 就是函数嵌套关系 可以向上级获取 不能向下级获取
2.当前作用域内变量调用 优先调用自身局部变量 如果自身局部作用域没有声明 向上一级查询
1. `var x = 10
function x(){
x = 20
}
x()
console.log(x)
这个函数会报错,原因如下:
1.声明提升
var x
function x(){}
2.顺序执行 执行语句
x = 10
x()
console.log(x)
2.先提升变量 再提升函数
`console.log(x)
var x= 10
function x() {
x = 20
}
x()
3.js没有动态作用域,函数在声明的时候,里面调用的变量就确定了变量属于哪个作用域
`var x = 20
function fn1(){
console.log(x)
}
x = 30
function fn2(){
var x = 1
fn1()
}
x = 40
fn2()
4.有if语句 需要判断if语句是否运行 (0 '' NaN undefined null都是false)
`var x = 20
function fn(){
if(x){ //var x = 30
var x = 30
}
console.log(x)
}
fn()
console.log(x)
5.声明提升中,提升再最前面的内容,执行语句 放在最前面的执行语句
`function fun(param){
console.log(param)
var param = function (){
console.log(1)
}
console.log(param)
}
fun(5)
以下是该函数的声明提升
var param
param = 5
console.log(param)
param = function(){
console.log(1)
}
console.log(param)
6.foo的函数声明和变量声明都是(开辟一个名称为foo的地址空间)主要看赋值是什么,就返回什么
`var foo = 1
function bar(){
function foo(){}
foo = 10
console.log(foo)
}
bar()
console.log(foo)
以下是声明提升解析
var foo
function bar(){}
foo = 1
bar()
function foo(){}//声明了一个标识符名称为foo的内存地址 默认存储内容为函数体,和var foo
foo = 10
console.log(foo)
console.log(foo)