一:let与块级作用域

在ES2015之前只有两中作用域
全局作用域
函数作用域
在ES2015中新增了一个块级作用域
块级作用域:定义在{}中,if 和 for中的{}都属于块级作用域

  1. // 例1:
  2. if (true) {
  3. var a = 123
  4. }
  5. console.log(a) // 123
  6. if (true) {
  7. let a = 123
  8. }
  9. console.log(a) // a is not defined
  10. // 例2:
  11. for (var i = 0; i < 3; i++) {
  12. for (var i = 0; i < 3; i++) {
  13. console.log(i)
  14. }
  15. }
  16. // 输出:012
  17. for (let i = 0; i < 3; i++) {
  18. for (let i = 0; i < 3; i++) {
  19. console.log(i)
  20. }
  21. }
  22. // 输出:012 012 012

以上都是定义块级作用域的方法,使用let关键字来定义块级作用域,因为在ES2015之前没有块级作用域的说法,所以使用var在{}定义的变量并不属于块级作用域

二:const

const是一个常量/衡量,一旦声明不可修改
注意:const声明的常量只是不能重新去指向新的内存地址,并不是不能修改常量中的属性成员

  1. const a = '123'
  2. a = '456'
  3. // Assignment to constant variable
  4. // 注意:
  5. const obj = {'name': 'jack'}
  6. console.log(obj.name) // jack
  7. obj.name = 'tom'
  8. console.log(obj.name) // tom

最佳实践:不用var,主用const,配合let
这样定义的的话能搞提高代码的质量

三:数组的解构

从数组或对象中获取指定元素的快捷方式

1、数组的解构

  1. const arr = [100, 200, 300]
  2. // 传统的做法
  3. const foo = arr[0]
  4. const bar = arr[1]
  5. const baz = arr[2]
  6. console.log(foo) // 100
  7. // 解构的做法
  8. const [foo, bar, baz] = arr
  9. console.log(foo) // 100
  10. // 如果只想定义一个值,长度必须跟数组长度一致
  11. const [, , baz] = arr
  12. console.log(baz) // 300
  13. // 如果只想取从当前位置开始之后的所有成员
  14. const [foo, ...rest] = arr
  15. console.log(rest) // [200, 300]
  16. // 注意:这种用法只能在解构成员的最后一个位置上使用
  17. // 如果解构位置的长度小于解构的数组,会默认从第一个位置提取
  18. const [foo] = arr
  19. console.log(foo) // 100
  20. // 如果解构位置的的长度大于解构的数组,则返回undefined
  21. const [foo, bar, baz, more] = arr
  22. console.log(more) // undefined
  23. // 设置默认值
  24. const [foo, bar, baz, more = "default value"] = arr
  25. console.log(more) // default value

四:对象的解构

基本上和数组的解构方式差不多

  1. const obj = { name: 'jack', age: '23' }
  2. // 例1:
  3. const { name } = obj
  4. console.log(name) // jack
  5. 注意:如果变量名和对象中的属性名冲突的话会报错
  6. const name = 'tom'
  7. const { name } = obj
  8. console.log(name) // Identifier 'name' has already been declared
  9. 所以我们可以更改属性名来成功输出
  10. const name = 'tom'
  11. const { name: nameObj } = obj
  12. console.log(nameObj) // jack
  13. 我们还可以设置默认属性
  14. const { sex = '男' } = obj
  15. console.log(sex) // 男

五:模版字符串

  1. // 传统的做法
  2. const str = 'hello es2015, this is a string'
  3. console.log(str) // hello es2015, this is a string
  4. // 新的写法
  5. const str = `hello es2015, this is a string`
  6. console.log(str) // hello es2015, this is a string
  7. // 好处:
  8. // 传统的做法需要在字符串中换行的话必须加上\n进行换行
  9. // 而新的做法直接换行就行了
  10. const str = `hello es2015,
  11. this is a string`
  12. console.log(str)
  13. // hello es2015,
  14. // this is a string
  15. // 如果需要在字符串中加入单引号或新双引号
  16. const str = `hello es2015, this is a \'string\'`
  17. console.log(str) // hello es2015, this is a 'string'
  18. // 支持插值表达式的形式
  19. const name = 'es2015'
  20. const str = `hello ${name}, this is a string`
  21. console.log(str) // hello es2015, this is a string
  22. // 还可以支持js的表达式
  23. const str = `hello es2015, this is a string, ${ 1 + 2}, ${ Math.random() }`
  24. console.log(str) // hello es2015, this is a string, 3, 随机值

六:带标签的模版字符串

  1. const str = console.log`hello world` // ['hello', 'world']
  2. // 还可以加变量或者表达式例:
  3. const name = `jack`
  4. const age = `23`
  5. result`hello ${name}, this is a ${age}`
  6. function result(string, name, age) {
  7. console.log(string, name, age) // ['hello', ', this is a', ''] jack 23
  8. }
  9. // 这种方式其实是以变量或者表达式的方式进行分割

七:字符串的扩展方法:

  1. // 其中最常用的包括
  2. // 1、includes: 字符串当中是否包含某些字段,返回true or false
  3. // 2、startsWith: 是否以某个字段开头,返回true or false
  4. // 3、endsWith: 是否以某个字段结尾,返回true or false
  5. // 例:
  6. const str = `hello world`
  7. console.log(str.includes(`o`)) // true
  8. console.log(str.startsWith(`h`)) // true
  9. console.log(str.endsWith(`d`)) // true

八:参数默认值

  1. // 在函数参数没有传值的情况下,默认undefined
  2. // 传统的做法:
  3. function foo (parmas) {
  4. parmas = parmas === undefined ? '123' : parmas
  5. console.log(parmas) // 123
  6. }
  7. foo()
  8. // 新的做法:
  9. function foo (parmas = 123) {
  10. console.log(parmas) // 123
  11. }
  12. foo()
  13. 注意:如果有多个参数的话,设置参数默认值一定要放到参数列表的最后
  14. 例:
  15. // 错误写法
  16. function foo (parmas = 123, parmas2) {
  17. console.log(parmas) // 123
  18. }
  19. foo()
  20. // 正确写法
  21. function foo (parmas2, parmas = 123) {
  22. console.log(parmas) // 123
  23. }
  24. foo()

九:剩余参数

  1. // 在参数数量不确定的情况下
  2. // 传统做法通过arguments获取到参数
  3. // 例:
  4. function foo () {
  5. console.log(arguments) // {'0': 1, '1': 2, '2': 3}
  6. }
  7. foo(1,2,3)
  8. // 新的做法:
  9. function foo (...args) {
  10. console.log(args) // [1, 2, 3]
  11. }
  12. foo(1,2,3)
  13. 注意:...args只能出现在参数的最后位置
  14. function foo (first, ...args) {
  15. console.log(args) // [2, 3]
  16. }
  17. foo(1,2,3)

十:展开数组

使用…的方式展开数组

  1. const arr = ['bar', 'bat', 'jack']
  2. console.log(...arr) // bar bat jack
  3. 把数组中的每一项传递给console.log 打印出来

十一:箭头函数

  1. // 比如筛选出一个数组中的奇数
  2. const arr = [1, 2, ,3, 4, 5]
  3. console.log(arr.filter(i => i % 2)) // [1, 3, 5]
  4. // 上面箭头函数使用普通函数筛选
  5. console.log(arr.filter(function(i) {
  6. return i % 2
  7. })) // [1, 3, 5]
  8. // 箭头函数中的this指向
  9. const obj = {
  10. name: 'jack',
  11. sayHi: function () {
  12. console.log(this.name) // jack
  13. }
  14. }
  15. obj.sayHi()
  16. // 因为sayHi这个方法是obj去调用的,所以this指向obj这个对象
  17. const obj = {
  18. name: 'jack',
  19. sayHi: () => {
  20. console.log(this.name) // undefined
  21. }
  22. }
  23. obj.sayHi()
  24. // 因为箭头函数中没有this的概念,所以箭头函数中的this指向window

十二:Proxy代理对象

用来监听某个对象中的数据读写

  1. const person = {
  2. name: 'jack',
  3. age: 23
  4. }
  5. const personProxy = new Proxy(person, { // person目标对象
  6. get(target, property) { // target目标对象,property属性名
  7. console(target, property) // { name: 'jack', age: 23 } name
  8. },
  9. // get方法读取目标
  10. set(target, property, value) {
  11. console.log(target, property, value) // target目标对象,property属性名, value要写入的值
  12. }
  13. // set方法写入目标
  14. })
  15. console.log(personProxy.name)

十三:生成器

生成器函数会自动帮我们返回一个生成器对象,调用这个对象的next()方法这个生成器函数就开始执行,在执行的过程中一旦遇到yield关键词,执行就会被暂停下来。而且yield的值将会作为next的结果返回,如果再调用next方法,这个函数将会从暂停的位置继续执行,直到全部结束

  1. function * foo() { // 定义生成器函数
  2. console.log(1)
  3. yield 100 // 遇到yield暂停执行, 直到执行下一次next方法
  4. console.log(2)
  5. yield 101
  6. console.log(3)
  7. yield 102
  8. }
  9. const generator = foo() // console.log(foo()) 返回[Generator] {}
  10. console.log(generator.next()) // 1 { value: 100, done: false }
  11. console.log(generator.next()) // 2 { value: 101, done: false }
  12. console.log(generator.next()) // 3 { value: 102, done: false }
  13. 最大的特点:惰性执行,就是说你给它一个命令它就执行一次