一、var 声明

ES6之前,js 中声明变量基本上用 var 关键字;

1、如果访问未声明的变量,会报错:ReferenceError

2、声明了未赋值,值为 undefined,跟前面的报错是两回事,虽然信息看起来像;

3、对于没有声明的变量可以直接赋值,不过这是一个非常不好的习惯;

而用 var 声明的全局变量,作为全局对象的属性,是不可配置的;

4、重复声明等价于赋值语句;

JavaScript从来不会告诉你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见(不过,它会执行后续声明中的变量初始化)。

5、声明提前(hoisting)

由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫做“hoisting”。“hoisting”就像是把所有的变量声明移动到函数或者全局代码的开头位置,但是 var 的赋值操作保留在原处。

声明原理:var 声明在代码执行之前,被提升到所在函数或全局环境的顶部,仅仅是声明提前,不涉及赋值操作;

总结:

  在 var 声明的函数或全局环境访问:在赋值操作之前访问,返回 undefined,不报错;在赋值操作之后访问,返回实际值,不报错;

  在 var 声明的函数或全局环境访问,报错,除非闭包;

举例:

实际上等价于:

更多例子:戳 MDN

二、let,const 声明

书上说没有声明提前,这样理解也没有问题,所以直接看 三 吧;

但是我的总结是可能有声明提前:

  1、在声明的函数或全局环境访问:

    在声明的代码块之访问:声明的位置之前访问(即使是使用 typeof),会报错(官方称”暂时性死区”);声明的位置之后访问,返回实际值;

    在声明的代码块之访问:报错(但使用 typeof 操作符不报错,返回不正确,可能为 undefined,与上述相比,证明了可能有声明提前);

  2、在声明的函数或全局环境访问,报错,除非闭包;

  证明可能有声明提前的代码:

function f() {
console.log(typeof a);
if (true) {
let a = 0;
}
}
f();//undefined

  下面代码报错:

function f() {
if (true) {
console.log(typeof a);
let a = 0;
}
}
f();//ReferenceError: a is not defined

  下面不报错:

function f() {
if (true) {
console.log(typeof b);
let a = 0;
}
}
f();//undefined

三、函数声明语句(不是函数表达式)

声明提前原理:函数声明语句在代码执行之前,被提升到所在函数或全局环境的顶部;

总结:

  在声明的函数或全局环境访问:都返回实际值;

  在声明的函数或全局环境访问,报错,除非闭包;

实际上是跟 var 一样声明提升了,不同的是:函数整体提升,不仅仅是声明提升,而且没有块级绑定(ES6 严格模式下会有);

参考资料:

JavaScript权威指南-第6版

JavaScript高级程序设计-第3版

深入理解ES6-中

js 中的变量声明提前总结的更多相关文章

  1. Js中有关变量声明和函数声明提升的问题

    在ECMAScript5中没有块级作用域一说,只有函数作用域和全局作用域,在其中声明的变量和函数和其他语言的展现形式不同,在某些情况下不一定需要先定义后使用,函数和变量的使用可以在其声明之前,这到底是 ...

  2. [JavaScript]JS中的变量声明与有效域

    1.变量声明 var a = 1; //使用var声明变量 b = 1; //不使用var 第一种情况,在当前域中声明一个名为a的变量,如果实在方法内则为局部变量,若在最外层声明则a为全局变量. 第二 ...

  3. js函数中变量声明提前

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. js中变量声明提前

    demo1: var a=10; function b(){alert(a); var a=20; alert(a)} b()//undefined 20 因为:js编译器在执行b这个函数时,会把函数 ...

  5. 【JS点滴】声明提前,变量声明提前,函数声明提前,声明提前的先后顺序

    声明提前,函数声明提前,好吧,老生常谈的问题了.正好,前些天在掘金看到一道关于声明提前的笔试题,那么这里就以这道题来作为本文的引子吧,代码如下: console.log(a)//? a();//? ; ...

  6. JavaScript变量声明提前

    上周四吃完午饭,leader发了一道JavaScript的题目给我们做,我们Team里面有做前端的,有做后台的,也有做mobile web的,所以大家对题目的理解各自都不一样,然后在QQ讨论组里面进行 ...

  7. js中的变量提升(hoisting)

    来看如下代码: function HelloJS(){ var array = [1,2,3,4,5]; for(var i in array){ } alert(i); } HelloJS(); a ...

  8. Javascript开发技巧(JS中的变量、运算符、分支结构、循环结构)

    一.Js简介和入门 继续跟进JS开发的相关教程. <!-- [使用JS的三种方式] 1.HTML标签中内嵌JS(不提倡使用): 示例:<button onclick="javas ...

  9. JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构

    JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...

随机推荐

  1. HTML十进制字符编号

    有时候写文章时,段落里引用的代码莫名的就被解释到原本的html中了,通过用一些HTML里特殊字符的编码即可回到原文,保留原格式. 字符 十进制字符编号 实体名字 说明 ! ! — 惊叹号Exclama ...

  2. ARM开发工具软件命令具体解释---嵌入式回归第三篇

    先从bootloader開始,由于临时眼下这些都会是裸机程序相关. 本人这里是VMwarm10.0上安装的红帽linux虚拟机.从以下的截图中能够看出 裸机开发流程: 这里先做第三步(第一步第二步已提 ...

  3. WannaCry病毒应急处置

    WannaCry病毒应急处置 病毒介绍   近期勒索病毒WannaCry大面积爆发,并迅速蔓延.被感染的机器,病毒会自动加密系统中的图片.文档.音频.视频等几乎所有类型的文件,必须缴纳高额勒索金(人民 ...

  4. 05、Windows Store app 的图片裁切(更新)

    在 Win Phone Silverlight api 中,有一个 PhotoChooserTask 选择器,指定宽.高属性,在选择图片的时候, 可以进行裁切,代码: PhotoChooserTask ...

  5. hdu1142(dj+记忆化搜索)

    题意:给你n各点,m行关于这些点的联通关系,以及距离,求从1这个点到2这个点之间,下一个点到2这个点比当前点到2这个点的距离要小的路径的条数...... 思路:dj+记忆化搜索....... #inc ...

  6. cocos2dx集成友盟社会化分享图片崩溃问题

    本人不懂oc,一步一步按照友盟的文档做,好不容易把分享做好了,结果在 分享图片的时候宕掉了.各种测试,搞了一下午终于搞定了. 如下是友盟文档的做法,错误就在[UIImage imageNamed:@& ...

  7. 编写自己的代码库(javascript常用实例的实现与封装)

    https://segmentfault.com/a/1190000010225928

  8. Unix系统编程()信号处理器简介

    信号处理器简介 信号处理器程序(也称为信号捕捉器)是当指定信号传递给进程时将会调用的一个函数.这里会学习信号处理器的基本原理,后面将继续学习. 调用信号处理器程序,可能会随时打断主程序流程:内核代表进 ...

  9. MapReduce原理<转>

    江湖传说永流传:谷歌技术有"三宝",GFS.MapReduce和大表(BigTable)! 谷歌在03到06年间连续发表了三篇很有影响力的文章,分别是03年SOSP的GFS,04年 ...

  10. 扫描线 - UVALive - 6864 Strange Antennas

    Strange Antennas Problem's Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=87213 M ...