1.作用域:标识符(变量和函数名)在哪些地方能够被访问 那些地方就是这个标识符的作用域。这些地方就是指的函数的代码块内部和函数代码块外部。
规则1:函数内部的代码块可以访问函数内部的标识符,也可以访问函数外部的标识符(副作用)
规则2:函数外部可以访问函数外部的标识符,但是不能访问函数内部的标识符
通常称函数内部的标识符为局部标识符
var a = 200
function fn(a) {
function fm(a) {
console.log(a,"第一次")
a = 90
console.log(a,"第二次")
}
fm(a)
console.log(a,"第三次")
}
fn(a+10)
console.log(a,"第四次")
分析: 首先fn(a+10)的a是到全局变量中找a的值为200,然后fn(a+10)就等价于fn(210);再将a=210传入fn函数,函数fn就有一个隐式操作var a=210;然后再将a=210作为参数传入fm函数,所以第一次打印210;然后再重新给a赋值为90,所以第二次打印90;第三次打印的还是fn中的a,为210;第四次打印的是全局作用域中的a,为200
2.函数在运行时,会有一个隐式提升的操作。每一个作用域在运行时,js引擎会先把作用域内部的关键字提前扫描 并声明。但是变量是只提升声明 而不赋值;函数是连同函数体一起提升。
3.函数运行时的隐式提升过程:
1.先隐式提升当前作用域内部的所有形参变量和局部变量(只提升变量 不提升赋值)
2.再把实参赋值给形参变量
3.然后执行函数的隐式提前声明
4.再按照代码顺序运行代码
var a = 10
function fn() {
// 隐式操作:把var修饰的变量提前声明
// var a
console.log(a)
//a打印undefined 是因为a声明了却没赋值
a = 40
//给隐式声明的变量赋值 初始化 a=40
var a = 20
//更新a的值 a = 20
console.log(a)
//打印a为20
}
console.log(a)
//打印a为10
fn()
console.log(a)
//打印a为10`
4.同名标识符的提升问题:
1.变量和函数同名时 先变量后函数
2.变量和变量同名时 就近访问
3.函数和函数同名时 也是就近访问
5.函数运行时的作用域
函数是一个引用数据,标识符可以在任何作用域去引用一个函数,但是函数运行时的作用域就是函数在生成(定义和声明)时,所在的作用域。也就是说函数运行代码时,一定是去它声明和定义的作用域执行代码