20190527-JavaScriptの打怪升级旅行 { 语句 [ 声明 ,变量 ] }
写在前面的乱七八糟:时间总是轻易地溜走,不留一丝念想,近一个月,倒是过得有点丧,从今天开始起,已经开始接触后台了,而JavaScript也只是大致有了个分类框架,那些细枝末节还有的补,任重道远,天将降大任于斯人也,然这也不算大任呐┓( ´∀` )┏
JavaScript发行于1992年,已经27年过去了,当时在Netscape公司的Brendan Eich会想到如今的JavaScript依旧这么火热的脚本语言吗?要说起这门语言,还得从下面的语句开始说起,我们的旅行,由此开始:

相信很多人在一开始学html时,都会写上"Hello World"这么一句话,而我在JavaScript学习中,写的第一个语句(statements)便是var a = 1;经过这一个月以来的学习,才惊觉这一句话里,竟可以包含这么多的知识点。
语句:声明 变量 赋值 数据;
1.声明
1.1声明方式
1.1.1使用关键词:var let const
1.1.2直接赋值:a = 1;
1.2声明关键词
1.2.1 var
早在ES5声明变量只有两种方法:
- var声明关键词,可用于声明全局作用域与函数作用域;
- function函数声明,可用于声明全局作用域与函数作用域;
1.2.2 let & const
ES6引入块作用域概念,并带来了另外两个声明关键词:let(变量) & const(常量),既然有var这个老骨干了,为什么还需要引入let 与 const呢?
这又不得不说到:顶层对象属性 & 全局变量,变量提升 & 暂时性死区,不捉急,一个个慢慢盘它就对了。
1.2.2.1顶层对象属性 & 全局变量
在ES5中,顶层对象的属性与全局变量是等价的。
顶层对象:在浏览器环境指window对象,在Node环境指global对象
全局变量:在全局作用域下运行的变量(后面再细盘)
现象:

F12后打开控制台,输入var a = 1;语句,再console.log(window),点开window,你会发生神奇的事情发生了,声明的全局变量a居然是window下面的属性

而同样的function a(){}函数声明也是如此,两者声明的全局变量都被当做顶层对象的属性挂载在顶层对象上,这说明什么?会带来什么影响呢?
说明:未声明的全局变量,自动成为全局对象的属性
问题:
1.没法在编译时便报出变量未声明的错误,只有运行时才知道
2.极容易创建全局变量
3.语义上,顶层对象是个有实体含义的对象,如此极易混淆顶层对象空间与全局作用域
方案:将全局变量与顶层对象属性分离 => ES6添加了let & const 关键词,class & import 命令
1.2.2.2变量提升(hoisting) & 暂时性死区(temporal dead zone,简称 TDZ)
现象:变量可以在声明之前使用,值为undefined

上图可得:var 声明的变量 a 在未声明时,便可被调用,而 let 声明的变量 b 在未声明时调用,便直接报错ReferenceError
变量提升:JavaScript 引擎的工作方式:解析代码,获取所有被声明的变量 => 一行一行地运行 => 所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升
暂时性死区:ES6明确规定:如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
说明:var 声明的变量,具有变量提升行为,而 let 声明的变量之前的范围属于暂时性死区
作用:主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为
那么问题又来了?有let为什么还要有const啊!JS又水我?
1.2.3 let || const
两者都可用于声明块级作用域,也就是{}包起来的作用域
1.2.3.1let
let 声明变量,其值与类型都可以改变,可重新赋值
1.2.3.2const
const 声明常量,但又分俩种情况:
1.声明原始值,不可二次赋值;
2.声明引用值,变量名不指向数据,而是指向数据所在的地址,只是保证变量名指向的地址不变,并不保证该地址的数据不变;
故在用 const 声明常量要注意。
综上,第一章BOSS:语句 の 第一层boss:声明,完结撒盐。
2.变量
2.1作用
存放值 / 表达式
2.2变量名
2.2.1标识符(identifier)
标识符(identifier):用来识别各种值的合法名称。最常见的标识符就是变量名,以及后面要提到的函数名
2.2.2命名规则
- 首字符:Unicode 字母(包括英文字母和其他语言的字母)|| 美元符号(
$)|| 下划线(_) - 第二个字符及后面的字符:Unicode 字母、美元符号和下划线 || 数字
0-9
2.2.3命名方法
- 羊肉串命名
- to_study
- 驼峰命名
- 大驼峰ToStudy
- 小驼峰toStudy
2.2.4命名禁忌
- 关键字(标识了 ECMAScript 语句的开头和/或结尾)
- break
- case catch continue
- default delete do
- else
- finally for function
- if in instanceof
- new
- return
- switch
- this throw try typeof
- var void
- while with
- JS报错:Identifier Expected
- 保留字(为将来的关键字而保留的单词)
- abstract boolean byte char class const
- debugger double enum export extends final float
- goto implements import int interface long
- native package private protected public
- short static super synchronized throws transient volatile
前方敌军即将上线:盘一下:执行环境(作用域),变量对象(全局 & 局部),作用域链
现象:

为什么第一次弹窗出来的不是1而是underfined呢?
解析:
1.进入全局环境:
1.1解析阶段:
var a ;// a === underfined
function b(){ };
1.2赋值阶段:
a = 1;
b();
2.函数b自执行,进入函数环境:
2.1解析阶段:
var a;// a === underfined
2.2赋值阶段:
window.alert(a)// 弹窗:underfined
a = 2;
window.alert(a)// 弹窗:2
执行环境:作用域
变量对象:用来保存执行环境下的变量和方法的
作用域链:一个个变量对象形成的作用域,通过变量对象形成的链条,即作用域链
前面介绍变量提升时,便说过JS引擎的解析方式,先提取声明,再赋值执行,故第一次弹窗是underfined而不是1,因为a已经在局部作用域内声明过了,那么问题又来了:若a没有在局部作用域内声明呢?

说明:此时,局部作用域内没有声明变量a,那么将顺着作用域链,向父级,爷爷级,一级级往上查找,直到最顶层,故弹窗1。
2.3全局变量 & 局部变量
2.3.1全局变量
变量在函数外定义,整个代码都可以调用的变量
2.3.2局部变量
变量在函数内声明,只能在函数内部访问
2.3.3注意点
2.3.3.1 当全局变量与局部变量重名时,优先使用局部变量
2.3.3.2 var 和 function 声明的变量都声明提前,赋值留在原地
2.4作用域 & 作用域链
2.4.1作用域
JS分两级作用域:
全局作用域:作用于全局环境(整个script标签)
局部作用域(函数作用域):作用于函数体内
2.4.2作用域链
一个个变量对象形成的作用域,通过变量对象形成的链条,即作用域链
综上,第一章BOSS:语句 の 第二层boss:变量,完结撒盐。
数据可是重头戏,下期见,┓( ´∀` )┏
20190527-JavaScriptの打怪升级旅行 { 语句 [ 声明 ,变量 ] }的更多相关文章
- 20190528-JavaScriptの打怪升级旅行 { 语句 [ 赋值 ,数据 ] }
写在前面的乱七八糟:今天考了试,emmm很基础的题,还是Mrs房的面试题让人绝望啊┓( ´∀` )┏,补了很多知识,很综合的题,坑也很多,总的来说,查漏补缺,其实是啥都缺~ 今天打的小BOSS主要是数 ...
- [label][JavaScript][The Defined Guide of JavaScript] 如何声明变量
因为觉得我自己的JavaScript基础很不扎实,或者可以说根本就没有所谓基础,所以就最近一直在看<The Defined Guide of JavaScript> . 在一边看的同时,我 ...
- 关于Javascript没有块级作用域和变量声明提升
Javascript是没有块级作用域的,在语句块中声明的变量将成为语句块所在代码片段的局部变量.例如: if(true){ var x=3; } console.log(x); 结果输出3. 再如: ...
- JavaScript 函数——语法,调用,返回值,局部变量,全局变量,未声明变量
JavaScript 函数是被设计为执行特定任务的代码块. JavaScript 函数会在某代码调用它时被执行. ㈠函数 ⑴什么是函数 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. ⑵ ...
- Javascript声明变量类型
声明变量类型 当您声明新变量时,可以使用关键词 "new" 来声明其类型: var carname=new String; var x= new Number; var y= ne ...
- 【JavaScript声明变量的规则】
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- javascript语法之声明变量
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- sql声明变量,及if -else语句、while语句的用法
--声明变量,同时为变量赋值 declare @n print @n --单独使用一条语句为变量复制 print @n print @n --通过set赋值与select复制的区别 select @n ...
- 为什么JavaScript声明变量的时候鼓励加var关键字
在JavaScript中,var用来声明变量,但是这个语法并不严格要求,很多时修改,我们可以直接使用一个变量而不用var声明它. var x = "XX"; y ="xx ...
随机推荐
- 想真正了解JAVA设计模式看着一篇就够了。 详解+代码实例
Java 设计模式 设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结 设计模式分为 23 种经典的模式,根据用途我们又可以分为三大类.分别是创建型模式.结构型模式和行为型模式 列举几种设 ...
- day38 02-Spring快速入门
Spring的核心是IOC和AOP,其他的什么像SpEL都是对IOC的支持. Spring里面的web指的是它可以使用Spring MVC. 集成指的是整合其他的框架. schema是所有配置文件的约 ...
- Codeforces 1150E(树、线段树)
要点 括号序列平衡度即树深度的性质 相当于中序遍历,则两点间最浅的地方即是LCA的性质 线段树维护\(d(a) + d(c) - 2*d(lca(a,c))\),一层层剥,思考维护这个量需要什么,结果 ...
- 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储。
https://github.com/kcloze/swoole-jobs 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储.参考资料:swoole https:/ ...
- 【JZOJ3623】【SDOI2014】数表(table) 树状数组+离线+莫比乌斯反演
题面 100 \[ Ans=\sum_{i=1}^n\sum_{j=1}^mg(gcd(i,j)) \] 其中, \[ g(d)=\sum_{i|d}i \] 我们注意到\(gcd(i,j)\)最多有 ...
- 【GDOI2017 day2】凡喵识图 二进制切分
题面 100 有一个显然的做法是\(O(n^2)\): 想办法优化这个做法: 我们给一个64位整数,切分成四个16位整数. 那么如果两个64位整数符合汉明距离为3的话,那么两者切分的四个16位整数中: ...
- 跟我一起学extjs5(02--建立project项目)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jfok/article/details/35569057 跟我一起学extjs5(02--建立pro ...
- C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题
问题背景 C#小白,由于本公司IM系统服务端(java)是本人独立开发的,加上现在所在项目需要对接IM系统,于是IM的客户端(C#实现)对接工作就交给我了.于是C#小白的我天真的以为只要调用C#端的S ...
- navgator 用于浏览器检测
- 【水滴石穿】bstmy-blend-app
这个项目是一个简单的底部导航切换页面 项目的地址为:https://github.com/Bstmy/bstmy-blend-app 先看效果 点击首页是首页面,点击个人中心是个人中心页面 先看代码 ...