自调用函数和因不声明变量而自动定义var的相关问题

首先给出默认不声明的变量下var定理:

函数体内,不声明变量 (如a=2) 他会向上级查找这个变量的定义,查找到顶层时候,还没有定义的话,它就会自动使用 var 定义(非严格模式下)


而自调用函数下 有且不仅有以下特点:

  1. 函数声明和执行是连续 一起的,既没有函数声明提升
  2. 自调用函数内的函数的定义是常量

直接上代码 用题目来巩固

对于自调用函数

//函数情况1 
var a=1;
var a=2;
(function a() {
    console.log(a);//输出a函数内容 因为没有函数声明提升
})()
console.log(a);//2 a函数是在自调用函数中声明定义的 不会外传 而var重复声明2覆盖了1

//函数情况2
var a=1;
(function a() {
    a=2; //因为作用域链上有a函数 不符合定理 不会var 但自调用函数里函数a是常量 常量不能修改 此时a=2是无效操作 严格模式下报const错误
    console.log(a);//输出a函数内容
})()
console.log(a);//1 没有触发定理 没有var 所以自调用函数里a的声明没有外传

//函数情况3
(function b() {
    a=2; //作用域链上没有a 符合定理 所以var a=2 
    console.log(a);//输出2
})()
console.log(a);//2 符合定理 所以var a=2 传出自调用函数外

函数情况1中,因为函数声明没有提升,所以不会出现a=2把a函数替换掉 导致“原a函数”调用不了的情况。

函数情况2中,因为作用域链上有a函数 不符合定理 不会var 但自调用函数里函数a是常量 常量不能修改 此时a=2是无效操作 严格模式下报const错误

函数情况3中,符合了定理,所以相当于最外层 有一个var a=2 所以传出了函数体外


对于普通函数

//函数情况4  正常情况下
function a(){
   var a=2 //a=2是在函数体内定义的 不会外传
   console.log(a)//2
}
a()
console.log(a)//a函数内容

//函数情况5 
function a(){
   a=2//对比函数情况2 作用域链上有a函数 不符合定理 不会var a函数不是常量a=2不是在函数内定义的 所以a=2覆盖了a函数 所以效果几乎等同于函数情况6
   console.log(a)//2
}
a()
console.log(a)//2

//函数情况6
function a(){}
a=2//此时 a值被替换成2
console.log(a)//2
console.log(a)//2

这里主要拿函数情况5来对比,对比函数情况2,作用域链上有a函数 不符合定理 不会var,a函数不是常量且a=2不是在函数内定义的 所以a=2找到外层定义的a函数并覆盖了a函数 所以效果几乎等同于函数情况6

猜你喜欢

转载自blog.csdn.net/weixin_43818307/article/details/123328594