JS-作用域

394 阅读3分钟

全局变量,个人理解全局变量就是全局对象window的属性

var a = 5  // 声明一个全局变量
console.log(window.a) // 5

1.变量作用域

javaScript的全局变量的作用域,顾名思义作用域就是全局,而函数的参数跟局部变量的作用域在函数体内。

如果两个变量重名,一个变量是全局变量,一个是局部变量,优先级是 局部变量>全局变量

var a = 1    // 声明全局变量
function fuc() {
    var a = 2 // 局部变量
    return a
}
console.log(fuc()) // 2

如果在函数内声明变量没有带var,会被当作全局变量,也叫隐式声明

function fuc() {
    var a = 2 // 局部变量
    return a
}
console.log(a) // a is not defined

function fuc() {
    a = 2 //  没有var,此时a是全局变量
    return a
}
console.log(a) // 2

2.函数作用域

javaScript变量的作用域,与java等语言不同的是,在变量声明的代码块之外是不可见的,简称“块级作用域”

function fuc(){
    console.log(num)  // 输出未定义的变量 会报错
}
fuc() // num is not defined

function fuc(){
    console.log(num)  // 不报错, 输出undefined,因为num在函数体内有定义
    var num = 5
    console.log(num) // 5
}
fuc() 
//由于变量提升,上面代码等价于
function fuc(){
    var num
    console.log(num)  // undefined
    num = 5
    console.log(num) // 5
}
fuc() 

3.作用域链

javaScript的函数是允许嵌套的,就是在一个函数内部声明另一个函数,代码如下

function A(){
    var num = 5
    function B() {
        var b = 2
    }
}

执行A函数的时候,会创建A函数的作用域,B函数在创建的时候会引用A的作用域


执行B函数的时候会引用函数A的作用域,由所谓的函数作用域的嵌套形成了函数作用域链。

在自身如果找不到该变量的时候,就会沿着作用域向上查找,直至在全局作用域找不到时抛出错误

作用域题目

  • js内部作用域可以访问外部,但外部不能访问内部

var a = 10
function aaa () { 
 alert(a)  // 调用顺序3,内部没有a变量,沿着作用域链向上寻找,在找到全局变量a =10
} 
function bbb () {
    var a = 20
    aaa()  // 调用顺序2
} 
bbb()  // 调用顺序1  结果为10
  • 不用var定义变量,会默认为全局变量

function aaa(){
      var a=b=10    
}
 aaa()
 alert(a) // 报错
 alert(b) // 10

//上面aaa()的代码等价于下面
var b = 10
function aaa() {
    var a = b
}

  • 寻找变量是就近原则,沿着作用域链往上找,变量的声明会被提升至顶部,赋值会留在原地

function aaa () {
  alert(a)
  var a = 20
}
aaa() // undefined  此题与上面第二点的例子一样

  • 同名的全局变量跟局部变量,局部变量优先级大于全局

var a = 10
function aaa () {
  alert(a)
  var a = 20
}
aaa() //结果为:undefined

//此代码等价于
var a = 10
function aaa () {
    var a
    alert(a)  //undefined
    a = 20
}
aaa() //结果为:undefined

  • 如果形参与局部变量同名时,优先级一样

var a = 10
function aaa (a) { // 函数传入形参 a
  alert(a)
  var a = 20
}
aaa(a) // 结果为: 10

var a = 1
var a       // 这里的var a 是一个重复定义,变量只有定义后未赋值才会输出undefined,
               这里JS引擎对重复定义的规定是:以最近的变量赋值作为变量在执行时的值
               所以var a相当于无效
console.log(a) // 1

  • 变量修改的时候,另一个变量会跟着变化,但是重新定义时,另一个不跟随变化

var a=[1,2,3]
var b = a
b.push(4)
alert(a) // 结果为[1,2,3,4] 当b改变的时候a也发生了改变  

当b重新被赋值的时候 a不会改变.示例:
var a = [1,2,3]
var b = a
b = [1,2,3,4]
alert(a) // 结果为 [1,2,3]