什么是标识符?
例如:var fn=; 其中var是关键字,fn就是标识符。
作用域:标识符(变量和函数名) 在哪些地方能够被访问, 那些地方就是这个标识符的作用域(实际指的就是 函数的代码块内部和函数的代码块外部)。
规则1:函数内部的代码可以访问函数内部的标识符,也可以访问函数外部的标识符(副作用)
规则2:函数外部可以访问函数外部的标识符,但是不能访问函数内部的标识符
通常称函数内部的标识符为局部标识符 脚本中的称为全局标识符
函数运行时的作用域:
函数是一个引用数据,标识符可以在任何作用域去引用一个函数 但是:
函数运行时的作用域在哪里? 函数在生成(定义和声明)时 所在用在的作用域
函数运行时 是在 写函数代码的地方运行代码 不是在调用代码的地方运行代码
标识符提升:
每一个作用域在运行时,js引擎会先把作用域内部的关键字隐式提前扫描 并声明。
函数也会隐式提升: 变量值提升声明,函数提升的是整个函数体。
对象内部的方法不会隐式提升。
函数声明式才会提前,定义式不会提前 :var fn1=函数
同名标识符提升问题:
利用形(形参和变量)实函运方法《老师总结的个人方法》:
它是指,在一个作用域的代码运行的时候 js引擎会执行代码的过程有一个执行流程
这个流程就是:
1.先隐式提升当前作用域内部的所有形参变量和局部变量 (只是声明提升,不提升赋值)
2.再把实参赋值给形参变量
3.然后执行函数的隐式提前声明
4.再按照代码顺序运行代码
变量函数同名时==>先变量然后函数
变量变量同名时 , 函数和函数同名时 ==>都是就近原则
案例1:
function fn () {
a=100
}
var a=200;
fn() //fn函数内部没有a标识符,去访问外部的a,并修改a的值 a=100
console.log(a) //由于外部a的值被修改,所以打印的是 200
案例2:
var total = 0;
function increment() {
// var total = 0
total = total + 2
console.log(total)
}
increment()//{var total=0; total = total + 2}
increment()//{var total=0; total = total + 2}
//两次的结果相同,因为函数的调用是运行一次代码:每一次调用都会重新执行所有代码
案例3:
var a = 10
function fn() {
//先隐式申明变量a,var a;
console.log(a) //打印undefined
a = 40
var a = 20
console.log(a) //20
}
console.log(a) //直接打印10
fn() //运行fn函数 undefined 20
console.log(a) //外面的a没有改变 10
案例4:
function fn(a) {
function fm() {
a = a + 1
console.log(a)
}
return fm
}
var f1=fn(10)
f1() //11
f1() //因为f1中传进了一个实参,所以第二次运行f1()并不会全部重新运行
//所以为12如果是 var f1=fn(10)
f1()
var f2=fn(10)
f2() //则两次的结果就是一样的,因为是两个独立运行的函数,两块不同的空间