var 关键字
var fn; fn就是标识符
作用域:标识符(变量和函数名) 在哪些地方能够被访问 哪些地方就是这个标识符的作用域
这些地方就是指的函数的代码块内部和函数的代码块外部
规则1:函数内部的代码可以访问函数内部的标识符 也可以访问函数外部的标识符(副作用)
规则2:函数外部可以访问函数外部的标识符 但是不能访问函数内部的标识符
案例1:
由以下代码可知:
1.fn运行时内部同时运行fm()
2.对于fm中的a 分为两种情况 1.加var 2.加上var
1.加var fm中的a只能由更内部的访问 外部不能访问所以fn中的打印a=20
2.不加var 不声明时 系统会帮我们在全局声明 这里的全局是在fn中,所以覆盖了fn中a=20的值现在等于10 打印=10
function fn(){
var a=20
function fm(){
a=10
}
fm()
console.log(a);//20 fm不加var 10
}
fn()
案例2 :
由以下代码可知:
1.对于一个带参的函数 其函数内部会隐式声明参数值 如下面代码fn中隐式声明了var a
2.因为fn中a有了var 所以本来的无var的a=100 就相当于赋值给参数a 不会再全局声明
最后结果还是全局中声明的a=200
function fn(a){
//实参:var a=300 因为实参会自动把a声明所以下面的a只是重新赋值已经声明过了不能全局
a=100
}
var a=200
fn(300)
console.log(a);//这个a只能访问外部的a //200
案例3:
由以下代码可知:
1.fn(a+10) 传入了一个210
2.fn内部的fm运行时分为带参和不带参两种情况:
1.带参时 隐式声明一个a=210 此时122a等于210 继续运行a=90会覆盖210 所以123a等于90因为没有改变外部a所以124a=210
2.不带参时 就没有隐式声明 所以122a就直接取找了外部fn的a=210 然后运行a=90因为无var声明所以a=90在fn中被声明并覆盖fn中的210在运行123a时a就等于90 然后外部124a运行也等于了90
3.因为全局的a=200并没有被改变所以125a=200
var a=200
function fn(a){
//var a=200 a=a+10
function fm(a){//加了参数a123=210 不加参数=90
//var a=210 //a=90
console.log(a,122);//210 这里的a只能访问fn中隐式申明的a
a=90 //有参数的时候fm中隐式声明的a被引用成210 没参数就取fn中的a声明
console.log(a,123);//90
}
//var a=300
fm(a)//fm(210)
console.log(a,124);//210
}
fn(a+10)//fn(200) a取了上面的a值
console.log(a,125);//这个a只能访问外部的a //200
案例4:
两个加减函数可以对全局变量施加影响
var total=0
function increment(){
total=total+2
}
function decrease(){
total=total-2
}
increment()
increment()
decrease()
console.log(total);//2
案例4修改版:
函数的调用试运行一次代码:每一次调用都会重新执行所有代码
改变:多加了参数 并给函数加了个打印
var total=0
function increment(total){
total=total+2
console.log(total);
}
increment(total)//var total=0 total=total+2 每次调用都重新申明
increment(total)//var total=0 total=total+2
console.log(total);
每一个作用域在运行时,js引擎会先把作用于内部的标识符的关键字隐式体检扫描并声明
函数的提升案例:
由下面的代码可知:
1.a是一个打印123的函数被作为参数进入fn函数 所以函数提升与隐式操作会把fn函数顶上排成如下样子:
1.隐式提升:var a=func(){123}
2.函数内部自带的function fm()也会在函数运行时提升上去 排在a下面
2.运行代码fm=a 因为fm被提升上去了所以fm可以在这里使用 使得fm函数等于a函数
3.打印函数fm此时打印123
4.小提示:在全局中function(){} 函数也会直接提升上去 但是var a=fucntion (){}函数只会提升声明值a
function fn (a){
// 隐式提升:var a=外部函数
// func fm(){log(124)}这个函数体被提升上去了
fm=a//最后一次声明fm=外部函数
function fm(){
console.log(124);
}
console.log(fm);//123
// console.log(fm.name);
}
var a=function(){
console.log(123);
}
fn(a)
报错案例:
由以下错误代码可知:
1.在对象中的函数不可提升
function fn(){
console.log(obj.say);
var obj={
say:function(){}
}
}
fn()
同名标识符提升问题:变量函数同名时 先提升变量在提升函数 就近原则var a在上 func在下离得近
1. var a 先提升
2. function a(){log} 后提升
console.log(a);//此时a=undefined 还没赋值 //func
var a=20
function a(){
console.log(100);
}
console.log(a);//此时a=20了 //20
同名标识符提升问题:函数和函数同名
和同变量一样 就近原则
function fn2(){
console.log(111);
}
function fn2(){
console.log(2222);
}
fn2()//
形(形参和变量)实(实参)函(函数的隐式提前声明)运(运行) 执行顺序
1.形参和函数内部var同时var a
2.var a=20 实参隐式赋值
3.func 函数提升上来
var a=20
function fn3(a){
console.log(a,1);//func
a=90
console.log(a,2);//90
var a=100
console.log(a,3);//100
function a(){//
console.log(666);
}
console.log(a,4);//100
}
fn3(a)