ES6常用新特性

这篇具有很好参考价值的文章主要介绍了ES6常用新特性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ES6改动很大,可以简单分为四类
1、解决原有语法的缺陷和不足
例如:let,const
2、对原有语法进行增强
解构、扩展、模板字符串
3、新增对象、全新的方法,全新的功能
Object.assign()、Proxy对象代理、Reflect 等等
4、全新的数据类型和数据结构
set、map、class、迭代器、生成器 等等

一、解决原有语法的缺陷和不足

1、let:块级作用域,没有变量提升

用途:for循环的计数器(for循环内部let声明的变量同样拥有块级作用域);循环事件绑定不必采用闭包形式

for (let i=0; i<3; i++) {
let i = ‘foo’
console.log(i)
}
2、const: 恒量/常量;声明后不能修改内存地址,可修改属性成员

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

二、对原有语法的增强

1、数组的解构:根据数组对应的位置提取对应的值赋给对应的变量

let arr = [1,2,3]
let [x, y, z] = arr
如果未取到对应的值,赋值“undefined”
可以用…运算符

var [x, …other] = arr
可以设置默认值

var [x=‘0’, y, z] = arr
用途:字符串截取

const str = ‘http://www.baidu.com?titile=article’
var [, strParam] = str.split(‘?’)
2、对象的解构:根据属性名提取

const obj = {name: ‘zdd’, age: 18}
const { name, age } = obj
如果想换一个变量名&添加默认值

const {name: objName=‘www’, age} = obj
应用场景:代码简化

const { log } = console
log(‘hh’)
3、模板字符串:字符串增强

1、可换行
2、可使用插值表达式添加变量,变量也可以替换为可执行的js语句:

let str = 生成一个随机数:${ Math.random() }
标签模板字符串,标签相当于一个自定义函数,自定义函数的第一个参数是被差值表达式截取的数组

// 标签模板字符串
const name = 'www';
const isMan = true
const tagFn = function (strings, name, isMan) {
  let sex = isMan ? 'man' : 'woman';
  return strings[0] + name + strings[1] + sex + strings[2]
}
const result = tagFn`hey, ${name} is a ${isMan}.`

4、字符串的扩展方法

1、includes
2、startWith
3、endsWith

5、函数参数增强:参数默认值

只有当参数为不传或传入undefined时使用默认值

const fn = function (x=1, y) {
  console.log(x)
  console.log(y)
}
fn()

6、…操作符:收起剩余数据、展开数组

收取剩余参数:取代arguments,arguments是一个类数组,…操作符是一个数组类型,可以使用数组方法
6.1、仅使用一次
6.2、放在参数最后

const fn = function (x, ...y) {
  console.log(y.slice(0))
}
fn(1,2,3,4,5)

展开数组

const spredArr = [1,2,3,4]
console.log(...spredArr)
console.log.apply(this, spredArr) //es5代替方案

7、箭头函数:简化写法

箭头函数的this指向上级作用域

const name = 'tony'
const person = {
  name: 'tom',
  say: () => console.log(this.name),
  sayHello: function () {
    console.log(this.name)
  },
  sayHi: function () {
    setTimeout(function () {
      console.log(this.name)
    }, 500)
  },
  asyncSay: function () {
    setTimeout(()=>console.log(this.name), 500)
  }
}
person.say()  //tony
person.sayHello() //tom
person.sayHi() //tony
person.asyncSay()  //tom

8、对象字面量的增强

8.1、如果key与value变量名相同,省略:value
8.2、省略函数:function
8.3、计算属性:[Math.random()]

const bar = ‘bar’
const obj = {
bar,
fn () {
console.log(‘1111’)
},
[Math.random()]: ‘123’
}
console.log(obj)

三、新增对象、全新的方法、全新的功能

1、Object.assign():合并多个对象,第一个参数就是最终的返回值,如果对象的属性名相同,后面的覆盖前面的

用途:复制对象,给options属性赋默认值

let objA = {
  a: 'aa',
  b: 'bb'
}
let objB = {
  b: 'dd',
  c: 'ee'
}
let result = Object.assign({}, objA, objB)
result.a = 'cc'
console.log(objA, result) //{a: "aa", b: "bb"} {a: "cc", b: "dd", c: "ee"}

2、Object.is():判断两个值是否相等,返回布尔值

用途:es5中,对于0的判断不区分正负值,-0 == +0返回true,NaN == NaN返回 返回false;
Object.is()规避了这些问题

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

3、Proxy:代理对象

基本用法

const person = {
  name: 'www',
  age: '20'
}
const personProxy = new Proxy(person, {
  get(target, key) {
    return target[key] ? target[key] : 'default'
  },
  set(target, key, value) {
    target[key] = value % 2 ? value : 99
  }
})
console.log(person.xxx) // undefined
console.log(personProxy.xxx) // default
console.log(personProxy.age) //20
personProxy.age = 100
console.log(personProxy) //{name: "www", age: 99}

这里注意的一点是,这里被拦截的是”personProxy“,而不是”person“
与Object.definedProperty()的比较:
1、相比与Object.definedProperty只能监听get,set行为,proxy监听的行为更多一些,has、deleteProperty … 等很多
2、对于数组的push,pop等操作,proxy是监听的整个对象的行为,所以通过set方法能够监听到;而definedProperty需要指定该对象的属性名,对于数组来说,就是指定数组的下标,是监听不到数组的push,pop等操作的

let arr = []
let arrProperty = new Proxy(arr, {
  set (target, key, value) {
    console.log(target, key, value) //[1] "length" 1
    target[key] = value
    return true
  }
})
arrProperty.push(1)
console.log(arrProperty) //[1]

3、proxy以非侵入的方式,监听了对象的读写;definedProperty需要指定具体需要监听对象的属性名,与上面的数组类似,如果想要监听一个含有多个属性的对象的读写行为,definedProperty需要遍历这个对象的所有属性

4、Reflect: 封装操作对象的统一API

在之前的es5中,操作对象有很多种方式

const obj = {
  name: '111',
  age: '22'
}
// 判断对象某个属性是否存在
console.log('name' in obj)
// 删除某个属性
console.log(delete obj['name'])
// 获取对象key
console.log(Object.keys(obj))

对于不同的操作行为,使用的方式却不同,Reflect的目的是使用同一套方式去操作对象

const obj = {
  name: '111',
  age: '22'
}
// 判断对象某个属性是否存在
console.log(Reflect.has(obj,'name'))
// 删除某个属性
console.log(Reflect.deleteProperty(obj, 'name'))
// 获取对象key
console.log(Reflect.ownKeys(obj))

5、用于处理异步,解决回调函数的地狱式嵌套问题

四、全新的数据结构和数据类型

1、class 类

es5写法

function People (name) {
  // 设置实例属性
  this.name = name;
}
// 设置实例的共享方法
People.prototype.sayHi = function () {
  console.log(this.name)
}
let p = new People('tom')
p.sayHi()

使用class更易理解,结构清晰

  class Peopel {
    constructor (name) {
      this.name = name
    }
    say () {
      console.log(this.name)
    }
  }
  const p = new Peopel('tony')
  p.say()

类的继承

  class Peopel {
    constructor (name) {
      this.name = name
    }
    say () {
      console.log(this.name)   //tom,在子类的sayAge中调用
    }
  }
  class Worker extends Peopel {
    constructor (name,age) {
      super(name)
      this.age = age
    }
    sayAge () {
      super.say()
      console.log(this)  // Worker {name: "tom", age: 18}
      console.log(this.age) // 18
    }
  }
  const p = new Worker('tom', 18)
  p.sayAge()

类的继承还是通过原型链的方式实现,具体可以看下babel转换后的代码
super可以作为函数调用,也可以作为对象调用
作为函数调用时,只能在子类的constructor中调用,此时执行父类的构造函数constructor,执行父类构造函数时,this指向的是子类Worker,所以实例p会有name属性(对于super理解的还是不够,后面要单独学习下)

2、set数据结构:可以理解为集合,不重复

  const s = new Set()
  s.add(1).add(2).add(3)
  console.log(s) //{1, 2, 3}
  console.log(s.size) // 3
  const arr = [1,2,3,2,4]
  console.log([... new Set(arr)]) //[1,2,3,4]

3、map数据结构

es5中的对象key只能是字符串,map的key可以是任意数据类型, 可以通过get,set,has等操作map

  const m = new Map()
  const tom = {name: '99'}
  m.set(tom, 90)
  console.log(m.get(tom))
  m.forEach((value, key) => {
    console.log(value, key)
  })

4、Symbol新的数据结构,唯一值

用途:防止全局对象中,某个属性名重名,产生冲突;定义私有属性,外部访问不到,且遍历不到

  const s = Symbol('描述')
  console.log(s)  
  const obj = {
    [Symbol('私有属性')]: '11'
  }
  console.log(obj)   //obj对象Symbol('私有属性')这个属性外部访问不到
  console.log(Object.keys(obj)) //[]
  console.log(Object.getOwnPropertySymbols(obj)) //[Symbol(私有属性)]

  const s1 = Symbol.for('111')
  const s2 = Symbol.for('111')
  console.log(s1 === s2) //true

5、for … of 遍历

es5中,使用for … in 遍历键值对结构数据,使用forEach遍历数组
es6中新增了set,map数据结构,for…of是用来统一遍历拥有某一种特性的数据结构(可迭代)

  const arr = [1,2,3] 
  for (const item of arr) {
    // 遍历数组
    console.log(item)
  }
  const s = new Set()
  s.add(1).add(2).add(3)
  for (const item of s) {
    // 遍历set结构
    console.log(item)
  }
  const m = new Map([
    ['name','昵称'],
    ['title', '标题']
  ])
  for (const [key, value] of m) {
    // 遍历map结构
    console.log(key)
    console.log(value)
    console.log(m.get(key))
  }

  const newSet = new Set([
    ['name','昵称'],
    ['title', '标题']
  ])
  const newMap = new Map(newSet)
  for (const [key, val] of newMap) {
    // 遍历set初始化后的map结构
    console.log(key)
    console.log(val)
  }

  const obj = {
    name: 'ttt',
    age: '19'
  }
  for (const [key, val] of obj) {
    // 遍历对象报错 Uncaught TypeError: obj is not iterable
    console.log(key, val)
  }

上面代码中,for…of可以遍历数组,set, map,但是却不能遍历对象,是因为对象没有可迭代接口

6、可迭代接口

在浏览器中打印一个数组,在数组的原型对象上有一个Symbol内置属性Symbol.iterator方法,该方法会返回一个iterator对象,该对象包含一个next()方法,调用iterator.next()会返回一个迭代器结果对象iterationResult,iterationResult对象包含两个值,value为遍历的item,done为当前数据是否遍历完成

  const iterator = arr[Symbol.iterator]()
  console.log(iterator) // Array Iterator {}
  const ite = iterator.next()
  console.log(ite) //{value: 1, done: false} value为迭代器的值,done标识是否遍历完

由于上面代码中obj对象不没有Symbol.iterator的内置方法,所以它不是一个可迭代对象,当使用for…of遍历时就报错了,下面手动实现obj可迭代

  let iteratorObj = {
    //iteratorObj是可迭代对象 iterable
    name: 'ttww',
    age: '18',
    [Symbol.iterator] () {
      let index = 0;
      let arr = []
      for (const key in iteratorObj) {
        arr.push([key, iteratorObj[key]])
      }
      return {
      //返回的对象叫iterator
        next () {
          return {
            //结果对象iterationResult
            value: arr[index],
            done: index++ >= arr.length
          }
        },
      }
    }
  }
  for (const [key, val] of iteratorObj) {
    console.log(key, val)
  }

上面代码中,iteratorObj有了可迭代接口,认为是可迭代对象iterable;Symbol.iterator方法返回的对象是迭代器对象iterator;迭代器对象next方法返回的对象是迭代器结果对象iterationResult

6、生成器 generator

用途:处理异步调用回调嵌套的问题

  function *geFn () {
    console.log('111')
    yield 100
    console.log('222')
    yield 200
    console.log('333')
    yield 300
  }
  let generator = geFn()
 
  console.log(generator.next())  //111 {value: 100, done: false}
  console.log(generator.next())  //222 {value: 200, done: false}
  console.log(generator.next())  //333 {value: 300, done: false}

在函数名前面加一个"*",函数就变为生成器函数,执行该函数时,里面的函数不会立即执行,而是会返回一个生成器对象,调用生成器对象的.next方法函数开始执行,当遇到”yield“关键字,函数会停止执行,并把yield的值当做next方法返回对象的value; 当下次调用next方法时,函数从当前位置开始继续执行
生成器函数执行后返回的生成器对象generator,内部也是实现了迭代器接口,所以可以使用for…of来遍历

  function *geFn () {
    console.log('111')
    yield 100
    console.log('222')
    yield 200
    console.log('333')
    yield 300
  }
  let generator = geFn()

  for (const item of generator) {
    console.log(item)
  }

可以使用生成器函数改写上面对象的迭代器方法

  let iteratorObj = {
    name: 'ttww',
    age: '18',
    [Symbol.iterator]:function *() {
      let index = 0;
      let arr = []
      for (const key in iteratorObj) {
        arr.push([key, iteratorObj[key]])
      }
      // for (let i =0; i<arr.length; i++) {
      //   console.log(arr[i])
      //   yield arr[i]
      // }
     
      for (const item of arr) {
        yield item
      }
      // arr = ['b',3,4,5]
      // return {
      //   next () {
      //     return {
      //       value: arr[index],
      //       done: index++ >= arr.length
      //     }
      //   },
      // }
    }
  }
  for (const [key, val] of iteratorObj) {
    console.log(key, val)
  }

这里有一个注意的点就是在循环arr数组时,不能是有forEach遍历,是因为forEach里需要传一个回调函数,这个函数不是生成器函数,在非生成器函数里使用yield关键字会报错

ES2016

1、数组新增方法:includes

  const arr = [1,2,3]
  console.log(arr.includes(2))  //true

2、指数运算符

console.log(2 ** 10) //1024
ES2017

1、Object.values(),以数组的形式,返回对象所有的值

  let obj = {
    title: 'wwwww',
    age: 199
  }
  console.log(Object.values(obj)) //["wwwww", 199]

2、Object.entries(),以数组的形式,返回对象的所有键值对

let obj = {
title: ‘wwwww’,
age: 199
}
console.log(Object.entries(obj)) //[[“title”, “wwwww”],[“age”, 199]]
可以将对象转为map数据结构

  let obj = {
    title: 'wwwww',
    age: 199
  }
 
  let m = new Map(Object.entries(obj))
  console.log(m) //{"title" => "wwwww", "age" => 199}

3、Object.getOwnPropertyDescriptor()
获取一个对象的完整描述信息,可用于将一个对象的get,set属性赋值给另一个对象

  let obj = {
    firstName: 'abc',
    lastName: '123',
    get fullName () {
      return this.firstName + this.lastName
    }
  }
  console.log(obj.fullName) //abc123
  const p2 = Object.assign({}, obj)
  // 此时赋值给p2的仅仅是fullName属性的值,并没有fullName属性的getter
  p2.firstName = '456'
  console.log(p2.fullName)  //abc123

  const description = Object.getOwnPropertyDescriptors(obj)
  console.log(description)
  const p3 = Object.defineProperties({}, description);
  p3.firstName = '789'
  console.log(p3.fullName)  //789123

4、字符串的padEnd()、padStart()方法
5、async/await文章来源地址https://www.toymoban.com/news/detail-696598.html

到了这里,关于ES6常用新特性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ES6 特性

    1.1.1 什么是 ES ES 全称 EcmaScript 是脚本语言的规范 JavaScript 是 EcmaScript 的一种实现 ES 新特性就是指 JavaScript 的新特性 1.1.2 为什么要使用 ES 语法简单,功能丰富 框架开发应用 前端开发职位要求 1.1.3 为什么要学习 ES6 ES6 的版本变动最多,具有里程碑的意义 ES6 加入许多新的语法

    2024年02月07日
    浏览(34)
  • ES6新特性

    1、初识ES6 ECMAScript 6.0(简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言;   ECMAScript是JavaScript的规范,而JavaScript是ECMAScript的实现;   ES6是一个历史名词,泛指 5.1 版本后

    2024年02月07日
    浏览(28)
  • 【ES6 新特性】

    ES6 为字符串扩展了几个新的 API: includes() :返回布尔值,表示是否找到了参数字符串。 startsWith() :返回布尔值,表示参数字符串是否在原字符串的头部。 endsWith() :返回布尔值,表示参数字符串是否在原字符串的尾部。 模板字符串相当于加强版的字符串,用反引号 `,除了

    2024年02月11日
    浏览(32)
  • ES6的重要特性

    1. 块级作⽤域:引⼊ let 和 const ,允许在块级作⽤域中声明变量,解决了变量提升和作⽤域污染的问题。 2. 箭头函数:使⽤箭头( = )定义函数,简化了函数的书写,并且⾃动绑定了 this 。 3. 模板字符串:使⽤反引号(`)包裹字符串,可以在字符串中使⽤变量和表达式

    2024年02月19日
    浏览(35)
  • ES6及以上新特性

    ES6(ECMAScript 2015)及以上版本引入了许多新特性,每个版本都有不同的增强和改进。以下是 ES6 及以上版本的新特性的详细描述: ES6(ECMAScript 2015): let 和 const 声明:引入块级作用域的变量声明,用于替代 var 声明,解决了变量提升的问题。 箭头函数:用 “=” 符号定义函

    2024年02月14日
    浏览(29)
  • ES新特性系列(一)—— ES的简介与ES6

          前几天在BOSS上了解现在的前端工作的情况和各个公司要求的技术栈情况,看到一条非常有意思的要求:“能够理解并使用ES6、ES7、ES8、ES9、ES10新特性,都2024年了你总不能只知道ES6吧?”       各位彦祖现在现在就回忆一下,自己是否能把上述的ES系列的常用新特性都

    2024年04月29日
    浏览(20)
  • 【ES6】—【新特性】—Symbol详情

    定义:独一无二的字符串 PS: Symbol 声明的值是独一无二的 PS: 无论Symbol.for()在哪里声明,都属于全局环境声明 当一个对象的key值有重复时,后面的值会覆盖前面的值 PS: 使用Symbol的独一无二的特性来解决

    2024年02月10日
    浏览(37)
  • ES6 新特性(详细复习笔记)--下

    应用实例-声明对象简写 1. 需求: 演示声明对象简写 代码演示 2-需求: 演示对象方法简写 3-应用实例-对象拓展运算符 需求: 演示对象拓展运算符使用 拷贝对象(深拷贝)的用法和理解 对象拓展运算符是比较新的特性,低版本的浏览器不支持 火狐/谷歌浏览器没有问题 基本介绍

    2024年02月15日
    浏览(36)
  • es6有哪些新特性?用法和案例

    目录 箭头函数 模板字符串  解构赋值 Promise  async/await 箭头函数使用 = 符号定义,可以更简洁地书写函数并且自动绑定 this 。比如: 箭头函数通常用在回调函数中,例如: 模板字符串是一种新的字符串格式,可以包含变量、表达式和换行符。通过使用占位符 ${} 可以插入变

    2024年02月06日
    浏览(30)
  • JavaScript ES6实现继承

    1 对象的方法补充 2 原型继承关系图 3 class方式定义类 4 extends实现继承 5 extends实现继承 6 多态概念的理 function 创建的名称如果开头是大写的,那这个创建的不是函数,是创建了类。 可以把class创建的类当做是function创建的类的一种语法糖。但是在直接使用的方面是有不同之处

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包