解析 var b = 10; (function b(){ b = 20 console.log(b) })()

引题:

var b = 10;
(function b(){
    
    
	b = 20
	console.log(b)
})()

讲解几个相关知识点:

1. 变量提升

变量提升是对JavaScript中执行上下文(创建和执行)工作的一种认识
从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。

2. 函数表达式提升 (named function expression)

官网简介:

  • 如果你想在函数体内部引用当前函数,则需要创建一个命名函数表达式。然后函数名称将会(且只会)作为函数体(作用域内)的本地变量。
  • 被函数表达式赋值的那个变量会有一个 name 属性,如果你把这个变量赋值给另一个变量的话,这个 name 属性的值也不会改变。如果函数是一个匿名函数,那 name 属性的值就是被赋值的变量的名称(隐藏值)。如果函数不是匿名的话,那 name 属性的值就是这个函数的名称(显性值)。这对于箭头函数也同样适用(箭头函数没有名字,所以你只能赋予 name 属性一个隐性名)。

函数表达式特点:

  • 标识符会在编译时提升到顶部

匿名函数特点

  • 标识符无法被修改

代码版:

// 此时的 b 会被提升到顶部
function b(){
    
    }

3. 立即执行函数(IIFE)

官网介绍:

  • 包围在 圆括号运算符 () 里的一个匿名函数,这个匿名函数拥有独立的词法作用域。这不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域。
  • 再一次使用 () 创建了一个立即执行函数表达式,JavaScript 引擎到此将直接执行函数。
    白话文版:
(function (){
    
    })()
// 还有其他的方法可以创建立即执行函数,下面放上链接

特点

  • 内边具有独立的词法作用域

跳转多方法创建立即执行函数链接

4.var

特点

  1. 存在变量提升(上面说到了)
  2. 一个变量可以声明多次,后面得声明会覆盖前面得
  3. var作用域时函数作用域,在全局定义时,this执行window,在函数体内会单独创建,该变量时局部的

重点分析这个题引得知识点:

var b = 10;
(function b(){
    
    
	b = 20
	console.log(b)
})()

先看答案:在这里插入图片描述

分析代码

  1. 代码进入预解析状态,将var b进行变量提升,此时b没有被赋值(b=undefined) (这里有人会说这里明明有个函数表达式呀,为什么没有进入变量提升,因为IIFE自带有词法作用域(我们常理解得作用域))
  2. 发现没有可以变量提升得时候将b赋值为10,此时会将b 赋值为10(b=10)
  3. 碰到了立即执行函数,会执行其内边的函数 function b()
  4. IIFE作用域中定义b = function b(){}
  5. 碰到了b = 20,会顺着作用域链寻找是否存在b,发现IIFE作用域中存在b,将IIFE作用域中的b赋值为20(b=20)(因为函数表达式特性,标识符无法被修改,所以这里执行失败)
  6. 执行console.log(b),此时的b会找IIFE中的作用域看看是否存在b,发现其内边存在,将其返回

这就是为什么console.log(b)为什么会输出function b(){}的原因了

总结知识点

  1. var 变量提升
  2. 函数表达式变量提升
  3. 函数表达式标识符不可被修改
  4. 立即执行函数内边有独立的作用域

不理解可以看这里 (超详细解析,早知道就不自己写了,直接看别人的多香呀,自己写的发现漏洞百出)

猜你喜欢

转载自blog.csdn.net/weixin_46112649/article/details/126376367
B
a^b
A/B
A*B