前端学习-ES6新特性

1,028 阅读5分钟

let

  • 可以通过新的关键字 let 定义块内部的变量
  • let 定义的变量在块级作用域内部能够被访问

块级作用域

作用域 - 某个成员能够起作用的范围

  • 全局作用域
  • 函数作用域
  • 块级作用域 块,就是 {} 包裹起来的一个范围
// 非常适合设置 在 for 循环中的循环变量
// 通过 let 定义变量,只在自己的循环中生效
for (let i = 0 ; i < 3 ; i++) {
   for (let i = 0; i < 3;i++) {
     console.log(i);
   }
}

// 通过循环批量添加事件
// 通过 let 定义变量,只能在块级内部被调用
var eles = [{}, {}, {}];
for (let i = 0 ; i < eles.length ; i++) {
   eles[i].onclick = function () {
     console.log(i);
   }
}
eles[0].onclick();

// 循环 实际上有两层作用域
for (let i = 0 ; i < 10 ; i++) {
   let i = "foo";
   console.log(i);
}
let i = 0;
if (i < 10) {
   let i = "foo";
   console.log(i);
}
i++;

//和 var 有另外一个区别,let 不会进行变量声明提升
console.log(a);
let a = 2;

const

恒量 / 常量
在 let 的基础上增加了一个【只读】效果

//不能修改值
const name = "zs";
name = "ls";

//声明的时候必须同时赋初值
const name;
name = "zs";

//对象类型可以添加属性
const obj = {};
obj.name = "zs";

最佳实践:不用 var,主用 const,配合 let

数组的解构

//解构对应下标的值
const arr = [100, 200, 300];
const [foo, bar, baz] = arr;
console.log(foo, bar, baz);
// 100 200 300

//只解构需要的下标的值
const arr = [100, 200, 300];
const [, , baz] = arr;
console.log( baz);
//300

//解构当前下标开始到结尾的所有的值
const arr = [100, 200, 300];
const [foo, ...rest] = arr;
console.log(rest);
//[200,300]

//解构的项目小于数组的长度
const arr = [100, 200, 300];
const [foo] = arr;
console.log(foo);
// 100

//解构的项目大于数组的长度
//解构时可以赋予默认值
const arr = [100, 200, 300];
const [foo, bar, baz = 400, more = 123] = arr;
console.log(more);//123
console.log(baz);//300

//实际应用
const path = "foo/bar/baz";
// const temp = path.split("/");
// const a = temp[1];
const [,,a] = path.split("/");
console.log(a);

对象的解构

// 解构时需要根据属性名提取内容
const obj = { name: 'zs', age: 18 };
const { name } = obj;
console.log(name);

//当变量名相同时可在冒号后添加一个新的名称来解决
//同样可以用等号赋予默认值
const name = "tom";
const { name: newName = "jack" } = obj;
console.log(name);//tom
console.log(newName);//zs

模板字符串字面量

//利用``包裹字符串内容
const str = `this is a \`string`;
console.log(str);

//需要在字符串内部添加变量时可以用${}包裹
const name = "tom";
const str = `hey, ${name},${1 + 1},${Math.random()}`;
console.log(str);

模板字符串标签函数

const name = "zs"; 
const gender = true;

//用strings接受纯字符
//strings[0] hi,
//strings[1] is a 
function myTagFunc(strings, name, gender) {

  const sex = gender ? "man" : "woman";
  return strings[0] + name + strings[1] + sex + strings[2];
}

const str = myTagFunc`hi, ${name} is a ${gender}`;
console.log(str);
//hi, zs is a man

字符串的扩展方法

const msg = 'Error: foo is not defined.'
//是否以某个字符串开始
console.log(msg.startsWith('Error'))
//是否以某个字符串结尾
console.log(msg.endsWith('.'))
//是否包含某个字符串
console.log(msg.includes('foo'))

参数默认值

// 函数参数的默认值
function foo(bar,enable = true) {
  // enable = enable || true
  // enable = enable === undefined ? true : enable
  console.log('foo invoked enable:')
  console.log(enable)
}
foo('bar')

剩余参数

// 剩余参数
function fun(n,...args) {
  console.log(args);
  //[2,3,4]
}
fun(1,2,3,4);

展开数组

// 展开数组操作
const arr = ['foo', 'bar', 'baz']
// console.log(arr[0],arr[1],arr[2])
// console.log.apply(console,arr)

console.log(...arr)

箭头函数

//简化函数的语法
const plus = (a, b) => {
   console.log('plus invoked')
   return a + b
}
console.log(plus(1,2))

//实际应用
//返回一个数组中的奇数项
const arr = [1,2,3,4,5,6,7]
// const arr1 = arr.filter(function (item) {
//   return item % 2
// })
const arr1 = arr.filter(i => i % 2)
console.log(arr1)

箭头函数与this

// 箭头函数内部没有this,会在外围查找
const person = {

  name: "tom",
  //获取不到name
  sayHi: () => {
     console.log(`hi,my name is ${this.name}`)
  }
  
  sayHiWait: function () {
    setTimeout(() => {
      //会找到sayHi的this
      console.log(`hi,my name is ${this.name}`)
    },1000);
  }
}
person.sayHi()

对象字面量增强

const bar = "bar"
const age = "age"
const obj = {
  name: "tom",
  // 属性名和变量名相同时可省略变量名
  bar,
  //简化了函数语法
  sayHi () {
    console.log('hi')
    console.log(this)
  },
  // 可动态计算属性名
  [1+2]: 18
}
console.log(obj)

对象扩展方法

Object.assign 方法

将多个源对象中的属性复制到一个目标对象中

const source1 = {
   a: 123,
   b: 123
}
const source2 = {
   b: 678,
   d: 789
}
const target = {
   a:456,
   c:789
}

const result = Object.assign(target,source1,source2);
console.log(target)
//a: 123 b: 678 c: 789 d: 789


// 复制对象
function fun(obj) {
   // 希望内部更改时,不要改外部的对象
   const newObj = Object.assign({},obj)
   newObj.name = 'tom'      
   console.log(newObj)
}
const obj = {
   name: 'jack',
   age: 18
}
fun(obj)
console.log(obj)


// 应用,在 options 对象参数接收时,简化
function Block(options) {
  Object.assign(this,options)
}
const block1 = new Block({width: 100, height: 100, x: 50, y: 50})
console.log(block1)

Object.is 方法

用于处理一些特殊的比较情况

0 == false // true
0 === false // false
+0 === -0 // true
NaN === NaN //false
Object.is(+0,-0) // false
Object.is(NaN,NaN) // true

Class 类

一种新的定义对象的方法

// 以前的写法
// function Person(name, age) {
//   this.name = name;
//   this.age = age;
// }
// Person.prototype.sayHi = function () {
//   console.log(`hi,my name is ${this.name}`)
// }

class Person {
  constructor (name, age) {
    this.name = name;
    this.age = age;
  }
  sayHi () {
    console.log(`hi,my name is ${this.name}`)
  }
}

const p1 = new Person("tom",18)
console.log(p1)
p1.sayHi()

静态方法

也叫类方法,this指向的当前的类

class Person {
  constructor (name, age) {
    this.name = name;
    this.age = age;
  }
  sayHi () {
    console.log(`hi,my name is ${this.name}`)
  } 
  static create (name,age) {
    return new Person(name,age)
  }     
}

//调用类方法直接创建实例对象
const p1 = Person.create("zs",19)
console.log(p1)

Extends

//父类
class Person {
  constructor (name, age) {
    this.name = name;
    this.age = age;
  }
  sayHi () {
    console.log(`hi,my name is ${this.name}`)
  }   
}

//子类
class Student extends Person {
  constructor (name,age,number) {
    //调用父类构造方法
    super(name,age)
    this.number = number
  }
  hello () {
    //调用父类函数
    super.sayHi()
    console.log(`学号是 ${this.number}`)
  }
}
const s1 = new Student("tom",18,101)
s1.hello();

Set 数据结构

这种数据结构内不允许出现重复的值

// 创建数据结构
const s0 = new Set()
s.add(1).add(2).add(3).add(4).add(2)
console.log(s)

//遍历
s.forEach(i => console.log(i))

for (let i of s) {
   console.log(i)
}

//获得集合的长度
console.log(s.size)

//是否存在某个值
console.log(s.has(4))

//删除某个值
console.log(s.delete(100))


//清空集合
s.clear()


//实际应用 数组去重
const arr = [1.3,4,6,2,4,7,5,8]
// const b = Array.from(new Set(arr))
//利用展开操作符返回一个数组
const b = [...new Set(arr)]
console.log(b)

Map 数据结构

可以将任意类型设置为键值

 const map = new Map()
const a = { a: 1}
map.set(a,100)

//获取对应的值
console.log(map.get(a))

// map.has() 是否包含某个数据
// map.delete() 删除
// map.clear() 清空

//遍历
map.forEach((value,key) => {
  console.log(key,value)
})

Symbol

一种全新的原始数据类型
作用就是表示一个独一无二的值

const s = Symbol()
console.log(s)
console.log(typeof s)

//可以添加一个描述文本
console.log(Symbol('foo'))


//将symbol作为属性名时无法被外部访问到
const obj = {
  [Symbol()] : 789,
  name: "zs"
}
obj[Symbol()] = 123
obj[Symbol()] = 456
console.log(obj[Symbol()])
console.log(obj.name)

for方法

需要重复使用一个symbol类型的值可以使用for方法

const a = Symbol.for(true)
const b = Symbol.for('true')
console.log(a === b)

toStringTag

利用symbol的toStringTag常量修改对象转成字符串后的标签

const obj = {
   [Symbol.toStringTag]: "XObject"
}
console.log(obj.toString())

for...of 循环

作为遍历所有数据结构的统一方式

//遍历数组
const arr = [100, 200, 300, 400]
for (const item of arr) {
   console.log(item)
}

//遍历set对象
const s = new Set(["foo", "bar", "baz"])
for (const item of s) {
   console.log(item)
}

//遍历map对象
const m = new Map()
m.set("foo",1)
m.set("bar",2)
for (const [key,value] of m) {
   console.log(key,value)
}

ES2016

数组的includes方法

检测是否包含某个值

const arr = [1,true,NaN,23,'hello']

console.log(arr.indexOf(NaN))//无法查找NaN的位置
console.log(arr.includes(NaN))//返回ture

指数运算符 **

// console.log(Math.pow(2,3))
console.log(2 ** 3)