当前位置: 首页 > news >正文

javascript 中的变量提升与函数提升

文章开始之前,我们来先看一段代码

变量提升

console.log(a); //undefined
var a = 10;
console.log(a); //10;复制代码

为什么在变量之前打印出来是 undefind 而在之后是 10 呢?
其实真正的执行是按一下步骤执行的;

var a; 
//首先会检查该作用域中有没有变量,如果有,就提到作用的顶部来;
console.log(a) 
//当我们打印的时候a已经存在了,此时并未赋值,所以是undefined
a = 10;
//在我们定义赋值的地方,才会给他赋值;
console.log(a) 
//此时之前已经将10赋给a了,所以a打印出来就是10了复制代码

那什么是变量提升呢?这就是变量提升;

使用var定义变量的时候,js解释器会将变量提升到该作用域的最顶部,这就是变量提升

看下一个例子:

var a = 10;
function f1(){
    console.log(a); //undefined
    var a = 20;     
    console.log(a); // 20
}
f1()复制代码

不用觉得奇怪,结果本该就是这样;同样的我们来解析一遍;

var a; //变量提升
a = 10; //赋值处赋值
function f1(){
    var a; //变量提升
    console.log(a) //undefined
    a = 20; //赋值处赋值
    console.log(a) //上面已赋值,所以结果是20
}
f1();复制代码

为什么全局作用域那里已经定了啊了,并且也赋值了,而在函数f1里面打印的还是undefined,这是因为函数形成的函数作用域,已经是一个封闭性的作用域,只要它里面存在此变量,将不会去访问外层作用域的相同变量了。
所以这也解释的通为什么函数f1里面打印的还是undefined了;

再看下面一个例子:

console.log(a); // 报错: a is not defined
a = 10;复制代码

这是为什么呢?后面明明有啊,为什么还报错了,这一点就要注意了,这里的a是直接赋值的,不是var 定义的变量,他就不存在变量提升了,所以请记住这句话
只有var命令定义的变量才存在变量提升

函数提升

同样先看下面代码

//示例一
console.log(f1()) // 10;
function f1(){
    return 10;
}
console.log(f1()) // 10;

//示例二
console.log(f2()) // 报错:f2 is not a function
var f2 = function (){
    return 20;
}
console.log(f2()) // 20;复制代码

示例一为什么都可以打印出来正确的答案,而示例二为什么第一个打印会报错?

对比两个函数我们不难发现,示例一中的函数是声明式函数,示例二中函数是字面量式函数;
这能说明什么吗?当然,这能说明 函数的提升只对声明式函数有效,对字面量函数无效
也就是说,声明式函数才有函数提升这个概念;

我们来解析一下上面两个函数:

//示例一
function f1(){return 10}; 
//函数提升是将整个函数提升到最顶部;
console.log(f1()) 
//10 执行到这里,函数已经存在,所以打印出来是10
console.log(f1())
//10 同样函数已经存在,能打印出正确结果 10

//----------------分割线--------------------//

//示例二
var f2;//是的,这里是个变量,所以要遵循变量提升
console.log(f2()) 
// 没错,在这里f2是个变量,还不是函数
//所以把他当做函数使用,当然会报错说他不是一个函数
f2 = function (){return 20} 
//在这里将匿名函数赋给f2
console.log(f2())
//在此之前已经将匿名函数赋值给f2了,所以f2代表的就是这个函数
//所以自然就可以将f2作为函数来调用了复制代码

另外要强调的一句是,函数提升的优先级要高于变量提升,也就是函数会被优先放在顶部,而后才是变量


好了,这就是变量提升和函数提升,是不是感觉很简单呢,最后我们再来看一个例子;

console.log(a); //function (){return}
var a = 10;
function a(){
    return 10;
}
console.log(a); // 10;复制代码

这里是不是和之前说的冲突了?解析应该是下面这样;

function a(){return 10} 
//首先函数被提升到最顶部
var a
//变量名与函数名一致,但是并不会将函数a覆盖
//相反的此时的变量a将会被忽略;因为在内存中其实存的仅仅是函数名(变量名)
//不是整个函数,将函数当做变量a去存储,所以当碰到一样的变量名a的时候
//将会被忽略;

console.log(a)
//因为变量a被忽略,所以这里不会打印出来undefined,而是会打印a函数;
a = 10;
//给a赋值,将会覆盖之前的a函数,之前说过,函数a仅仅是存储为函数名a,
//将函数名a当成一个变量去存储,其实就相当于使用function定义了一个变量a
//和var 定义变量是一个概念;

console.log(a)
//这个时候a的值是10,所以打印的结果是10;复制代码

好了,关于变量提升和函数提升就讲到这里了,如果本篇文章帮助到了你,那么荣幸之至

原创不易,总结不易,手打不易,转载时请注明出处,谢谢

相关文章:

  • Linux shell笔记
  • Linux文件查找命令find,xargs详述【转】
  • 论调用约定
  • testngpp - next generation unit test framework for c/c++
  • WizKnowledge的插入代码插件
  • linux 下的磁盘配额
  • 基于centos4.4的mg手工下载RPM包安装顺序记录
  • 前端日刊君来也
  • JAVA 空间分配担保
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • CSS技术
  • input 全选和取消全选
  • 从中国男足看项目管理
  • 1. lvs+keepalived 高可用群集
  • CheckPoint常用命令
  • ES6指北【2】—— 箭头函数
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【附node操作实例】redis简明入门系列—字符串类型
  • co.js - 让异步代码同步化
  • KMP算法及优化
  • Mybatis初体验
  • PHP变量
  • Python 基础起步 (十) 什么叫函数?
  • 飞驰在Mesos的涡轮引擎上
  • 基于HAProxy的高性能缓存服务器nuster
  • 开源SQL-on-Hadoop系统一览
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​LeetCode解法汇总518. 零钱兑换 II
  • $refs 、$nextTic、动态组件、name的使用
  • %@ page import=%的用法
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (算法)Travel Information Center
  • (一)80c52学习之旅-起始篇
  • (转)甲方乙方——赵民谈找工作
  • (转)详解PHP处理密码的几种方式
  • ***利用Ms05002溢出找“肉鸡
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET BackgroundWorker
  • .NET Core 版本不支持的问题
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .net FrameWork简介,数组,枚举
  • .NET Reactor简单使用教程
  • .net6使用Sejil可视化日志
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .Net中的设计模式——Factory Method模式
  • /3GB和/USERVA开关
  • ::before和::after 常见的用法
  • [ffmpeg] aac 音频编码
  • [GDMEC-无人机遥感研究小组]无人机遥感小组-000-数据集制备