ECMAScript6

一、ES6

1.块级作用域-let和var

  • var的设计可以看成JavaScript语言设计上的错误,但这样的错误多半不能修复和移除,因为需要向后兼容
  • 可以将let看成更完美的var
  • 块级作用域
    • JS中使用var来声明一个变量时,变量的作用域主要与函数的定义有关
    • 针对其他块定义来说是没有作用域的,比如if/for等,这在开发中会引起一些问题
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>块级作用域</title>
</head>
<body>
<button>按钮0</button>
<button>按钮1</button>
<button>按钮2</button>
<script>

  //ES5语法,没有块级作用域,只有函数的作用域,无论点击哪个按钮都是按钮2,因为i改变了,类似于全局变量
  // var btns = document.getElementsByTagName("button");
  // for(var i = 0;i<btns.length;i++){
  //   btns[i].addEventListener("click", function () {
  //     console.log("第" + i + "个按钮被点击了")
  //   })
  // }

  //闭包,利用了ES5的函数作用域来解决没有块级作用域的问题
  // var btns = document.getElementsByTagName("button");
  // for(var i = 0;i<btns.length;i++){
  //   (function(i){
  //     btns[i].addEventListener("click", function () {
  //       console.log("第" + i + "个按钮被点击了")
  //     })
  //   })(i)
  // }
  //ES6语法,使用let代替var,let有块级作用域
  let btns = document.getElementsByTagName("button");
  for(let i = 0;i<btns.length;i++){
    btns[i].addEventListener("click", function () {
      console.log("第" + i + "个按钮被点击了")
    })
  }
</script>
</body>
</html>
  • 程序分析
    ES5语法:var定义变量
    在这里插入图片描述
    在这里插入图片描述
    ES5语法:var定义变量,采用闭包来解决
    在这里插入图片描述
    在这里插入图片描述
    ES6语法,采用let来定义变量
    在这里插入图片描述
    在这里插入图片描述

2.const

  • const关键字
    • 在很多语言中已存在,主要的作用是将某个变量修饰为常量
    • 在JavaScript中使用const修饰的标识符为常量,不可以再次赋值
  • 当修饰的标识符不会被再次赋值时,就可以使用const来保证数据的安全性
  • 建议:在ES6开发中,优先使用const,只有需要改变某一标识符的时候才使用let
  • const的注意:
    • 注意一:被const修饰的变量可以看作一个常量,一旦定义了就不能修改,类似于final
    • 注意二:const修饰变量时一定要赋初始值
    • 注意三:const修饰的对象不能改变,但是对象内部的属性可以修改
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>const</title>
</head>
<body>

</body>
<script>
  //1.被const修饰的变量可以看作一个常量,一旦定义了就不能修改,类似于final
  // const name = 'hahha';
  // name = 'kkk'

  //2.const修饰变量时一定要赋初始值
  //const name ;

  //3.const修饰的对象不能改变,但是对象内部的属性可以修改
  const object = {
    name : 'hh',
    age: 12,
    height: 188
  }
  object.name = 'jj'
  object.age = 10
  object.height = 185
</script>
</html>

3.变量解构赋值

  • ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这称为解构赋值
  • 数组的解构
<script>
  const name = ['张三','李四','王五','秦六']
  let [zhang,li,wang,qin] = name
  console.log(zhang);
  console.log(li);
  console.log(wang);
  console.log(qin);
</script>

在这里插入图片描述
在这里插入图片描述

  • 对象的解构
<script>
  //对象的解构
  const zhang = {
    name:'张三',
    age:18,
    call:function () {
      console.log("我叫张三");
    }
  }

  let {name,age,call} = zhang

  console.log(name);
  console.log(age);
  call()
</script>

在这里插入图片描述
在这里插入图片描述

4.模板字符串

  • ES6引入了新的声明字符串的方式,ES5是采用双引号(" "),单引号(’’),来声明字符串的,但这样有一个弊端,就是不能换行,如果我声明的是一串HTML代码,那么不换行的话,很难阅读,而采取换行需要使用字符串拼接,ES6引入了反引号(``)这个完美解决了换行的问题
<script>
  //声明
  let string = `字符串`
  console.log(string,typeof string);

  //内容可以直接换行
  let str = `<ul>
              <li>zhangsan</li>
              <li>lisi</li>
              <li>wangwu</li>
             </ul>`

  //变量拼接
  let name = '张三'
  let out = `${name}是法外狂徒`

  console.log(out);
</script>

在这里插入图片描述
在这里插入图片描述

5.对象字面变量的增强写法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>增强写法</title>
</head>
<body>

</body>
<script>
  const name = 'jj'
  const age = 15
  const height = 188

//  ES5写法
//   const obj = {
//     name: name,
//     age: age,
//     height: height
//   }

//  ES6写法
  const obj = {
    name,
    age,
    height
  }
  console.log(obj)

  //函数的增强写法
  //ES5
  const object = {
    run:function () {

    }
  }
  //ES6增强写法
  const object = {
    run() {

    }
  }
</script>
</html>

6.箭头函数的使用和this指向

(1)基本使用
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>箭头函数的基本使用</title>
</head>
<body>
<script>
  //箭头函数:也是一直定义函数的方式
  //1.定义函数的方式:function
  const aaa = function () {

  }
  //2.对象字面量中定义函数
  const obj = {
    aaa(){

    }
  }
  //3.ES6中的箭头函数
  // const aaa = (参数列表) => {
  //
  // }
  //无参数时
  const ccc = () => {

  }
</script>
</body>
</html>
(2)参数和返回值
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>箭头函数参数和返回值</title>
</head>
<body>
<script>
  //1.参数问题
  //两个参数
  const sum = (num1,num2) => {
    return num1 + num2
  }
  //一个参数(可以把括号省略)
  const power = num => {
    return num * num
  }
   //2.返回值
  //函数代码块中有多行代码
  const test = () => {
    console.log('hello world');
    console.log('hello vue');
  }
  //函数代码块中只有一行代码
  const mul = (num1,num2) => num1 * num2//自动返回结果
  //没有返回值,打印demo的结果时为undefined,调用demo时打印hello world
  const demo = () => console.log('hello world');
</script>
</body>
</html>
(3)this的使用
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>箭头函数中this的使用</title>
</head>
<body>
<script>
  //什么时候使用箭头函数,一般是作为其他函数的参数时使用
  setTimeout(function () {
    console.log(this) //这时打印的是window
  },1000)
  setTimeout(() => {
    console.log(this) //这时打印的是window
  },1000)

  //问题:箭头函数的this是如何查找的?
  //答案:向外层作用域中,一层一层查早this,直到有this的定义
  const obj = {
    aaa(){
      setTimeout(function () {
        console.log(this) //这时打印的是window
        setTimeout(function () {
          console.log(this) //这时打印的是window
        },1000)
        setTimeout(() => {
          console.log(this) //这时打印的是window,查找到最外层的setTimeout时发现有this的定义,指向的是window
        },1000)
      },1000)
      setTimeout(() => {
        console.log(this) //这时打印的是Obj对象,查找到aaa时发现有this的定义
      },1000)
    }
  }
</script>
</body>
</html>

7.函数参数的默认值设置

  • ES6允许给函数的参数赋初始值
<script>
  //形参(一般具有默认值的参数要放在后面)
  function add(a,b,c = 10) {
    return a + b + c
  }

  console.log(add(1, 2));
  console.log(add(1, 2, 3));

  //与解构赋值结合
  function connect({host = '127.0.0.1',user,password,port}) {
    console.log(host);
    console.log(user);
    console.log(password);
    console.log(port);
  }

  connect ({
    host : 'localhost',
    user:'root',
    password:'root',
    port:'3306'
  })
</script>

在这里插入图片描述
在这里插入图片描述

8.rest参数

  • ES6引入rest参数,用于获取函数的实参,用来代替argument
<script>
  //ES5获取实参的方式
  function name() {
    console.log(arguments);
  }
  name('张三','李四','王五')

  //ES6rest参数
  function name1(...args) {
    console.log(args);
  }
  name1('张三','李四','王五')
  
  //rest参数必须放到最后
  function fn(a,b,...args) {
    console.log(a);
    console.log(b);
    console.log(args);
  }
  fn(1,2,3,4,5)
</script>

在这里插入图片描述
在这里插入图片描述

9.扩展运算符

  • … 扩展运算符能将数组转换为逗号分隔的参数序列
<script>
  const name = ['张三','李四','王五']

  function kuangtu() {
    console.log(arguments);
  }

  kuangtu(name)
  kuangtu(...name)//这样相当于kuangtu('张三','李四','王五')
</script>

在这里插入图片描述

  • 扩展运算符的应用
<script>
  //数组的合并
  const name = ['张三','李四']
  const name1 = ['王五','秦六']
  const kuangtu = name.concat(name1)
  const kuangtu1 = [...name,...name1]

  console.log(kuangtu);
  console.log(kuangtu1);

  //数组的克隆
  const letter = ['a','b','c']
  const colonletter = [...letter]
  console.log(colonletter);

  //将伪数组转换为真正的数组
  const divs = document.querySelectorAll('div')
  console.log(divs);

  const divArrs = [...divs]
  console.log(divArrs);
</script>

在这里插入图片描述

10.symbol

(1)Symbol介绍与创建
  • ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
  • Symbol特点
    • Symbol 的值是唯一的,用来解决命名冲突的问题
    • Symbol值不能与其他数据进行运算
    • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
<script>
  //创建一个symbol
  let s = Symbol()
  console.log(s);

  let s1 = Symbol("张三")
  let s2 = Symbol("张三")
  //s1与s2并不一样
  console.log(s1 === s2);
  //Symbol.for创建
  let s3 = Symbol.for("张三")
  let s4 = Symbol.for("张三")
  //s3与s4一样
  console.log(s3 === s4);

  //不能与其他数据运算
  // let result = s + 10
  // let result = s > 10
  // let result = s + "10"
</script>

在这里插入图片描述

(2)对象添加Symbol类型属性和方法
  • 在不知道对象中是否存在同名的方法,而又不想去改变原对象的同名方法,可以使用Symbol安全地给对象添加相应的方法
<script>
  let game = {
    name:'游戏',
    up(){
      console.log('上升');
    },
    down(){
      console.log('下降');
    }
  }

  let methods = {
    up:Symbol(),
    down:Symbol()
  }
  game[methods.up] = function() {
    console.log('我可以上升');
  }
  game[methods.down] = function () {
    console.log('我可以下降');
  }

  console.log(game)
  
  let game1 = {
    name:'游戏',
    [Symbol("up")] : function() {
      console.log('上升');
    },
    [Symbol("down")] : function () {
      console.log('下降');
    }
  }

  console.log(game1);
</script>

在这里插入图片描述

(3)Symbol的内置属性
  • 除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。
Symbol.hasInstance当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
Symbol.unscopables该对象指定了使用with关键字时,哪些属性会被with环境排除。
Symbol.match当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。
Symbol.search当该对象被str. search (myObject)方法调用时,会返回该方法的返回值。
Symbol.split当该对象被str. split (myObject)方法调用时,会返回该方法的返回值。
Symbol.iterator对象进行 for…of循环时,会调用Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
Symbol. toStringTag在该对象上面调用toString方法时,返回该方法的返回值
Symbol.species创建衍生对象时,会使用该属性

11.迭代器

(1)迭代器介绍
  • 迭代器(terator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
  • ES6 创造了一种新的遍历命令 for…of循环,lterator接口主要供 for…of 消费
  • 原生具备iterator接口的数据(可用for…of遍历)
    • Array
      Arguments
      Set
      Map
      string
      TypedArray
      NodeList
  • 原理
    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
    • 每调用next方法返回一个包含value 和l done 属性的对象
    • 注:需要自定义遍历数据的时候,要想到迭代器。
<script>
  const name = ['张三','李四','王五','秦六']

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

  for ( let i in name){
    console.log(i);
  }

  let iterator = name[Symbol.iterator]()
  console.log(iterator);
  console.log(iterator.next());
  console.log(iterator.next());
  console.log(iterator.next());
  console.log(iterator.next());
  console.log(iterator.next());
</script>

在这里插入图片描述

(2)迭代器自定义数据遍历
<script>
  //遍历自定义数据
  const Class = {
    name : '法外狂徒',
    members : [
        "zhangsan",
        "lisi",
        "wangwu",
        "qinliu"
    ],
    [Symbol.iterator](){
      let index = 0
      let _this = this
      return{
        next:function () {
          if(index < _this.members.length) {
            const result = {value:_this.members[index],done:false}
            index++
            return result
          }
          else {
            return {value: undefined,done: true}
          }
        }
      }
    }
  }
  for(let i of Class){
    console.log(i);
  }
</script>

在这里插入图片描述
在这里插入图片描述

12.生成器

(1)生成器函数声明与调用
  • 生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
<script>
  //生成器函数声明
  function * a() {
    console.log('111');
  }
   let iterator = a()
  iterator.next()

  //嵌套yield,yield可以看作函数代码的分隔符
  function * b() {
    console.log("第一")
    yield '111';
    console.log("第二")
    yield '222';
    console.log("第三")
    yield '333';
  }

  let iterator1 = b()
  iterator1.next()
  iterator1.next()
  iterator1.next()
  
  for(let i of b()){
    console.log(i);
  }

</script>

在这里插入图片描述

(2)生成器函数的参数传递
<script>
function * a(arg) {
    console.log(arg);
    let one = yield '111'
    console.log(one);
    let two = yield '222'
    console.log(two);
    let three = yield '333'
    console.log(three);
  }

  let iterator = a("AAA")
  console.log(iterator.next());
  console.log(iterator.next("BBB"));
  console.log(iterator.next("CCC"));
  console.log(iterator.next("DDD"));
</script>

在这里插入图片描述

(3)生成器函数实例(解决异步编程,回调地狱的问题)
<script>
//实例
  //1s后输出111,2s后输出222,3s后输出333
  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()
  </script>

在这里插入图片描述

13.Promise

(1)Promise的介绍和基本使用
1)什么是Promise
  • ES6中一个非常重要和好用的特性就是Promise
  • Promise到底是做什么的呢?
    • Promise是异步编程的一种解决方案。
  • 那什么时候会来处理异步事件呢?
    • 一种很常见的场景应该就是网络请求了。
    • 封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。
    • 所以往往会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
    • 如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。
  • 但是,当网络请求非常复杂时,就会出现回调地狱。
2)网络请求的回调地狱
  • 考虑下面的场景(有夸张的成分):
    • 通过一个url1从服务器加载一个数据data1 , data1中包含了下一个请求的url2
    • 通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3
    • 通过data2取出url3,从服务器加载数据data3 ,data3中包含了下一个请求的url4
    • 发送网络请求url4,获取最终的数据data4
$.ajax( 'url1', function (data1) {
	$.ajax(data1 ['url2 '], function (data2){
		$.ajax(data2 ['url3']function (data3){
			$.ajax(data3 ['url4'],function (data4){
				console.log(data4);
			})
		})
	})
})

  • 上面的代码有什么问题吗?
    • 正常情况下,不会有什么问题,可以正常运行并且获取想要的结果。
    • 但是,这样的代码难看而且不容易维护。
    • 我们更加期望的是一种更加优雅的方式来进行这种异步操作。
  • 如何做呢?就是使用Promise。
    • Promise可以以一种非常优雅的方式来解决这个问题。
3)定时器的异步事件
  • 用一个定时器来模拟异步事件:
    • 假设下面的data是从网络上1秒后请求的数据
    • console.log就是我们的处理方式。
  setTimeout(()=>{
    let data1 = 'Hello World'
    console.log(data1);
    setTimeout(() =>{
    	let data2 = 'Hello Vuejs'
    	console.log(data2);
    },1000)
  },1000
  • 这是过去的处理方式,将它换成Promise代码
  //resolve,reject作为Promise的参数
  //resolve,reject本身也是函数
  new Promise((resolve ,reject)=>{
  //第一次网络请求
    setTimeout(()=>{
      resolve('Hello World')
      reject('error')
    },1000)
  }).then( data =>{
  //第一次处理
    console.log(data);
    //第二次网络请求
    return new Promise((resolve ,reject)=>{
		setTimeout(()=>{
			 resolve('Hello Vuejs')
    	},1000)
	}).then( data =>{
  		//第二次处理
    	console.log(data);
    })
  }).catch( error =>{
  //错误处理
    console.log(error);
  })
(2)Promise的三种状态
  • 首先,当开发中有异步操作时,就可以给异步操作包装一个Promise
  • 异步操作之后会有三种状态:
    • pending :等待状态,比如正在进行网络请求,或者定时器没有到时间。
    • fulfill :满足状态,当主动回调了resolve时,就处于该状态,并且会回调.then()
    • reject:拒绝状态,当主动回调了reject时,就处于该状态,并且会回调.catch()
  • Promise的另外一种写法:
  • catch中的内容可以写在then中
 new Promise((resolve ,reject)=>{
    //第一次网络请求
    setTimeout(()=>{
      resolve('Hello World')
      reject('error')
    },1000)
  }).then( data =>{
    //第一次处理
    console.log(data);
    //第二次网络请求
    return new Promise((resolve ,reject)=>{
      setTimeout(()=>{
        resolve('Hello Vuejs')
      },1000)
    }).then( data => {
      //第二次处理
      console.log(data);
    })
  },error =>{
    //错误处理
    console.log(error);
  })
(3)Promise的链式调用
  • 无论是then还是catch都可以返回一个Promise对象。
  • 所以,代码其实是可以进行链式调用的:
  • 这里直接通过Promise包装了一下新的数据,将Promise对象返回了
    • Promise.resovle():将数据包装成Promise对象,并且在内部回调resolve()函数
    • Promise.reject():将数据包装成Promise对象,并且在内部回调reject()函数
  // 链式调用的代码
  new Promise( (resolve,reject) =>{
    setTimeout( function() {
      resolve( 'Hello World ' )
    },1000)
  }).then(data => {
    console.log(data);//=>Hello World
    return new Promise(resolve => {
      resolve(data + '111')
    })
  }).then( data => {
    console.log(data);// => Hello World111
    return new Promise(resolve => {
      resolve(data + '222')
    })
  }).then(data => {
    console.log(data);//=>Hello World111222
    return new Promise((resolve,reject) => {
      reject(data + 'error')
    })
  }).then(data => {
    console.log(data);// 这里没有输出,这部分代码不会执行
    return new Promise(resolve => {
      resolve(data + '333')
    })
  }).catch(data => {
    console.log(data);// =→>Hello world111222error
    return new Promise(resolve => {
      resolve(data + '444')
    })
  }).then(data => {
    console.log(data);//=> Hello World111222error444
  })
  • 简写一
//简写一
  new Promise( (resolve,reject) =>{
    setTimeout( function() {
      resolve( 'Hello World ' )
    },1000)
  }).then(data => {
    console.log(data);//=>Hello World
    return Promise.resolve(data + '111')
  }).then(data => {
    console.log(data);// => Hello World111
    return Promise.resolve(data + '222 ')
  }).then(data => {
    console.log(data);//=>Hello World111222
    return Promise.reject(data + 'error ')
  }).then(data => {
    console.log(data);// 这里没有输出,这部分代码不会执行
    return Promise.resolve(data + '333 ')
  }).catch(data => {
    console.log(data);// =→>Hello world111222error
    return Promise.resolve(data + '444')
  }).then(data => {
    console.log(data);//=> Hello World111222error444
  })
  • 简写二
//简写二
  new Promise( (resolve,reject) =>{
    setTimeout( function() {
      resolve( 'Hello World ' )
    },1000)
  }).then(data => {
    console.log(data);//=>Hello World
    return data + '111'
  }).then(data => {
    console.log(data);// => Hello World111
    return data + '222 '
  }).then(data => {
    console.log(data);//=>Hello World111222
    throw data + 'error'
  }).then(data => {
    console.log(data);// 这里没有输出,这部分代码不会执行
    return data + '333'
  }).catch(data => {
    console.log(data);// =→>Hello world111222error
    return data + '444'
  }).then(data => {
    console.log(data);//=> Hello World111222error444
  })
(4)Promise的all方法的使用
  • all方法可以等待在其内部的所有请求都返回结果后全部获取出来
  Promise.all([
    new Promise((resolve,reject)=>{
      setTimeout(()=>{
        resolve({name:'zhangsan',age:18})
      },2000)
    }),
    new Promise((resolve,reject)=>{
        resolve({name:'lisi',age:19})
    },1000)
  ]).then( result =>{
    console.log(result);
  })
  • 运行截图
    在这里插入图片描述

14.集合Set

(1)集合介绍
  • ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算和for…of进行遍历,集合的属性和方法:
    • size返回集合的元素个数
    • add增加一个新元素,返回当前集合
    • delete删除元素,返回boolean值
    • has检测集合中是否包含某个元素,返回boolean值
    • clear清空集合,返回undefined
<script>
  //声明一个集合
  let s = new Set
  let s1  = new Set(['111','222','333'])

  console.log(s1.size);
  s1.add('444')
  console.log(s1);
  s1.delete('444')
  console.log(s1);
  console.log(s1.has('111'));

  for (let i of s1){
    console.log(i);
  }
  s1.clear()
  console.log(s1);
</script>

在这里插入图片描述

(2)集合实践
<script>
  const arr = [1,1,2,3,3,4,5,5,6]
  //去重
  let one = [...new Set(arr)]
  console.log(one);
  //交集
  const arr2 = [4,5,6,7,8]
  let two = [...new Set(arr)].filter(item =>{
    let s2 = new Set(arr2)
    if(s2.has(item)){
      return true
    }else
      return false
  })
  console.log(two);
  //并集
  let three = [...new Set([...arr,...arr2])]
  console.log(three);
  //差集
  let four = [...new Set(arr)].filter(item =>{
    let s2 = new Set(arr2)
    if(!s2.has(item)){
      return true
    }else
      return false
  })
  console.log(four);
</script>

在这里插入图片描述

15.Map

  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用扩展运算符和for…of进行遍历。Map的属性和方法:
    • size返回Map的元素个数
    • set增加一个新元素,返回当前Map
    • get返回键名对象的键值
    • has检测 Map中是否包含某个元素,返回 boolean值
    • clear清空Map,返回undefined
<script>
  let m = new Map

  m.set('name','zhangsan')
  m.set('eat',function () {
    console.log('吃饭')
  })
  let key = {
    province : '省份'
  }
  m.set(key,["北京","天津","河北"])

  comsole.log(m);
  console.log(m.size);
  console.log(m.get('name'));
  console.log(m.get(key));

  m.delete('name')
  console.log(m);

  // m.clear()
  // console.log(m);
</script>

在这里插入图片描述

16.Class

(1)Class介绍
  • ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6 的 class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
  • 知识点:
    • class声明类
    • constructor定义构造函数初始化
    • extends 继承父类
    • super调用父级构造方法
    • static定义静态方法和属性
    • 父类方法可以重写
<script>
  //ES5
  function Phone(brand,price) {
    this.brand = brand
    this.price = price
  }
  //添加方法
  Phone.prototype.call = function () {
    console.log('打电话');
  }
  //实例化对象
  let Huawei = new Phone("华为",4999)
  Huawei.call()
  console.log(Huawei);
  //ES6
  class TelPhone{
    //构造方法
    constructor(brand,price) {
      this.brand = brand
      this.price = price
    }
    call(){
      console.log('打电话');
    }
  }
  let onePlus = new TelPhone("一加",3999)
  onePlus.call()
  console.log(onePlus);
</script>

在这里插入图片描述

(2)静态成员
  • 静态成员的意思是,变量或者函数是属于这个类的,而不属于实例对象,所以实例对象并不能使用它们
<script>
  //ES5
  function Phone() {
  }
  Phone.name = '手机'
  Phone.call = function () {
    console.log('打电话');
  }
  Phone.prototype.size = 5.5
  let huawei = new Phone()
  console.log(huawei.name);
  console.log(huawei.size);

  //ES6
  class TelPhone{
    static name = '手机'
    static call(){
      console.log('打电话');
    }
  }
  let nokia = new TelPhone()
  console.log(nokia.name);
</script>

在这里插入图片描述

(3)类继承
<script>
  class phone{
    constructor(brand,price) {
      this.brand = brand
      this.price = price
    }
  }
  class smartPhone extends phone{
    constructor(brand,price,color,size) {
      super(brand,price);
      this.color = color;
      this.size = size;
    }
    playGame(){
      console.log('玩游戏');
    }
  }
  let xiaomi = new smartPhone('小米',2000,'黑色',5.5)
  console.log(xiaomi);
  xiaomi.playGame()
</script>

在这里插入图片描述

(4)子类对父类方法的重写
<script>
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;
    }
    playGame(){
      console.log('玩游戏');
    }
    call(){
      console.log('视频通话');
    }
  }
  let xiaomi = new smartPhone('小米',2000,'黑色',5.5)
  console.log(xiaomi);
  xiaomi.playGame()
  xiaomi.call()
  </script>

在这里插入图片描述

(5)get和set
<script>
  class phone{
    get Price(){
      console.log('属性被读取了');
      return '1000元'
    }
    set Price(newValue){
      console.log('属性被修改了');
    }
  }
  let s = new phone()
  console.log(s.Price);
  s.Price = 'free'
</script>

在这里插入图片描述

17.数值扩展

<script>
  //Number.EPSILON是JavaScript表示的最小精度
  console.log(0.1 + 0.2 === 0.3);//这样实际是不相等的
  function equal(a,b) {
    if(Math.abs(a-b) < Number.EPSILON){
      return true
    }else {
      return false
    }
  }
 //如果两者相减,精度小于Number.EPSILON,可以认为两者相等
  console.log(equal(0.1 + 0.2, 0.3));

  //进制
  //二进制
  let b = 0b1010
  //八进制
  let o = 0o777
  //十六进制
  let h = 0x100

  console.log(b);
  console.log(o);
  console.log(h);

  //Number.isFinite()检测一个数值是否为有限数,是返回true,不是返回false
  console.log(Number.isFinite(100));
  console.log(Number.isFinite(100 / 0));

  //Number.isNaN()检测一个数值是否为NaN,是返回true,不是返回false
  console.log(Number.isNaN(100));

  //Number.parseInt() Number.parseFloat(),字符串转整数,浮点数
  console.log(Number.parseInt('123aaa'));
  console.log(Number.parseFloat("1.23aaa"));

  //Number.isInteger() 判断一个数是否为整数,是返回true,不是返回false
  console.log(Number.isInteger(100.1));

  //Math.trunc(),将小数部分抹掉
  console.log(Math.trunc(1.1));

  //Math.sign(),判断一个数是否为正数,负数,或零,正数返回1,负数返回-1,零返回0
  console.log(Math.sign(-100));
  console.log(Math.sign(0));
  console.log(Math.sign(100));

</script>

18.对象方法扩展

<script>
  // Object.is() 判断两个值是否完全相等,类似于===
  console.log(Object.is(120, 120));
  console.log(Object.is(NaN, NaN));//这样是相等的
  console.log(NaN === NaN);//这样是不等的

  //Object.assign(),对象的合并
  const info  = {
    name : 'zhangsan',
    age: 18
  }
  const info1 = {
    age:20,
    height:180
  }
  //若对象存在同名属性,后面的对象属性会将前面的对象属性覆盖
  console.log(Object.assign(info, info1));

  //Object.setPrototypeOf() 设置原型对象 Object.getPrototypeOf() 获取原型对象
  const province = {
    province: "省份"
  }
  const cites = {
    cites : ['北京','上海','南京']
  }
  Object.setPrototypeOf(province,cites)
  console.log(Object.getPrototypeOf(province));
  console.log(province);
</script>

19.ES6模块化的导入和导出

export基本使用

  1. export指令用于导出变量,例如:
// info.js
export let name = '张三'
export let age = 18
export let height = 1.88
  • 另一种写法
// info.js
let name = '张三'
let age = 18
let height = 1.88
export (name,age,height)
  1. export导出函数或类
export function test(content) {
	console.log(content);
}
export class Person {
	constructor(name,age) {
		this.name = name ;
		this.age = age;
	}
	run(){
		console.log(this.name + "在奔跑");
	}
}
  • 另一种写法
function test(content){
	console.log(content);
}
class Person {
	constructor(name, age){
		this.name = name ;
		this.age = age ;
	}
	run() {
		console.1og(this.name +"在奔跑");
	}
}
export {test,Person}
  1. export default
  • 某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名,这个时候就可以使用export default
// info.js
export default function o {
	console.1og ( 'default function ' );
}
  • 我们来到main.js中,这样使用就可以了
    这里的myFunc是自己命名的,你可以根据需要命名它对应的名字
//mian.js
import myFunc from './info.js '
myFunc()
  • 另外,需要注意: export default在同一个模块中,不允许同时存在多个。

import的基本使用

  • 使用export指令导出了模块对外提供的接口,可以通过import命令来加载对应的这个模块了
  • 首先,我们需要在HTML代码中引入两个js文件,并且类型需要设置为module
<script src="info.js" type="module"></script>
<script src="main.js" type="module"></script>
  • import指令用于导入模块中的内容,比如main.js的代码
import {name,age,height} from "./info.js"
console.log(name, age,height);
  • 如果希望某个模块中所有的信息都导入,一个个导入显然有些麻烦;
    • 通过*可以导入模块中所有的export变量
    • 但是通常情况下我们需要给*起一个别名,方便后续的使用
import * as info from './info.js'
console.log(info.name,info.age, info.height,info.friends);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值