目标
- 了解 JS 基础语法
- 如何创建变量
- let、var、const 之间的区别
- 了解掌握流程控制等相关语法
- 解构
- 模板字符串
- 掌握字符串的Api
ES6 的发展过程
ECMAScript 6.0(ES6)是 JavaScript 语言的新一代标准,它于 2015 年 6 月正式发布,它的目标是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现,日常场合,这两个词是可以互换的。
在 ES6 之前,JavaScript 语言是非常落后的,很多现代化的特性都不具备,难以支撑大型应用的开发,ES6 的发布,使得 JavaScript 彻底改变。
目前 ES 的版本升级成为了一个不断滚动的流程,标准委员会最终决定,标准在每年的 6 月份正式发布一次,作为当年的正式版本。接下来的时间,就在这个版本的基础上做改动,知道下一年的 6 月份,草案就变成了新一年的版本,这样一来,就不需要以前的版本号了,只需要用年份来标记。
ES6 于 2015 年发布,也称为 ES2015,之后每年发布的版本变化都非常小,因此,ES6 既是一个历史名词,也是一个泛指,涵盖了 ES6 之后的所有标准,所以我们简单认为 ES6 就是指的“新一代的 JavaScript”语言,在发布之初 ES6 面临着许多兼容性的问题,主流的 JavaScript 引擎支持程度还不够高,通常需要使用 Babel 之类的工具来进行转义,现在我们可以借助最新的 JS 引擎来直接执行原生 ES6 代码了。
ES6 包含的内容非常多,本课程内容不会对 JavaScript 基础语法做过多的讲解,这部分内容需要自行学习,这里主要介绍一些常见 API 的使用,如果想要熟练使用 JavaScript,首先需要熟练掌握常用的 API。
jQuery已经完成了它的历史使命,它的很多 API 如今已经成为标准,得到了原生的支持,在我们后面的课程中不会涉及jQuery,也不允许在作业中使用。本章内容假定同学们已经完成了前面要求的 JS 相关基础知识的自学。
基础语法
let
ES6 新增了 let 命令用来声明变量,它的用法类似于 var,区别在于它只在 let 声明的代码块内有效,并且 let 在同一作用域内不能重复声明,我们建议在平时的开发中使用 let 替代 var。
function varTest() {
var x = 1
if (x === 1) {
var x = 2 // 两个x是同一个变量
console.log(x)
// 输出:2
}
console.log(x)
// 输出:2
}
function letTest() {
let x = 1
if (x === 1) {
let x = 2 // 两个x是不同的变量
console.log(x)
// 输出:2
}
console.log(x)
// 输出:1
}
另外,在程序和方法的最顶端,var 声明的变量会给全局对象增加属性,但是 let 不会,例如:
var x = 'hello'
let y = 'hello'
console.log(this.x) // "hello"
console.log(this.y) // undefined
上面的 this 取决于执行环境,如在浏览器中执行,指向的是 window 对象,如在 Node.js 中执行,指向的则是 global 对象。
另外需要注意的是,let 在同一块作用域中不允许重复声明,例如:
if (flag) {
let test = 1
let test = 2 // SyntaxError
}
使用大括号 {} 可以用来定义一个块级作用域。
const
const 常量也是块级范围的,这一点与 let 相似,但 const 声明的值是无法被改变的,也不能被重新声明,全局常量也不会变为 window 对象的属性,所以,常量必须在声明的时候就指定它的值。
const number = 123
number = 456 // Uncaught TypeError: Assignment to constant variable
一般我们建议在声明常量的时候全部采用大写字母,例如:
const MY_NUMBER = 123
需要注意的是,如果 const 用来定义数组或对象,那么对于他们子项或者属性的修改是允许的,但是不能够对自身重新赋值,例如:
const MY_ARRAY = [1, 2, 3]
MY_ARRAY.push(4) // 允许
MY_ARRAY = [] // 不允许
const MY_OBJECT = { key: 123 }
MY_OBJECT.key = 456 // 允许
MY_OBJECT = { key: 456 } // 不允许
如果想要冻结对象属性的修改,可以使用 Object.freeze() 来时对象不可变,例如
const MY_OBJECT = { key: 123 }
Object.freeze(MY_OBJECT)
MY_OBJECT.key = 456 // 常规模式下该语句不会起作用,但是也不会报错,严格模式下会报错
练习
通过练习寻找总结 var、let、const 之间的区别。
布尔与关系操作符
关系操作符
| 运算符 | 描述 |
|---|---|
| == | 等于 |
| === | 绝对等于(值和类型) |
| != | 不等于 |
| !== | 绝对不等 |
| > | 大于 |
| < | 小于 |
| <= | 小于等于 |
| >= | 大于等于 |
特殊情况的比较结果
| 表达式 | 结果 |
|---|---|
| null == undefined | true |
| “NaN” == NaN | false |
| 5 == NaN | false |
| NaN == NaN | false |
| NaN != NaN | true |
| false == 0 | true |
| true == 1 | true |
| true == 2 | false |
| undefined == 0 | false |
| null == 0 | false |
| “5” == 5 | true |
布尔操作符
| 运算符 | 描述 |
|---|---|
| && | and |
| || | or |
| ! | not |
练习
在使用这些运算符进行比较的时候,会发生类型转换。他们是如何转换的,请练习总结。
附加:其他的操作符
除了这两种操作符外,还有其他的操作符,例如一元操作符,逗号操作符等等,请自行了解。
强制类型转换
在使用上述两种操作符时,都会进行类型转换,请课后自行了解。
程序控制
if…else
if(a == 1) { console.log('a=1');} else if(a == 2) { console.log('a=2');} else { console.log('a=other');}
switch…case
switch(n) { case 1: { break } case 2: { break } default: { }}
for循环
for(let i = 0; i < 10; i++) { if(i%2==0) { continue; } console.log(i)}
while循环
while(true) { console.log("true");}
练习
猜数字小游戏:
设定一个谜底数字,输入一个四位数的数字,输出一个字符表示是否猜对
- 例如要谜底数字是1234
- 猜测1233,则输出3A1B
- 猜测1234,则输出4A0B
思考:除了for、while还有哪些其他的循环的方法
解构赋值
解构赋值语法是一种 JavaScript 表达式,通过解构赋值,可以将属性、值从对象、数组中取出,赋值给其他变量,以前如果我们想要给变量赋值,只能直接指定变量的值,例如:
let a = 1let b = 2let c = 3
如果我们想要从数组中取出值,需要这么来写:
let array = [1, 2, 3]let a = array[0]let b = array[1]let c = array[2]
如果我们想要从对象中取出属性和值,需要这么来写:
let object = { a: 1, b: 2, c: 3 }let a = object.alet b = object.blet c = object.c
通过上面的例子我们可以看到,书写起来非常的繁琐,不够简洁,现在通过 ES6 的解构赋值语法,我们就可以轻松实现。
解构数组
基本语法如下,左侧的变量名和右侧数组中的元素一一对应
let [a, b, c] = [1, 2, 3]console.log(a) // 1console.log(b) // 2console.log(c) // 3
可以给左边数组中的变量设置默认值,例如
let [a = 1, b = 2] = [5]console.log(a) // 5console.log(b) // 2
可以通过解构直接交换两个变量,在没有解构的时候,我们需要一个中间临时变量
let a = 1let b = 2// 不使用解构来交换let c = aa = bb = c// 使用解构来交换[ (a, b)] = [b, a]console.log(a) // 2console.log(b) // 1
解构数组一个常用的场景是解析函数返回值,例如
function foo() { return [1, 2]}let [a, b] = foo()console.log(a) // 1console.log(b) // 2
可以忽略掉某些值。例如
let [a, , , b] = [1, 2, 3, 4]console.log(a) // 1console.log(b) // 4
剩余模式,将剩余部分的数组赋值给一个变量
let [a, ...b] = [1, 2, 3]console.log(a) // 1console.log(b) // [2, 3]
解构对象
基本语法如下:
let object = { a: 1, b: 2, c: 3 }let { a, b } = objectconsole.log(a) // 1console.log(b) // 2
可以从一个对象中提取变量并赋值给和属性名不同的新变量名
let object = { a: 1, b: 2, c: 3 }let { a: aa, b: bb } = objectconsole.log(aa) // 1console.log(bb) // 2
解构对象也可以指定默认值,例如:
let object = { a: 5 }let { a = 1, b = 2 } = objectconsole.log(a) // 5console.log(b) // 2
解构对象也支持剩余模式,例如
let { a, ...b } = { a: 1, b: 2, c: 3 }console.log(a) // 1console.log(b) // { b: 2, c: 3 }
解构对象的一个典型应用场景是从函数参数对象中提取数据,例如下面的代码,函数接收的参数是一个对象,如果不使用解构,需要专门去读取参数对象中的属性值
function test(user) { console.log(user.id, user.name)}let user = { id: 1, name: 'test',}test(user)
如果我们使用解构对象,接可以直接将属性取出来
function test({ id, name }) { console.log(id, name)}let user = { id: 1, name: 'test',}test(user)
模板字符串
模板字符串是增强版的字符串,用反引号 (`)来标识,它可当作普通字符串来使用,也可以用来定义多行文本,或者通过 ${} 在字符串中嵌入变量或表达式。
let a = `template string` // 普通字符串let name = 'Frank'let b = `Hello ${name}!`console.log(b) // Hello Frank!
模板字符串的另外一大作用就是多行文本定义变得更加方便,对比例子:
let name = 'Frank'let a = `<div> <p>Hello ${name}!</p></div>`let b = '<div>\n <p>Hello ' + name + '!</p>\n</div>'console.log(a === b) // true
字符串操作
字符串处理是我们在编程的时候非常常用的功能,这里介绍一些基本的字符串处理方法,有的是ES6之前就存在的。
substring
该方法返回一个字符串在开始索引到结束索引之间的一个子集,或者从开始索引到字符串末尾的一个子集。
语法
参数
indexStart:需要截取的第一个字符的索引,该索引位置的字符作为返回的字符串的首字母。indexEnd:可选参数,一个0到字符串长度之间的整数,以该数字为索引的字符串不包括在截取的字符串内。
返回值
包括给定字符串的指定部分的新字符串
下面查看一些示例:
let str = '0123456789'console.log(str.substring(0, 3)) // '012'console.log(str.substring(3, 6)) // '345'console.log(str.substring(0, -3)) // 相当于 str.substring(0, 0),输出为空字符串
slice
slice 的作用和 substring 非常类似,不同的是,slice 的参数可以为负数,表示倒数第几个字符
let str = '0123456789'console.log(str.slice(0, 3)) // '012'console.log(str.slice(3, 6)) // '345'console.log(str.slice(0, -3)) // '0123456',表示从第0各字符提取到倒数第三个字符console.log(str.slice(-3, -1)) // '78'
includes
方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。
参数
searchString:要搜索的字符串position:开始搜索的索引位置,默认为0,可选
示例:
let str = '0123456789'console.log(str.includes('123')) // trueconsole.log(str.includes('123', 4)) // false
startsWith
startsWith 方法用来判断当前字符串是否以另外一个给定的子字符串开头,并根据判断结果返回 true 或 false。
参数
searchString:要搜索的字符串position:开始搜索的索引位置,默认为0,可选
示例:
let str = '0123456789'console.log(str.startsWith('0123')) // trueconsole.log(str.startsWith('1234')) // falseconsole.log(str.startsWith('1234', 1)) // true
endsWith
endsWith 与 startsWith 作用类似,用来判断当前字符串是否以另外一个给定的子字符串结尾,endsWith 的第二个参数是可选的 str 长度,示例如下:
let str = '0123456789'console.log(str.endsWith('789')) // trueconsole.log(str.endsWith('456', 7)) // true,相当于判断 '0123456'.endsWith('456)
repeat
该方法返回一个新字符串,表示将原字符串重复 n 次,示例如下:
'abc'.repeat(2) // 'abcabc'
padStart、padEnd
这两个方法提供了字符串补全长度的功能,如果某个字符串不够指定的长度,会在头部或者尾部补全,padStart 用于头部补全,padEnd 用于尾部补全,这个在格式化字符串的时候非常有用,示例如下:
'5'.padStart(5, '0') // '00005''123'.padEnd(5) // '123 ',默认使用空格补全'12345'.padStart(4) // '12345',超出长度,不会变化
trim、trimStart、trimEnd
这三个方法的作用类似,trim 用来消除字符串首尾的空格,trimStart 用来消除字符串头部的空格,trimEnd 用来消除字符串尾部的空格,他们返回的都是新字符串,不会改变原值,示例如下:
let str = ' abc 'str.trim() // 'abc'str.trimStart() // 'abc 'str.trimEnd() // ' abc'
replaceAll
以前js的字符串替换方法 replace() 只会替换第一个匹配,如果想要替换所有的匹配,需要写正则表达式,例如:
'aabbcc'.replace('b', '_') // 'aa_bcc''aabbcc'.replace(/b/g, '_') // 'aa__cc'
写正则增加了复杂度,现在新增的 replaceAll() 方法,可以一次性替换所有匹配
'aabbcc'.replaceAll('b', '_') // 'aa__cc'
split
该方法使用指定的分割字符将一个字符串分割成子字符串数组,以一个指定的分割字符串来决定每个拆分的位置
console.log('Hello JavaScript'.split(' ')) // [ 'Hello', 'JavaScript' ]console.log('Hello'.split('')) // [ 'H', 'e', 'l', 'l', 'o' ]
附加:正则表达式
什么是正则表达式,了解JS正则表达式的用法。
本文概述了ES6中的let、var和const的区别,流程控制、解构赋值、字符串API以及模板字符串的使用。重点介绍了变量声明的新规范,以及如何通过实践理解比较操作符和运算符的行为。
1170

被折叠的 条评论
为什么被折叠?



