作用域和变量
就是变量(变量名/函数名)的生效适用范围
作用域的分类
- 全局作用域(window): 一个 html 页面打开就是一个全局作用域
2.私有作用域: 只有函数生成私有作用域
(1) 只要你书写了一个函数, 就会生成一个私有作用域
(2) 一经书写, 作用域永生不变
作用域的上下级关系
书写在哪一个作用域内的函数, 就是哪一个作用域的子级作用域
提供了三个机制(熟读并背诵全文)
1. 变量定义机制
(1) 定义在哪一个作用域下的变量, 就是哪一个作用域的私有变量
(2) 只能在当前作用域以及后代作用域内使用
2. 变量访问机制
(1) 当你需要访问某一个变量的值的时候
(2) 首先在自己作用域内查找, 如果有, 直接使用, 停止查找
(3) 如果没有, 自动去到父级作用域查找, 如果有直接使用, 停止查找
(4) 以此类推, 直到全局作用域(window) 都没有, 那么直接报错, xxx is not defined
3. 变量赋值机制
(1) 当你需要给某一个变量赋值的时候
(2) 首先在自己作用域内查找, 如果有, 直接赋值, 停止查找
(3) 如果没有, 那么自动去到父级作用域查找, 如果有直接赋值, 停止查找
(4) 以此类推, 直到全局作用域(window) 都没有
(5) 把这个变量定义为全局变量, 在进行赋值
// 这段代码是在全局作用域下书写
console.log('我在全局作用域下')
// 在全局作用域下定义了一个叫做 fn1 的函数
function fn1() {
// 这里就是全局作用域下的一个 fn1 私有作用域
// 这里是在 fn1 私有作用域内书写的代码
function fn2() {
// 这里就是 fn1 私有作用域的 自己作用域
}
}
变量的三个形态
必须要有定义变量的关键字 var / function / …, 或者是函数的形参
(1) var num
(2) var num = 100
(3)function fn() {}
(4)function fn(a, b) {}
变量定义机制
(1) 定义在哪一个作用域下的变量, 就是哪一个作用域的 私有变量
(2)只能在当前作用域以及后代作用域内使用
// 在全局定义变量
var n1 = 100
console.log(n1)
function fn1() {
// 在 fn1 私有作用域内定义变量
var n2 = 200
console.log(n1)
console.log(n2)
function fn2() {
// 在 fn2 私有作用域内定义变量
var n3 = 300
console.log(n1)
console.log(n2)
console.log(n3)
}
fn2()
// console.log(n3)
}
fn1()
// console.log(n2)
2. 什么是变量访问 ?
(1) 你需要拿到某一个变量所保存的值来使用(运算, 输出, …)
(2) num++
(3) fn()
(4) console.log(aaa)
变量访问机制
(1) 当你需要访问一个变量的值的时候
(2)首先在自己作用域内查找, 如果有直接使用, 停止查找
(3) 如果自己作用域内没有, 会自动去到父级作用域查找, 如果有直接使用, 停止查找
(4) 如果还没有, 就再去父级作用域查找
(5)以此类推, 直到全局作用域(window)都没有, 那么直接报错 ** xxx id not defined **
// var num = 100
function fn1() {
// var num = 200
function fn2() {
// var num = 300
console.log(num)
}
fn2()
}
fn1()
(1) 给某一个变量进行赋值操作
(2)有赋值符号, 或者函数的实参
(3) num += 10 等价于 num = num + 10
(4) fn(10, 20)
变量赋值机制
(1) 当你需要给某一个变量进行赋值的时候
(2)首先在自己作用域内查找, 如果有直接赋值, 停止查找
(3)如果没有, 会自动去到父级作用域查找, 如果有直接赋值, 停止查找
(4)如果还没有, 再去到父级作用域查找
(5)以此类推, 直到全局作用域(window) 都没有
(6)** 会把这个变量定义为全局变量, 在进行赋值 **
var num 是变量定义
num = 10 是变量赋值
var num = 10
num + 20 是变量访问
num = xxx 是变量赋值
num += 20