“Code tailor”,为前端开发者提供技术相干资讯以及系列根底文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。
前言
在开始学习之前,咱们想要告诉您的是,本文章是对 JavaScript
语言常识中 “ 语言根底 - 语法和变量 ” 局部的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习
- JavaScript 语法
- 申明变量与赋值
汇总总结
第一段代码
在开始学习 JavaScript
时,咱们先看一段 JavaScript
代码,如下:
console.log('Hello JavaScript!')
你能猜到这段代码的后果吗?这段代码的操作就是在控制台输入后果是 Hello JavaScript!
,到这里第一段代码就完结了。
JavaScript 语法
辨别大小写
你须要晓得,ECMAScript
中所有都辨别大小写。无论是变量、函数名还是操作符,都辨别大小写。举个例子,变量 XHS
和变量 xhs
是两个不同的变量。
标识符
所谓标识符,就是变量、函数、属性或函数参数的名称。标识符能够由一或多个下列字符组成:
- 第一个字符必须是一个字母、下划线 (
_
) 或美元符号($
); - 剩下的其余字符能够是字母、下划线、美元符号或数字。
标识符中的字母能够是扩大 ASCII(Extended ASCII)
中的字母,也能够是 Unicode
的字母字符.
依照常规,ECMAScript
标识符应用驼峰大小写模式,即第一个单词的首字母小写,前面每个单词的首字母大写,如:
xhsRookies
xhsRookiesBoy
尽管这种写法并不是强制性的,但因为这种模式跟 ECMAScript
内置函数和对象的命名形式统一,所以算是最佳实际。
留神 关键字、保留字、
true
、false
和null
不能作为标识符。
代码正文
JavaScript
中有两种正文形式:单行正文和多行正文。
正文的代码在程序中不会执行
单行正文以两个斜杠字符结尾,如:
// 单行正文
多行正文以一个斜杠和一个星号 (/*
) 结尾,以它们的反向组合 (*/
) 结尾,如:
/* 这是多行
正文 */
严格模式
ECMAScript 5
减少了严格模式 (strict mode
) 的概念。严格模式是一种不同的 JavaScript
解析和执行模型,ECMAScript 3
的一些不标准写法在这种模式下会被解决,对于不平安的流动将抛出谬误。要对整个脚本启用严格模式,在脚本结尾加上这一行:
'use strict'
尽管看起来像个没有赋值给任何变量的字符串,但它其实是一个预处理指令。任何反对 JavaScript
的引擎看到它都会切换到严格模式。抉择这种语法模式的目标是不毁坏 ECMAScript 3
语法。
也能够独自指定一个函数在严格模式下执行,只有把这个预处理指令放到函数体结尾即可:
function doSomething() {
'use strict'
// 函数体
}
严格模式会影响 JavaScript
执行的很多方面,所有古代浏览器都反对严格模式。
语句
ECMAScript
中的语句以分号结尾。省略分号意味着由解析器确定语句在哪里结尾,如上面的例子所示:
var sum = a + b // 没有分号也无效,但不举荐
var diff = a - b // 加分号无效,举荐
即便语句开端的分号不是必须的,也应该加上。记着加分号有助于避免省略造成的问题,比方能够防止输出内容不残缺。此外,加分号也便于开发者通过删除空行来压缩代码(如果没有结尾的分号,只删除空行,则会导致语法错误)。加分号也有助于在某些状况下晋升性能,因为解析器会尝试在适合的地位补上分号以纠正语法错误。
关键字与保留字
ECMA-262
形容了一组保留的 关键字,这些关键字有非凡用处,比方示意管制语句的开始和完结,或者执行特定的操作。依照规定,保留的关键字不能用作标识符或属性名。
break do in typeof
case else instanceof var
catch export new void
class extends return while
const finally super with
continue for switch yield
debugger function this
default if throw
delete import try
标准中也形容了一组将来的 保留字,同样不能用作标识符或属性名。尽管保留字在语言中没有特定用处,但它们是保留给未来做关键字用的。以下是 ECMA-262
第 6 版为未来保留的所有词汇。
始终保留:
enum
严格模式下保留
implements package public
interface protected static
let private
模块代码中保留
await
申明变量并赋值
在 JavaScript
中,有 3 个关键字能够申明变量: var
、const
和 let
。其中,var
在 ECMAScript
的所有版本中都能够应用,而 const
和 let
只能在 ECMAScript 6
(将在前面学到) 及更晚的版本中应用。
var 关键字
要定义变量,能够应用 var
关键字,后跟变量名:
var xhsRookies
这行代码定义了一个名为 xhsRookies
的变量,能够用它保留任何类型的值。ECMAScript
实现变量初始化,因而能够同时定义变量并设置它的值:
var xhsRookies = 'hi'
xhsRookies
被定义为一个保留字符串值 hi
的变量。像这样初始化变量不会将它标识为字符串类型,只是一个简略的赋值而已。随后,不仅能够扭转保留的值,也能够扭转值的类型:
var xhsRookies = 'hi'
xhsRookies = 100 // 非法,但不举荐
在这个例子中,变量 xhsRookies
首先被定义为一个保留字符串值 hi
的变量,而后又被重写为保留了数值 100
。尽管不举荐扭转变量保留值的类型,但这在 ECMAScript
中是齐全无效的。
1. var 申明作用域
应用 var
操作符定义的变量会成为蕴含它的函数的局部变量。比方,应用 var
在一个函数外部定义一个变量,就意味着该变量将在函数退出时被销毁:
function xhsTest() {var xhsRookies = 'hi' // 局部变量}
xhsTest()
console.log(xhsRookies) // 出错!
这里,xhsRookies
变量是在函数外部应用 var
定义的。函数叫 xhsTest()
,调用它会创立这个变量并给它赋值。调用之后变量随即被销毁,因而示例中的最初一行会导致谬误。不过,在函数内定义变量时省略 var
操作符,能够创立一个全局变量:
function xhsTest() {xhsRookies = 'hi' // 全局变量}
xhsTest()
console.log(xhsRookies) // "hi"
去掉之前的 var
之后,xhsRookies
就变成了全局变量。只有调用一次函数 xhsTest()
,就会定义这个变量,并且能够在函数内部拜访到。
尽管能够通过省略 var 操作符定义全局变量,但不举荐这么做。在部分作用域中定义的全局变量很难保护,也会造成困惑。
如果须要定义多个变量,能够在一条语句中用逗号分隔每个变量(及可选的初始化):
var xhsRookies = 'hi',
xhsFound = false,
xhsNumber = 29
这里定义并初始化了 3 个变量。
2. var 申明晋升
应用 var
时,上面的代码不会报错。这是因为应用这个关键字申明的变量会主动晋升到块作用域 5 顶部:
{console.log(xhsNumber) // undefined
var xhsNumber = 26
}
之所以不会报错,是因为 ECMAScript
运行时把它看成等价于如下代码:
{
var xhsNumber
console.log(xhsNumber) // undefined
xhsNumber = 26
}
这就是所谓的“晋升”(hoist
),也就是把所有变量申明都拉到块作用域的顶部。
let 申明
let
跟 var
的作用差不多,但有着十分重要的区别。最显著的区别是,let
申明的范畴是块作用域,而 var
申明的范畴是函数作用域。
{
var xhsRookies = 'xhs-rookies'
console.log(xhsRookies) // xhs-rookies
}
console.log(xhsRookies) // xhs-rookies
{
let xhsNumber = 26
console.log(xhsNumber) // 26
}
console.log(xhsNumber) // ReferenceError: xhsNumber 没有定义
在这里,xhsNumber
变量之所以不能在块作用域内部被援用,是因为它的作用域仅限于该块外部。块作用域是函数作用域的子集,因而实用于 var
的作用域限度同样也实用于 let
。
let
也不容许同一个块作用域中呈现冗余申明。这样会导致报错:
var xhsRookies
var xhsRookies
let xhsNumber
let xhsNumber // SyntaxError; 标识符 xhsNumber 曾经申明过了
当然,JavaScript
引擎会记录用于变量申明的标识符及其所在的块作用域,因而嵌套应用雷同的标识符不会报错,而这是因为同一个块中没有反复申明:
var xhsRookies = 'xhs-rookies'
console.log(xhsRookies) // 'xhs-rookies'
{
var xhsRookies = 'xhs-rookies-boy'
console.log(xhsRookies) // 'xhs-rookies-boy'
}
let xhsNumber = 30
console.log(xhsNumber) // 30
{
let xhsNumber = 26
console.log(xhsNumber) // 26
}
对申明冗余报错不会因混用 let
和 var
而受影响。这两个关键字申明的并不是不同类型的变量,它们只是指出变量在相干作用域如何存在。
var xhsRookies
let xhsRookies // SyntaxError
let xhsNumber
var xhsNumber // SyntaxError
1. 全局申明
与var
关键字不同,应用 let
在全局作用域中申明的变量不会成为 window
对象的属性(var
申明的变量则会)。
var xhsRookies = 'xhsRookies'
console.log(window.xhsRookies) // 'xhsRookies'
let xhsNumber = 26
console.log(window.xhsNumber) // undefined
不过,let
申明依然是在全局作用域中产生的,相应变量会在页面的生命周期内存续。因而,为了 防止 SyntaxError
,必须确保页面不会反复申明同一个变量。
2. let 作用域
在 let
呈现之前,代码块中定义的迭代变量会渗透到内部:
{var xhs = 5}
console.log(xhs) // 5
改成应用 let
之后,这个问题就隐没了,因为 let
变量的作用域仅限于代码块外部:
{let xhs = 0}
console.log(xhs) // ReferenceError: xhs 没有定义
const 申明
const
的行为与 let
基本相同,惟一一个重要的区别是用它申明变量时必须同时初始化变量,且尝试批改 const
申明的变量会导致运行时谬误。
const xhsNumber = 26
xhsNumber = 36 // TypeError: 给常量赋值
// const 也不容许反复申明
const xhsRookies = 'xhs-rookies'
const xhsRookies = 'xhs-rookies-boy' // SyntaxError
// const 申明的作用域也是块
const xhsRookies = 'xhs-rookies'
console.log(xhsRookies) // xhs-rookies
变量命名规定
- 严格辨别大小写(大写的变量和小写的变量是不同的变量);
- 变量名能够由数字、字母 (大小写都能够)、下划线、美元符(
$
) 组成,然而不能以数字结尾; - 不能是
javascript
中的关键字和保留字,如:if
,else
,function
等; - 变量名须要有意义,即语义化,加强代码可读性,比方:存储年龄用
age
,姓名用name
,能够避免过段时间就不了解代码是什么了,也能够避免单干时他人看不懂; - 应用驼峰命名法:从第二个单词开始,首字母大写,如用户集体数据(
userPersonalData
);
题目自测
一:下列代码输入后果是什么?
var xhsRookies = 'hello'
function textFun() {var xhsRookies = 'hi'}
console.log(xhsRookies)
- A.
hello
- B.
hi
- C.
hi hello
- D.
hello hi
二: 下列代码输入后果是什么?
console.log(xhsRookies)
var xshRookies = 'xhs-rookies'
console.log(xhsNumber)
let xhsNumber = 26
三: 下列代码输入后果是什么?
const xhsNumber = 26
xhsNumber = 36
console.log(xhsNumber)
题目解析
一、
Answer:A
这道题考查的是 var
申明作用域,在第一行 xhsRookies
变量在 textFun
函数作用域外应用 var
定义的,第三行 xhsRookies
变量是在 textFun
作用域外部应用 var
定义的。所以最初一行输入 xhsRookies
其实是第一行定义的,后果是:hello
二、
Answer:
undefined
ReferenceError: Cannot access ‘xhsNumber’ before initialization
此题考查的是变量的晋升,输入 xshRookies
时,因为 xshRookies
应用 var
申明的,存在变量晋升,所以在输入前会认为 var xshRookies
并未赋值,所以是undefind
; 在解析代码时,JavaScript
引擎也会留神呈现在块前面的 let
申明,只不过在此之前不能以任何形式来援用未声明的变量。在 let
申明之前的执行霎时被称为“暂时性死区”(temporal dead zone
),在此阶段援用任何前面才申明的变量都会抛出 ReferenceError
。
三、
Answer:
TypeError: Assignment to constant variable.
此题考查的是 const
申明特点,用它申明变量时必须同时初始化变量,且尝试批改 const
申明的变量会导致运行时谬误。