最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES6 新特性

    正文概述 掘金(小流江河)   2021-02-05   609

    ES6 已经是前端人员必备的知识技能,系统化学习ECMAScript是很有必要的。

    ECMAScript概述

    通常将ECMAScript看作是JavaScript的标准规范,但实际上JavaScript是ECMAScript的扩展语言。ECMAScript只是提供了最基本的语法,JavaScript在语言基础上进行了扩展。 JavaScript语言本身指的就是ECMAScript。 ES6 新特性 ES6 新特性

    ES2015概述

    ES2015开始按照年份开始命名,很多人习惯将ES2015或之后的新版本称之为ES6。实际工作中,注意分辨ES6是特指还是泛指。
    ES2015官网 ES2015主要更新:
    解决原有语法上的一些问题或者缺陷
    对原有语法进行增强
    全新的对象、全新的方法、全新的功能
    全新的数据类型和数据结构

    准备工作

    任何一个支持Es2015的环境都可以: node.js或者最新版本的Chrome浏览器或者在VScode软件中使用Chrome调试。使用VScode的话,需要安装以下插件

    • Debugger for Chrome
    • Live Server
    • Browser Preview

    let 和块级作用域

    • 全局作用域: ES5及之前
    • 函数作用域: ES5及之前
    • 块级作用域:ES2015及之后

    被{}包围的部分被称之为块级作用域。

    // 通过循环批量添加事件
    // 通过 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);
    // var a = 1;
    let a = 2;
    

    const

    在let的基础上增加了一个【只读】的效果,不允许修改,且有块级作用域

    const name = "zs";
    name = "ls";// 会报错,不能修改const类型变量的值
    // 声明的时候必须同时赋初值
    const name ;// 会报错,声明的时候必须同时赋初值
    name = "zs";
    const obj = {};
    obj.name = "zs";// 不会报错,因为没有改变指针,只是给指针指向的地址增加内容
    obj = {};// 会报错,不能更改指针
    

    最佳实践:不用var,主用const,配合let
    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)//  ...表示获取foo之后的值[200, 300]赋给rest
    
    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。超出数组范围,没能从arr获取值,输出默认值123
    console.log(baz)// 输出300。上述算式中,先进行赋值得到默认值400,再进行解构,得到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 //从obj对象解构得到同名属性值,赋给变量name 
    console.log(name)// 输出zs
    
    const name = "tom"
    const { name: newName = "jack" } = obj// 从obj对象解构得到同名属性值,赋给变量newname, 假如没获取到,就只有默认值"jack"
    console.log(name)// 输出tom
    console.log(newName)// 输出jack
    const { log } = console// 将console对象的log方法指针解构赋值给log变量,起到简化代码的作用
    log("haha")// 输出haha
    

    模板字符串

    使用`字符串内容`书写模板字符串

    const str = `this 
    is a \`string`//  模板字符串可以保留中间换行。在输出html字符串时比较方便。
    console.log(str)
    
    const name = "tom"
    const str = `hey, ${name},${1 + 1},${Math.random()}`
    console.log(str)//  ${}插值表达式会将内部的值插入到str字符串中
    

    模板字符串标签函数

    利用标签函数对模板字符串进行二次加工处理,得到我们想要的效果

    // 模板字符串标签函数
    const str = console.log`hello JavaScript`//输出数组['hello JavaScript']
    
    const name = "zs"
    const gender = true
    function myTagFunc(strings, name, gender) {
      // console.log(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)
    

    字符串扩展方法

    • include()是否包含某字符串
    • startsWith()是否包含以某字符串为开头
    • endsWith()是否包含以某字符串为结尾

    参数默认值

    // 函数参数的默认值
    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)//  获得剩余参数组成的数组
    }
    fun(1,2,3,4)// 输出[2,3,4]
    

    展开数组

    ...还可以用来展开数组

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

    箭头函数

    =>可以简化函数的定义过程

    // 原始定义
    function plus(a) {
      return a + 1
    }
    console.log(plus(10))
    // 箭头函数定义
    const plus = a => a + 1
    // 多参数,多行定义
    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)// 输出[1,3,5,7]
    

    箭头函数的this

    // 箭头函数与 this
    const person = {
      name: "tom",
      // sayHi: function () {// 原始方法
      //   console.log(`hi,my name is ${this.name}`)// 输出hi,my name is tom
      // }
      // sayHi: () => {// 箭头函数方法,但是这里的this指的函数外部的this, 是undefined。无法实现我们想要的效果
      //   console.log(`hi,my name is ${this.name}`)// 输出hi,my name is
      // }
      sayHi: function () {
        // const _this = this;//  当有这种情况时,都可以使用箭头函数来替代
        setTimeout(() => {
          console.log(`hi,my name is ${this.name}`)// 输出hi,my name is tom
        },1000);
      }
    }
    person.sayHi()
    

    对象字面量的增强

    // 对象字面量增强
    const bar = "bar"
    const age = "age"
    const obj = {
      name: "tom",
      bar,// 等价bar: bar, 
      sayHi () {
        console.log('hi')
        console.log(this)
      },
      // 计算属性名
      [1+2]: 18,//  表示1+2结果命名的属性3:18
      [age]: 18//  表示以age恒量命名的属性age:18
    }
    // obj[age] = 18
    console.log(obj)
    // obj.sayHi()
    

    对象扩展方法

    Object.assign()

    Object.assign(target, sourceObj1, sourceObj2...)将多个源对象中的属性复制到另一个目标对象中。

    // 对象扩展方法
    // 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)
    console.log(target === result)
    // 复制对象
    // 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) {
      // this.width = options.width;
      Object.assign(this,options)
    }
    const block1 = new Block({width: 100, height: 100, x: 50, y: 50})
    console.log(block1)
    

    Object.is()

    判断对象值是否相等,一般不使用

    // 对象扩展方法
    // Object.is 方法
    console.log(
      // 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 类
    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()
    

    静态方法static

    ES2015中新增添加静态方法的关键字 static

    // 静态方法
    class Person {
      constructor (name, age) {
        this.name = name;
        this.age = age;
      }
      sayHi () {
        console.log(`hi,my name is ${this.name}`)
      } 
      static create (name,age) {// 声明方法是静态方法
        console.log(this)// 静态方法中的this指向Person类
        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)// super对象指向父类Person
        this.number = number
      }
      hello () {
        super.sayHi()
        console.log(`学号是 ${this.number}`)
      }
    }
    const s1 = new Student("tom",18,101)
    s1.hello();
    

    Set 数据结构

    一种新的数据类型,类似于数据,但是内部数据不允许重复。

    // Set 数据结构
    const s = new Set()
    s.add(1).add(2).add(3).add(4).add(2)
    console.log(s)// 输出{1,2,3,4},因为最后添加的2重复了,所以被忽略
    // 遍历方法一
    s.forEach(i => console.log(i))// 遍历s的值赋值给形参i并执行箭头函数
    // 遍历方法二
    for (let i of s) {// 效果同s.forEach(i => console.log(i))
      console.log(i)
    }
    // console.log(s.size)// 获取元素的个数
    // console.log(s.has(4))// 判断元素是否在s中
    // console.log(s.delete(100))// 删除元素
    // console.log(s)
    // s.clear()// 清除所有元素
    // console.log(s)
    // 应用:数组去重
    const arr = [1.3,4,6,2,4,7,5,8]
    // const b = Array.from(new Set(arr))// 数组和Set集合的转换
    const b = [...new Set(arr)]// 利用...展开集合,得到数组
    console.log(b)
    

    Map数据结构

    类似于对象,内部是一一对应的映射关系键值对,但是不受类型限制

    // 原始方法,当对象作为键名会出现问题
    const obj = {}
    obj[true] = "boolean"
    obj[123] = "number"
    obj[{a: 1}] = "object"
    console.log(Object.keys(obj))// 输出['true','123','[object object]'] 所有键名都是字符串类型
    console.log(obj[{}])// 输出"object",不是我们想要的一一对应的效果(只有obj[{a: 1}]的值才是"object")
    console.log(obj['[object Object]'])// 输出"object",不是我们想要的
    // Map 数据结构
    const map = new Map()
    const a = { a: 1}
    map.set(a,100)
    console.log(map)
    console.log(map.get(a))
        
    // map.has()
    // map.delete()
    // map.clear()
    map.forEach((value,key) => {
      console.log(key,value)
    })
    

    Symbol 数据类型

    Symbol(),作用就是表示一个独一无二的值。 很多时候,我们添加的数据可能跟模块的数据冲突(覆盖源数据),而造成意料之外的后果。我们就需要使用Symbol()来制造独一无二的数据,来解决这种覆盖(数据重复)问题。

    // shared.js =============================
    const cache = {}
    // // a.js ==================================
    cache['foo'] = Math.random()
    // // b.js ==================================
    cache['foo'] = 123// 会覆盖源数据
        
    
    // Symbol 符号,作用就是表示一个独一无二的值
    const s = Symbol()
    console.log(s)
    console.log(typeof s)
    console.log(Symbol() === Symbol())// 输出false
    console.log(Symbol('foo'))// 传入参数来标记
    console.log(Symbol('bar'))
    console.log(Symbol('baz'))
        
    const obj = {
      [Symbol()] : 789,// 可以利用Symbol()设置私有属性,使其不被外部访问
      name: "zs"
    }
    obj[Symbol()] = 123// 利用Symbol()添加数据,不会产生覆盖
    obj[Symbol()] = 456
    console.log(obj[Symbol()])//  输出undefined
    console.log(obj.name)
    

    Symbol补充

    // Symbol 补充
        
    console.log(Symbol("foo") === Symbol("foo"))// 输出false, 因为唯一性
    const a = Symbol.for(true)// 会自动转换成字符串'true'
    const b = Symbol.for('true')// 参数相同的for函数标记的Symbol(),表示同一个Symbol()
    console.log(a === b)// 输出true
    const obj = {
    	// 一般对象.toString()都是'[object object]',利用Symbol.toStringTag
        // 可更改对象的toString()标签
      [Symbol.toStringTag]: "XObject"
    }
    console.log(obj.toString())// 输出'[object XObject]'
    const obj = {
      [Symbol()]: "Symbol value",
      foo: "foo value"
    }
    for (var k in obj) {
      console.log(k)
    }// 只输出'foo',而无法得到Symbol()值
    console.log(Object.getOwnPropertySymbols(obj))// 输出[Symbol()]
    // console.log(Object.keys(obj))// 只输出['foo'],而无法得到Symbol()值
    // console.log(JSON.stringify(obj))只输出{"foo": "foo value"},而无法得到Symbol()值
    

    for of 遍历

    const arr = [100, 200, 300, 400]
    for (const item of arr) {
      console.log(item)
    }
    arr.forEach(item => {   //没有办法打断遍历
      console.log(item)
    })
    for (const item of arr) {//没有办法打断遍历
      console.log(item)
      if (item >= 200) {
        break
      }
    }
    const s = new Set(["foo", "bar", "baz"])
    for (const item of s) {
      console.log(item)
    }
    const m = new Map()
    m.set("foo",1)
    m.set("bar",2)
    for (const [key,value] of m) {// 使用数组解构m的键值对数组
      console.log(key,value)
    }
    //const obj = {
    //  name: "zs",
    //  age: 18
    //}
    //for (const item of obj) {// for of 这样遍历对象会报错
    //  console.log(item)
    //}
    

    ES2015其他内容

    • 可迭代接口
    • 迭代器模式
    • 生成器
    • Proxy代理对象
    • Reflect统一的对象操作API
    • Promise异步解决方案
    • ESModules语言层面的模块化标准

    ES2016概述

    相对ES2015只是一个小的版本,只增加了少量内容:数组的includes()方法和指数运算符**。

    // ES2016 新增内容
    const arr = [1,true,NaN,23,'hello']
    // console.log(arr.indexOf(true))// 返回下标1
    // console.log(arr.indexOf(null))// -1
    // console.log(arr.indexOf(NaN))// -1,这不是我们想要的
    // includes 包含
    // console.log(arr.includes(NaN))// true
    // 指数运算符 **
    // console.log(Math.pow(2,3))
    console.log(2 ** 10)// 相当于console.log(Math.pow(2,10))
    

    起源地下载网 » ES6 新特性

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元