es6 import会变量提升吗

ES6 import会产生变量提升的现象。变量提升是将变量声明提升到它所在作用域的最开始的部分。js要经历编译跟执行阶段,在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二部则是在执行阶段执行到该语句的时候才执行。

es6 import会变量提升吗

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

变量提升

JavaScript是单线程语言,所以执行肯定是按顺序执行。但是并不是逐行的分析和执行,而是一段一段地分析执行,会先进行编译阶段然后才是执行阶段。在编译阶段阶段,代码真正执行前的几毫秒,会检测到所有的变量和函数声明,所有这些函数和变量声明都被添加到名为Lexical Environment的JavaScript数据结构内的内存中。所以这些变量和函数能在它们真正被声明之前使用。

先从一个简单的例子来入手:

 a = 2; var a; console.log(a);

登录后复制

以上的代码会输出什么,假如这段代码是从上到下执行的话,肯定会输出undefined,然而JavaScript却不是自上而下执行的语言。这段代码的输出结果是2,意外吗?那么,为什么会这样,这个关键点就在于–变量提升。他会将当前作用域的所有变量的声明,提升到程序的顶部,因此,上面的代码等价于以下代码,这样是不是就能明白一些了?

 var a; a = 2; console.log(a);

登录后复制

那么我们再看一个例子:

 console.log(a); var a = 2;

登录后复制

这段代码又会输出什么?输出2吗?其实这段代码会输出undefined。这又是为什么呢?刚刚说过,JavaScript会将变量的声明提升到顶部,但是赋值语句是不会提升的,对于js来说,var a = 2是分为两步解析的:

var a;a = 2;

登录后复制

而js只会提升 var a 这句,所以刚刚的语句等价于:

 var a; console.log(a); a = 2;

登录后复制

那么,为什么会有变量提升?

为什么会出现变量提升这个现象呢?因为js与其他语言一样,都要经历编译跟执行阶段。而js在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二部则是在执行阶段执行到该语句的时候才执行。

ES6的import变量提升

ES6 import 会产生变量提升的现象。

比如以下的测试代码,

// a.jsconsole.log('I am a.js...')import { foo } from './b.js';console.log(foo);// b.jsconsole.log('I am b.js...')export let foo = 1;

登录后复制

运行a.js,

// node -r esm a.js I am b.js...I am a.js...1

登录后复制

打印的结果是先出现‘I am b.js…’,然后再出现‘I am a.js…’,这就是变量提升的现象。

这是因为 ES6 在语言标准层面上实现了模块功能,所以当对a.js预编译时发现关键词import后,先去加载b.js,所以先输出‘I am b.js…’。

整个流程是,

1.png

变量提升的产生,其实与变量对象的创建过程有关。

变量对象创建过程

变量对象(Variable Object)的创建,依次经历以下几个步骤。

2.png

检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。

检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

function声明会比var声明优先级更高一点。

function test() {  console.log(a);  console.log(foo());  var a = 1;  function foo() {    return 2;  }}test();

登录后复制

直接从test()的执行上下文开始理解。

// 创建过程testEC = {    // 变量对象    VO: {},    // 作用域链    scopeChain: {}}// VO 为 Variable Object 的缩写,即变量对象VO = {    arguments: {...},    foo:     // 表示foo的地址引用    a: undefined}

登录后复制

test()执行的结果是,

// node -r esm demo01.js undefined2

登录后复制

其实,上面的代码demo01.js,变成了这样的执行顺序,

function test() {    function foo() {        return 2;    }    var a;    console.log(a);    console.log(foo());    a = 1;}test();

登录后复制

【相关推荐:javascript学习教程

以上就是es6 import会变量提升吗的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2921622.html

(0)
上一篇 2025年3月11日 18:30:30
下一篇 2025年2月19日 11:29:53

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • jquery怎么移除z-index样式

    jquery移除z-index样式的方法:1、利用css()移除,只需将z-index属性的值设置为默认值“auto”即可,语法“$(“选择器”).css(“z-index”,”a…

    2025年3月11日 编程技术
    200
  • jquery怎么设置元素多个属性值

    jquery设置元素多个属性值的方法:1、使用attr()设置,语法“$(selector).attr({属性名:属性值;属性值:属性值…})”;2、使用prop()设置,语法“$(selector).prop({属性名:属性值…

    2025年3月11日 编程技术
    200
  • jquery中的$有啥作用

    作用有:1、作为jQuery包装器,利用选择器来选择DOM元素,语法“$(“选择器”)”;2、功能函数前缀,作为通用实用工具函数的命名空间的前缀,例“$.trim(sString);”;3、解决window.onlo…

    2025年3月11日
    200
  • jquery load方法有什么缺陷

    jquery load方法的缺陷:1、load方法会自动忽略掉head、body、script标签;2、动态加载后会出现滚动条偏移的问题,只需在load方法的回调函数里面加入“$(document).scrollTop(0);”即可解决;3…

    2025年3月11日
    200
  • jquery的toggle()方法有什么用

    toggle()方法可用于切换被选元素的hide()与show()方法,进而控制元素的显示和隐藏,语法“$(selector).toggle(speed,callback)”;也可用于绑定两个或多个事件处理器函数,以响应被选元素的轮流的cl…

    2025年3月11日
    200
  • jquery怎么修改tr属性值

    jquery修改tr属性值的方法:1、利用jquery选择器获取指定tr元素,语法“$(“选择器”)”,会返回包含指定tr元素的jquery对象;2、使用attr()函数修改指定tr元素对象的属性值,语法“tr元素对…

    2025年3月11日
    200
  • jquery怎么改变style样式

    jquery改变style样式的方法:1、利用css()给指定元素设置新style样式即可,语法“$(selector).css({“属性名1″:”属性值1″,”属性名2&#824…

    2025年3月11日
    200
  • es6中新增数组方法有哪些

    es6数组方法有:1、Array.from(),用于将类数组对象或可遍历对象转为真正的数组;2、Array.of(),用于将一组值,转为数组;3、copyWithin(),用于在当前数组内部,将指定位置的成员复制到其他位置;4、fill()…

    2025年3月11日
    200
  • es6中filter过滤器有什么作用

    在es6中,filter过滤器对数组元素进行过滤并返回一个新的数组。filter()函数会创建一个新数组,其包含通过所提供回调函数实现的测试的所有元素,语法“arr.filter(callback(element[, index[, arr…

    2025年3月11日
    200
  • es6中reduce()怎么用

    在es6中,reduce()函数用于对数组中的每个元素从左到右依次执行一个由用户提供的回调函数,并将其累积结果汇总为单个返回值;语法“arr.reduce(callback(accumulator, currentValue[, index…

    2025年3月11日 编程技术
    200

发表回复

登录后才能评论