ES6 + 语法新特性(超详细)

1.let 命令

let 用来申明变量, 但与传统的var有所不同

  • 变量不能重复申明
let star='罗志祥';
let star='小猪'  //error
  • let 有块级作用域
{
    let girl='周扬青'
}
console.log(girl) //error
  • 不存在变量提前
console.log(song)   //error
let song='恋爱达人'
  • 不影响作用域链
let school='abc'
function fn(){
    console.log(school) //abc
}

在双层for循环中 , 及时计数器相同,也能互不影响


let arr = [1,2,3]

for(let i = 0;i < arr.length; i++){
    for(let i = 0;i < arr.length; i++){
        console.log(i)
        //打印9 次 , 一次为012012012
    }
}

2.const

const 一般用于申明常量

  • 一定要赋初始值
  • 一般常量使用大写(潜规则)
  • 也具有块级作用域(与let一样)
  • 常量的值不能修改
const a = 1
a = 2 //error

但是可以修改原有属性中的属性值

const obj = {
  name: '张三',
  car: {
    pace: '100W',
    name: '奥迪rs7',
  },
}

obj.name = '李四' 

2.解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

  • 数组的解构
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝']
let [a, b, c, d] = F4
console.log(a) //小沈阳
console.log(b) //刘能
console.log(c) //赵四
console.log(d)  //宋小宝
  • 对象的解构
const F4 = {
  name: '赵本山',
  age: '不详',
  xiaopin: function () {
    console.log('我可以演小品')
  },
}
let { name, age, xiaopin } = F4
console.log(name) //赵本山
console.log(age) //不详
console.log(xiaopin) //[Function: xiaopin]

3.模板字符串

  • 采用 `` 的形式定义字符串
    申明
let str = `我也是一个字符串`
console.log(str, typeof str) //我也是一个字符串 string

内容中可以直接出现换行符

let str = `<ul>
            <li>冉海锋</li>
            <li>冉海锋</li>
           </ul>`;

变量拼接

let lovest = '冉海锋';
let out = `${lovest}是最帅的`;
console.log(out)  //冉海锋是最帅的

4.对象的简化写法

  • ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的书写更加简洁
let name = 'aaa'
let change = function () {
  console.log('aaa')
}

const school = {
  name,
  change,
  improve() {
    console.log('bbb')
  },
}
console.log(school)
/**
 * {
    name: 'aaa',
    change: [Function: change],
    improve: [Function: improve]
  }
 */
  1. 箭头函数
  • ES6允许使用箭头(=>)定义函数
    箭头函数中不会创建自己的this,始终指向上一层作用域
function A() {
  console.log(this.name)
}

let B = () => {
  console.log(this.name)
}

name = '拉钩教育'
const school = {
  name: 'lagou',
}

//直接调用
A() //拉钩教育
B() //undefined
  • 不能作为构造实例化对象
let A = (name, age) => {
  this.name = name
  this.age = age
}
let me = new A('xiao', 123) //error
  • 不能使用arguments变量
let fn = () => {
  console.log(arguments)
}
fn(1, 2, 3) //error

省略小括号,当形参有且只有一个的时候

let add = n => {
    return n + 1;
}

省略花括号,当代码体只有一条语句的时候,此时return也必须省略

let add = n => n+1;

6.函数参数默认值

  • 可以给形参赋初始值,一般位置要靠后(潜规则)
function add(a,b,c=12){
    return a+b+c; 
}
let result = add (1,2);
console.log(result) // 15

与解构赋值结合

function A({host='127.0.0.1',username,password,port}){
    console.log(host+username+password+port)
}
A({
    username:'ran',
    password:'123456',
    port:3306
})

7.rest参数

let fn = (...args) => {
  console.log(args) // [ 1, 2, 3 ]
}

fn(1, 2, 3)

rest参数 一般放在最后


let fn = (a, ...args) => {
  console.log(a) //1
  console.log(args) // [  2, 3 ]
}

fn(1, 2, 3)

如果不是放在最后则会报错

let fn = (...args,a) => { //error
  console.log(a) 
  console.log(args)
}
fn(1, 2, 3)

可以对rest 参数重新赋值

let fn = (...args) => {
  args = 1
  console.log(args) //1
}
fn(1, 2, 3)

8.扩展运算符

  • 扩展运算符与rest参数一样 都是用...表示
    扩展运算符是能将数组展开
let arr = [1, 2, 3]
console.log(...arr) //1 2 3

数组的合并

const A = ['aa','bb'];
const B = ['cc','dd'];
const C = [...A,...B];
console.log(C)   //[aa,bb,cc,dd]

数组的克隆

const A = ['a','b','c'];
const B = [...A];
console.log(B)   //[a,b,c]

将伪数组转换为真正的数组

const A = documents.querySelectorAll('div');
const B = [...A];
console.log(B) // [div,div,div]

扩展运算符,也可以用来展开对象和字符串等, 方法与数组类似
值得注意的是, 扩展运算符在拷贝对象时为部分只有第一层是深拷贝其他层级为浅拷贝

let person = {
  name: '张三',
  age: 18,
  car: {
    name: '奥迪RS7',
  },
}

let person2 = { ...person }

person.name = '李四'
console.log(person) //{ name: '李四', age: 18, car: { name: '奥迪RS7' } }
console.log(person2) // { name: '张三', age: 18, car: { name: '奥迪RS7' } }

person.car.name = 'AMG c63'
console.log(person) //{ name: '李四', age: 18, car: { name: 'AMG c63' } }
console.log(person2) // { name: '李四', age: 18, car: { name: 'AMG c63' } }

9. Symbol

ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol特点:

  • Symbol的值是唯一的,用来解决命名冲突的问题
  • Symbol值不能与其他数据进行运算
  • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys或来获取对象的所有键名,或者通过Object.getOwnPropertySymbols来获取所有Symbol键名
    创建
let s = Symbol('aa');
let s2= Symbol('aa');
console.log(s===s2)   //false

let s3 = Symbol.for('bb');
let s4 = Symbol.for('bb');
comsole.log(s3===s4) ///true

不能与其他数据进行运算

let result = s + 100  //error
let result = s > 100  //error
let result = s + s  //error

Symbol内置值

class Person {
    static [Symbol.hasInstance](param){
        console.log(param);
        console.log("我被用来检测了");
        return false;
    }
}
let o = {};
console.log(o instanceof Person); //我被用来检测了,false

给对象添加方法方式一:


let game = {
  name: 'ran',
}
let methods = {
  up: Symbol(),
  down: Symbol(),
}
game[methods.up] = function () {
  console.log('aaa')
}
game[methods.down] = function () {
  console.log('bbb')
}
console.log(game) // name: 'ran',Symbol(),Symbol()

给对象添加方法方式二

let youxi = {
  name: '狼人杀',
  [Symbol('say')]: function () {
    console.log('阿萨德')
  },
}
console.log(youxi) // name:'狼人杀',Symbol(say)

10.迭代器

  • 迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
  • 原理:创建一个指针对象,指向数据结构的起始位置,第一次调用==next()==方法,指针自动指向数据结构第一个成员,接下来不断调用next(),指针一直往后移动,直到指向最后一个成员,没调用next()返回一个包含value和done属性的对象
const arr = ['AA', 'BB', 'CC', 'DD']
let iterator = arr[Symbol.iterator]()
console.log(iterator.next()) //{{value:'AA',done:false}}
console.log(iterator.next()) //{{value:'BB',done:false}}
const banji = {
  name: '终极一班',
  stus: ['aa', 'bb', 'cc', 'dd'],
  [Symbol.iterator]() {
    let index = 0
    let _this = this
    return {
      next: () => {
        if (index < this.stus.length) {
          const result = { value: _this.stus[index], done: false }
          //下标自增
          index++
          //返回结果
          return result
        } else {
          return { value: undefined, done: true }
        }
      },
    }
  },
}
for (let v of banji) {
  console.log(v) // aa bb cc dd
}

11.生成器

  • 生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同,是一种特殊的函数
function* gen() {
  //函数名和function中间有一个 *
  yield '耳朵' //yield是函数代码的分隔符
  yield '尾巴'
  yield '真奇怪'
}
let iterator = gen()
console.log(iterator.next())
//{value:'耳朵',done:false} next()执行第一段,并且返回yield后面的值
console.log(iterator.next()) //{value:'尾巴',done:false}
console.log(iterator.next()) //{value:'真奇怪',done:false}

生成器函数的参数传递

function* gen(args) {
  console.log(args)
  let one = yield 111
  console.log(one)
  let two = yield 222
  console.log(two)
  let three = yield 333
  console.log(three)
}

let iterator = gen('AAA')
console.log(iterator.next()) //AAA  { value: 111, done: false }
console.log(iterator.next('BBB')) //BBB  { value: 111, done: false }
console.log(iterator.next('CCC')) //ccc  { value: 111, done: false }
console.log(iterator.next('DDD')) //DDD  { value: undefined, done: true }

用生成器函数的方式解决回调地狱问题

function one() {
  setTimeout(() => {
    console.log('111')
    iterator.next()
  }, 1000)
}
function two() {
  setTimeout(() => {
    console.log('222')
    iterator.next()
  }, 2000)
}
function three() {
  setTimeout(() => {
    console.log('333')
    iterator.next()
  }, 3000)
}

function* gen() {
  yield one()
  yield two()
  yield three()
}

let iterator = gen()
iterator.next() // 111 222 333

模拟异步获取数据

function one() {
  setTimeout(() => {
    let data = '用户数据'
    iterator.next(data)
  }, 1000)
}
function two() {
  setTimeout(() => {
    let data = '订单数据'
    iterator.next(data)
  }, 2000)
}
function three() {
  setTimeout(() => {
    let data = '商品数据'
    iterator.next(data)
  }, 3000)
}

function* gen() {
  let users = yield one()
  console.log(users)
  let orders = yield two()
  console.log(orders)
  let goods = yield three()
  console.log(goods)
}

let iterator = gen()
iterator.next() // 用户数据 订单数据 商品数据

12.Promise

成功回调

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    let data = '数据库数据'
    // resolve(data);
    reject(data)
  })
})

p.then(
  function (value) {
    //成功则执行第一个回调函数,失败则执行第二个
    console.log(value) //数据库数据
  },
  function (reason) {
    console.error(reason)
  }
)

失败回调

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    let data = '数据库数据'
    resolve(data)
    // reject(data)
  })
})

p.then(
  function (value) {
    //成功则执行第一个回调函数,失败则执行第二个
    console.log(value)
  },
  function (reason) {
    console.error(reason) //数据库数据
  }
)

使用promise封装ajax请求

function ajax (data) {
  return new Promise((resolve, rejects) => {
    // 创建一个XMLHttpRequest对象去发送一个请求
    const xhr = new XMLHttpRequest()
    // 判断请求类型,请求的地址就是参数传递的url
    if(data.methods==="post"){
       xhr.open(data.methods, data.url, true);
          xhr.send(JSON.stringify(data.param));
       }else{
          xhr.open(data.methods, data.url, true);
          xhr.send();
       }
     }
    // 设置返回的类型是json,是HTML5的新特性
    // 我们在请求之后拿到的是json对象,而不是字符串
    xhr.responseType = 'json'
    // html5中提供的新事件,请求完成之后(readyState为4)才会执行
    xhr.onload = () => {
      if(this.status === 200) {
        // 请求成功将请求结果返回
        resolve(this.response)
      } else {
        // 请求失败,创建一个错误对象,返回错误文本
        rejects(new Error(this.statusText))
      }
    }
    // 开始执行异步请求
    xhr.send()
  })
}

//发送请求
let data = {
  url: '', //请求地址
  methods: 'post',
  param: formData,
}
let p = ajax(data)
p.then(
  (res) => {
    //请求成功
    res.data.forEach((val, index) => {
      cent.innerHTML += `<span id='' class='zxz-portry_content_span'>${val}</span>`
    })
  },
  (reason) => {
    //请求失败
    alert(reason.msg)
  }
)

13.Set集合

ES6提供了新的数据结构set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用「扩展运算符』和「 for…of…』进行遍历,集合的属性和方法:

  • size返回集合的元素个数
  • add增加一个新元素,返回当前集合
  • delete删除元素,返回boolean值has检测集合中是否包含某个元素,返回boolean值

let s = new Set()
let s2 = new Set(['A', 'B', 'C', 'D'])

//元素个数
console.log(s2.size) //4

//添加新的元素
s2.add('E')

//删除元素
s2.delete('A')

//检测
console.log(s2.has('C')) //true

//清空
s2.clear()

console.log(s2) //Set(0) {}

Set 常用与数组去重

let arr = [1, 2, 3, 4, 5, 1, 2]

console.log(new Set(arr)) //Set(5) { 1, 2, 3, 4, 5 }

得到的是个Set集合, 如要转换成数组,可通过扩展运算符

let arr = [1, 2, 3, 4, 5, 1, 2]

console.log([...new Set(arr)]) //[ 1, 2, 3, 4, 5 ]

深度数组去重

let arr = [{ name: '123' }, { name: '123' }, { name: '234' }]

//先将数组中的元素全部转为字符串
let arr2 = arr.map((item) => JSON.stringify(item))
//将数组去重后转为对象
let arr3 = [...new Set(arr2)].map((item) => JSON.parse(item))
console.log(arr3) // [ { name: '123' }, { name: '234' } ]

14. Map集合

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』和「for…of…』进行遍历。Map的属性和方法。

let m = new Map()
m.set('name', 'ran')
m.set('change', () => {
  console.log('改变!')
})
let key = {
  school: 'atguigu',
}
m.set(key, ['成都', '西安'])

//size
console.log(m.size) //3

//删除
m.delete('name')

//获取
console.log(m.get('change')) //[Function (anonymous)]

// //清空
// m.clear()

//遍历
for (let v of m) {
  console.log(v)
  //[ 'change', [Function (anonymous)] ]
  //  [ { school: 'atguigu' }, [ '成都', '西安' ] ]
}

15. Class

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

class person {
  constructor(brand, price) {
    this.brand = brand
    this.price = price
  }

  call() {
    console.log('我可以打电话')
  }
}

let A = new person('1+', 1999)
console.log(A) //person { brand: '1+', price: 1999 }

静态成员

class Person {
  static name = '手机'
}
let nokia = new Person()
//静态成员无法通过实例化访问
console.log(nokia.name) //undefined

console.log(Person.name) //手机

构造函数继承

function Phone(brand, price) {
  this.brand = brand
  this.price = price
}
Phone.prototype.call = function () {
  console.log('我可以打电话')
}
function SmartPhone(brand, price, color, size) {
  Phone.call(this, brand, price)
  this.color = color
  this.size = size
}

//设置子级构造函数原型
SmartPhone.prototype = new Phone()
SmartPhone.prototype.constructor = SmartPhone

//声明子类方法
SmartPhone.prototype.photo = function () {
  console.log('我可以玩游戏')
}
const phone = new SmartPhone('锤子', 2499, '黑色', '5.5inch')
console.log(phone) //SmartPhone { brand: '锤子', price: 2499, color: '黑色', size: '5.5inch' }

类的继承

class Phone {
  constructor(brand, price) {
    this.brand = brand
    this.price = price
  }
  //父类的成员属性
  call() {
    console.log('我可以打电话')
  }
}
class SmartPhone extends Phone {
  constructor(brand, price, color, size) {
    super(brand, price)
    this.color = color
    this.size = size
  }
  photo() {
    console.log('拍照')
  }

  playGame() {
    console.log('打游戏')
  }
}
const phone = new SmartPhone('小米', 1999, '黑色', '4.7inch')
phone.call() //我可以打电话
phone.photo() //拍照
phone.playGame() //打游戏

子类对父类方法的重写

class Phone {
  constructor(brand, price) {
    this.brand = brand
    this.price = price
  }
  //父类的成员属性
  call() {
    console.log('我可以打电话')
  }
}
class SmartPhone extends Phone {
  constructor(brand, price, color, size) {
    super(brand, price)
    this.color = color
    this.size = size
  }
  photo() {
    console.log('拍照')
  }

  playGame() {
    console.log('打游戏')
  }

  //重写!
  call() {
    console.log('我可以进行视频通话')
  }
}
const phone = new SmartPhone('小米', 1999, '黑色', '4.7inch')
phone.call() //我可以进行视频通话
phone.photo() //拍照
phone.playGame() //打游戏

get 和set的设置

class Phone {
  get price() {
    console.log('价格被读取了')
    return 'I LOVE YOU'
  }

  set price(val) {
    console.log('价格被修改了')
    return val
  }
}

//实例化对象
let s = new Phone()
s.price = 12 //价格被修改了
console.log(s.price) //价格被读取了  I LOVE YOU

16.数值扩展

// Number.EPSILON是 JavaScript的最小精度,属性的值接近于 2.22044...E-16
function equal(a, b) {
  if (Math.abs(a - b) < Number.EPSILON) {
    return true
  } else {
    return false
  }
}

console.log(equal(0.1 + 0.2 === 0.3)) //false
console.log(equal(0.1 + 0.2, 0.3)) //true

//二进制和八进制
let b = 0b1010 //2进制
let o = 0o777 //8进制
let d = 100 //10进制
let x = 0xff //16进制
console.log(x) //255

//检测一个数是否为有限数
console.log(Number.isFinite(100)) //true
console.log(Number.isFinite(100 / 0)) //false
console.log(Number.isFinite(Infinity)) //false

//检测一个数值是否为NaN
console.log(Number.isNaN(123)) //false

//字符串转整数
console.log(Number.parseInt('5213123love')) //5213123
console.log(Number.parseFloat('5.123123神器')) //5.123123

//判断是否为整数
console.log(Number.isInteger(5)) //true
console.log(Number.isInteger(2.5)) //false

//将小数部分抹除
console.log(Math.trunc(3.45345345345)) //3

//检测一个数到底是正数、负数、还是0
console.log(Math.sign(100)) //1
console.log(Math.sign(0)) //0
console.log(Math.sign(-123)) //-1

17. 对象方法扩展

//1.Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)) //true
console.log(Object.is(NaN, NaN)) //false

//2.Object.assign 对象的合并
const a = {
  name: 'ran',
  age: 12,
}
const b = {
  pass: 'i love you',
}
console.log(Object.assign(a, b)) //{name:'ran',age:'12',pass:'i love you'}

//3.Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const school = {
  name: '拉钩教育',
}
const cities = {
  city: ['北京', '上海'],
}
Object.setPrototypeOf(school, cities) //{ name: 'ran', age: 12, pass: 'i love you' }
console.log(Object.getPrototypeOf(school)) //{ city: [ '北京', '上海' ] }
console.log(school) //{ name: '拉钩教育' }

18.模块化

  • 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
  • 模块化的好处:
    1.防止命名冲突
    2.代码复用
    3.高维护性
    4.模块化规范产品
  • ES6之前的模块化规范有:
    1.CommonJS ====> NodeJS、Browserify
    2.AMD ====> requireJS
    3.CMD ====> seaJS

模块功能主要有两个命令构成:export和inport

  • export命令用于规定模块的对外接口
  • inport命令用于输入其他模块提供的功能
// src/js/m1.js
export let school = '拉钩教育'
export function teach(){
    console.log('教技能')
}
import * as m1 from "./src/js/m1.js";
    console.log(m1);
暴露语法汇总
  1. 统一暴露
//统一暴露
let school = '拉钩教育';
function findjob(){
    console.log('找工作吧');
}
//export {school,findjob}

2.默认暴露

//默认暴露
export default {
    school:'lagou',
    change:function(){
        console.log('我们可以改变你')
    }
}
引入语法汇总

1.通用方式引入

import * as m1 from "./src/js/m1.js"
import * as m2 from "./src/js/m2.js"
import * as m3 from "./src/js/m3.js"

2.解构赋值方式

import {school,teach} from "./src/js/m1.js"
import {school as lagou,findJob} from "./src/js/m2.js"
import {default as m3 } from "./src/js/m3.js"
import m3 from "./src/js/m3.js"

19 . ECMAscript2016 中的新特性

  • Array.prototype.includes:用来检测数组中是否包含某个元素,返回布尔类型值
  • 在ES7中引入指数操作符**,用来实现幂运算,功能与Math.pow结果相同
//include
const mingzhu = ['西游记', '红楼梦', '水浒传', '三国演义']
console.log(mingzhu.includes('西游记')) //true
console.log(mingzhu.includes('金瓶梅')) //false

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

20 . ECMAscript2017 中的新特性

20.1async函数

async和await两种语法结合可以让异步代码像同步代码一样

async函数:

  • async函数的返回值为promise对象
  • async返回的promise对象的结果值由async函数执行的返回值决定
async function fn(){
   //1.如果返回的是一个非Promise的对象,则fn()返回的结果就是成功状态的Promise对象,值为返回值
   //2.如果返回的是一个Promise对象,则fn()返回的结果与内部Promise对象的结果一致
   //3.如果返回的是抛出错误,则fn()返回的就是失败状态的Promise对象
   return new Promise((resolve,reject)=>{
       resolve('成功的数据');
   });
}
const result = fn();
result.then(value=>{
   console.log(value)  //成功的数据
},reason=>{
   console.log(reason)
})
20.2await表达式
  • await必须放在async函数中
  • await右侧的表达式一般为promise对象
  • await可以返回的是右侧promise成功的值
  • await右侧的promise如果失败了,就会抛出异常,需要通过try…catch捕获处理
//创建Promise对象
    const p = new Promise((resolve, reject) => {
        // resolve("成功的值")
        reject("失败了")
    })

    //await 必须放在async函数中
    async function main() {
        try {
            let res = await p;
            console.log(res);
        } catch (e) {
            console.log(e);
        }
    }

    //调用函数
    main()  //失败了

发送ajax请求

//ajax请求返回一个promise
    function sendAjax(url){
        return new Promise((resolve, reject) => {

            //创建对象
            const x =new XMLHttpRequest();

            //初始化
            x.open('GET',url);

            //发送
            x.send();

            //时间绑定
            x.onreadystatechange = ()=>{
                if(x.readyState === 4 ){
                    if(x.status >= 200 && x.status < 300){
                        //成功
                        resolve(x.response)
                    }else {
                        //失败
                        reject(x.status)
                    }
                }
            }
        })
    }

   //async 与 await 测试
    async function main(){
        let result = await sendAjax("https://api.apiopen.top/getJoke")
        console.log(result);
    }
    main()
20.3 对象方法扩展
const school = {
  name: '拉钩',
  cities: ['北京', '上海', '深圳'],
  xueke: ['前端', 'Java', '大数据', '运维'],
}

//获取对象所有的键
console.log(Object.keys(school)) // [ 'name', 'cities', 'xueke' ]

//获取对象所有的值
console.log(Object.values(school)) //[ '拉钩', [ '北京', '上海', '深圳' ], [ '前端', 'Java', '大数据', '运维' ] ]

//entries,用来创建map
console.log(Object.entries(school))
/**
 * [
    [ 'name', '拉钩' ],
    [ 'cities', [ '北京', '上海', '深圳' ] ],
    [ 'xueke', [ '前端', 'Java', '大数据', '运维' ] ]
   ]
 */
console.log(new Map(Object.entries(school)))
/**
 * Map(3) {
    'name' => '拉钩',
    'cities' => [ '北京', '上海', '深圳' ],
    'xueke' => [ '前端', 'Java', '大数据', '运维' ]
  }   
 */

//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptor(school))
//二维数组
const res = Object.fromEntries([
  ['name', '张三'],
  ['cities', '成都', '武汉'],
])
console.log(res) //  { name: '张三', cities: '成都' }

//Map
const m = new Map()
m.set('name', 'zhangSan')
const result = Object.fromEntries(m)
console.log(result) //{ name: 'zhangSan' }

21.字符串扩展方法

//trim
   let str= ' asd  '
   console.log(str) //asd
   console.log(str.trimStart()) //asd  清空头空格
   console.log(str.trimEnd()) //  asd  清空尾空格

22.flat

flat 可降低数组的维度

const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
// console.log(arr.flat()) //[ 1, 2, 3, 4, 5, 6, [ 7, 8, 9 ] ]
//参数为深度,是一个数字
console.log(arr.flat(2)) //[ 1, 2, 3, 4, 5, 6,  7, 8, 9  ]

22.Symbol的description

用来获取Symbol的字符串描述

let s = Symbol('拉钩教育');
console.log(s.description) //拉钩教育

23.私有属性

class Person {
  //公有属性
  name
  //私有属性
  #age
  #weight

  //构造方法
  constructor(name, age, weight) {
    this.name = name
    this.#age = age
    this.#weight = weight
  }
  intro() {
    console.log(this.name)
    console.log(this.#age)
    console.log(this.#weight)
  }
}

//实例化
const girl = new Person('张三', 18, '45kg')
console.log(girl.#age) //error
console.log(girl) //Person{name: "张三", #age: 18, #weight: "45kg"}
girl.intro() // 冉 18  45kg

24.可选链操作符

//相当于一个判断符,如果前面的有,就进入下一层级
function main(config) {
  const dbHost = config?.db?.host
  console.log(dbHost) //192.168.1.100
}

main({
  db: {
    host: '192.168.1.100',
    username: 'root',
  },
  cache: {
    host: '192.168.1.200',
    username: 'admin',
  },
})

25.动态import

btn.onclick = function(){
    //使用之前并未引入,动态引入,返回的其实是一个Promise对象
    import('./hello.js').then(module=>{
        module.hello();
    })
}

26.BigInt类型

大整型

let n = 521n
console.log(n, typeof n) // 521n  n

函数

let n = 123
  console.log(BigInt(n)) // 123n  //不要使用浮点型,只能用int

大数值运算

//大数值运算
let max = Number.MAX_SAFE_INTEGER // 9007199254740991
console.log(max + 1) // 9007199254740992
console.log(max + 2) // 9007199254740992 出问题了
console.log(BigInt(max) + BigInt(1)) //9007199254740992n
console.log(BigInt(max) + BigInt(2)) //9007199254740993n

绝对全局对象 globalThis

console.log(globalThis) //window  //适用于复杂环境下直接操作window
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容