美文网首页JavaScript那些事
js基础阵营:变量篇之变量,函数提升

js基础阵营:变量篇之变量,函数提升

作者: 来瓶二锅头00 | 来源:发表于2022-03-07 21:35 被阅读0次
上面已经介绍完了变量的定义,以及变量的作用域问题,这章我们来看看变量提升的问题。在进行这章开始前,我们先来探讨一个很悠久的问题,那就是 image.png

哈哈。开玩笑。言归正传。我们先看下面代码

console.log(a);
var  a = 2;
输出结果是 image.png 直觉上我们理解的是程序会从上往下,顺序执行,按照这个逻辑,我们应该得到的是这样的 image.png
但是实际上感觉是代码是这样的
var a;
console.log(a);
a = 2;

为什么会这样呢?这里就需要知道编辑器在执行程序所需要的做的事了,编辑器在执行程序的时候会先执行编译,那么编译阶段有一部分的工作是找到所在作用域中的所有的声明,所以我们可以理解为,在js中任何代码在执行前,其(函数,变量)声明都会被先处理。因此,我们看到var a = 2;其实在编译器中是var a和a = 2;两部分。var a,是在编译阶段执行的,a = 2在执行阶段执行。这个过程就好像变量以及函数声明从他们原有的代码处被移动了,所以叫做提升。
上面说的是变量,那么函数呢?是否也会提升呢?我们来看下下面的例子

sayName();
function sayName(){
  console.log('来瓶二锅头');
}
将上面代码放到控制台,看下结果 image.png

显而易见,我们的函数声明也提升了,实际上在执行的时候代码是这样的

function sayName(){
  console.log('来瓶二锅头');
}
sayName();

那么函数内部的变量是否也会提升呢?我们再来看下这个例子

function sayName(){
  console.log(name);
  var name = '来瓶二锅头';
}
sayName();
在控制台我们看下结果 image.png

可以看到我们输出的是undefined,而不是referenceError.所以函数中的变量也得到了提升,实际的代码是这样的

function sayName(){
  var name;
  console.log(name);
  name = '来瓶二锅头';
}
sayName();

所以前面我理解的结论 在js中任何代码在执行前,其(函数,变量)声明都会被先处理是正确的。
此时我们在针对函数来想下,除了上面的函数声明,我们如果通过函数表达式是否会得到提升呢?看下下面的代码

sayName();
var sayName = function (){
  console.log('来瓶二锅头');
}
输出到控制台,看下结果 image.png

此时报错不在referenceError而是TypeError。那么我们在试下下面的代码看看

console.log(sayName);
var sayName = function (){
  console.log('来瓶二锅头');
}
在控制台执行下看看结果 image.png

至此大家应该明白啥意思了吧。前面说过了,我们会把声明提前,但是执行的依旧在原位置,所以程序执行前面的代码的时候,实际上是这样的

var sayName;
sayName();
sayName = function (){
  console.log('来瓶二锅头');
}

这个时候,sayName只是被定义了,不是一个函数,所以执行sayName()会报TypeError,而执行console.log(sayName);也不会报错
那么我们如果通过函数表达式加具名函数一起使用,会是什么样子呢?一起看下下面代码

sayName();
a();
var sayName = function a(){
  console.log('来瓶二锅头')
}
在控制台执行下,看下结果 image.png

可以看到sayName是报TypeError,但是a()是报ReferenceError错误。sayName上面说过了,那a()是为什么呢?我们在看下下面的代码

var sayName = function a(){
  console.log(a);
  console.log('来瓶二锅头')
}
sayName();
控制台看下结果 image.png

那么我们可以看出实际上程序在执行的时候,代码是下面这样的

var sayName;
sayName = function(){
  var a = 函数本身;
  console.log(a);
  console.log('来瓶二锅头')
}
sayName();

所以我们从另一个角度也能得出一个结论,那就是如果函数表达式是跟着具名函数,那么具名函数实际是这个方法本身。在其函数作用域内生效。是不是很神奇。那么原理具体是什么呢?我们在后面的函数篇来给出解答(挖坑,看下后面是否真的可以给填上,哈哈)。

上面说到了函数以及变量提升的问题,那么我们再来思考一个问题,那就是如果函数名和变量名相同的时候,谁在前呢? image.png
我们来看下下面的例子
test()
var test;
function test() {
  console.log('a');
}
test = function(){
  console.log('b');
}
控制台执行结果为 image.png

那么我们可以看出,在执行过程中,实际上为

function test() {
  console.log('a');
}
var test;
test();
test = function(){
  console.log('b');
}

所以我们可以得出结论,在变量以及函数相同的情况下函数优先。我们再来思考一个问题,那就是变量实际上存在覆盖的问题,那么下面的代码执行的结果是啥呢?

test();
function test(){
  console.log('a');
}
var test = function(){
  console.log('b'); 
}
function test(){
  console.log('c');
}

按照我们上面说的编译时候提升的问题,代码可以理解为

function test(){
  console.log('a');
}
function test(){
  console.log('c'); 
}
var test;
test();
test = function(){
  console.log('b'); 
}

由于存在 重载,所以执行结果为c。
我们再来设想一个场景,如果我们在普通的块级作用域中定义函数,会怎么样呢?看下下面的代码

test1()
if(true){
    function test1(){
        console.log('1')
    }
}
结果为 image.png

为什么呢?我们都知道普通的块级作用域会将变量提升到上级作用域中,那么实际上代码逻辑为

var test1;
test1();
if(true){
  test1 = function(){
   console.log('1')
  }
}

所以你懂了吗?至此关于提升的问题结束了。接下来我们将看看变量的类型一系列问题。

相关文章

  • js基础阵营:变量篇之变量,函数提升

    上面已经介绍完了变量的定义,以及变量的作用域问题,这章我们来看看变量提升的问题。在进行这章开始前,我们先来探讨一个...

  • js基础阵营:变量篇之特殊变量-数组

    前面我们以及说过了,变量的一些基础知识,这章我们将来看看特殊一个变量数组。在其他语言中我们可以知道,数组一般存储的...

  • js基础阵营:变量篇之特殊变量-对象

    这一章,我们将好好去看看一个特殊的变量,对象。我们先看看官方的定义:无序属性的集合,其属性可以包含基本值,对象,或...

  • JS中的提升

    JS中包含两种提升,变量提升和函数提升。 变量提升 变量提升只能是var或者function声明的变量或者函数,l...

  • 前端经典面试题合集(一)

    1.谈谈变量提升 考察点:js基础知识,js执行机制,变量的提升答:执行js代码时,会生成执行环境,在函数中的代码...

  • js基础阵营:变量篇之变量类型

    前面我们已经说过了变量的提升,那么变量具体有哪些类型呢?当前JavaScript具有5个基本数据类型,分别是:nu...

  • Javascript 变量执行过程 和 数组 & 对象的区别

    变量提升 JS执行过程1. 先提升(先提升函数,再提升变量,如果名字一样,变量提升会覆盖函数提升)2. 再执行,如...

  • js基础阵营:变量篇之变量作用域

    上面已经介绍完了变量的定义,说完定义肯定要说下变量的常见的问题。其实变量的常见问题说来说去也就那么几个,变量作用域...

  • 猫眼

    var变量提升,函数声明提升,消除变量声明提升(let); 高阶函数,函数式的编程,柯里化 原型链继承,js面向对...

  • js基础阵营:变量篇之特殊变量-对象的创建

    上一章,我们说到了对象的一些基本的属性,这一章,我们来看下如何去创建一个对象。在js中创建对象有两种方式,一种是单...

网友评论

    本文标题:js基础阵营:变量篇之变量,函数提升

    本文链接:https://www.haomeiwen.com/subject/rrxorrtx.html