全局变量,个人理解全局变量就是全局对象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]