ECMAScript6相关笔记

ECMAScript6

常用

let关键字

  1. 作用:与var类似, 用于声明一个变量

  2. 特点:
    1)在块作用域内有效;
    2)不能重复声明;
    3)不会预处理, 不存在提升

  3. 应用:
    1)循环遍历加监听
    2)使用let取代var是趋势

<script type="text/javascript">
    // 不会预处理, 不存在提升
    // console.log(username)    //error
    let username = 'yoliu'
    console.log(username) //yoliu

	// 在块作用域内有效
    let btns = document.getElementsByTagName('button')
    for (var i = 0; i < btns.length; i++) {
      var btn = btns[i];
      btn.onclick = function () {
        alert(i) // 此时不管点击哪个按钮都显示3
      }
    }

    for (let i = 0; i < btns.length; i++) {
      var btn = btns[i];
      btn.onclick = function () {
        alert(i) // 此时能够正常显示对应的i 
      }
    }
</script>

const关键字

  1. 作用:定义一个常量
  2. 特点:
    1)不能修改
    2)其它特点同let
  3. 应用:保存不用改变的数据

变量的解构赋值

<script type="text/javascript">
    let obj = {
      username: 'yoliu',
      age: 21
    }
    // let username = obj.username
    // let age = obj.age

    let {
      username,
      age
    } = obj
    console.log(username, age)

    let arr = [1, 3, 5, 'abc', true]
    let [, , a, b, c] = arr
    console.log(a, b, c)

    function foo({
      username,
      age
    }) {  //相当于 {username, age} = obj
      console.log(username, age)
    }
    foo(obj)
</script>

模板字符串

  1. 模板字符串 : 简化字符串的拼接 模板字符串必须用 包含变化的部分使用${xxx}定义
<script type="text/javascript">
  let obj = {username:'yoliu',age:21}
  let str = '我的名字叫:' + obj.username + ',我今年的年龄是:' + obj.age
  console.log(str)

  str = `我的名字叫:${obj.username},我今年的年龄是:${obj.age}`
  console.log(str)

</script>
  • includes(str) : 判断是否包含指定的字符串
  • startsWith(str) : 判断是否以指定字符串开头
  • endsWith(str) : 判断是否以指定字符串结尾
  • repeat(count) : 重复指定次数

简化的对象写法

  • 简化的对象写法:
    1)省略同名的属性值
    2)省略方法的function
  • 例如:
    let x = 1;
    let y = 2;
    let point = {
    x,
    y,
    setX (x) {this.x = x}
    };
<script type="text/javascript">
  let username = 'yoliu'
  let age = 21
  let obj = {
    username,  //同名的属性可以省略不写
    age,
    getName(){   // 可以省略函数的function
      return this.username
    }
  }
  console.log(obj)
  console.log(obj.getName())
</script>
  • Object.assign(target, source1, source2…) : 将源对象的属性复制到目标对象上
  • Object.is(v1, v2) : 判断2个数据是否完全相等
  • __proto__属性 : 隐式原型属性

数组

  • Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
  • Array.of(v1, v2, v3) : 将一系列值转换成数组
  • find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
  • findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标

箭头函数

作用: 定义匿名函数

  • 基本语法:

    1. 没有参数: () => console.log(‘xxxx’)
    2. 一个参数: i => i+2
    3. 大于一个参数: (i,j) => i+j
    4. 函数体不用大括号: 默认返回结果
    5. 函数体如果有多个语句, 需要用{}包围,若有需要返回的内容,需要手动返回
    6. 使用场景: 多用来定义回调函数
  • 箭头函数的特点:

    1. 简洁
    2. 箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this
    3. 扩展理解: 箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。

3点运算符

  • 用途
  1. rest(可变)参数

  2. 扩展运算符

<script type="text/javascript">
    //  rest(可变)参数
    // function foo(a, b) {
    //   console.log(arguments)
    //   arguments.forEach(function (item, index) {
    //     console.log(item, index) //因为arguments是伪数组,所以不具备数组的方法,所以会报错
    //   })
    // }

    function foo(...value) {
      console.log(value)
      value.forEach(function (item, index) {
        console.log(item, index) //因为arguments是伪数组,所以不具备数组的方法,所以会报错
      })
    }
    foo(2, 65, 33, 44)
	
	// 扩展运算符
    let arr = [1, 6]
    let arr1 = [2, 3, 4, 5]
    arr = [1, ...arr1, 6]
    console.log(arr)
    console.log(...arr)
</script>

注意:当使用三点运算符收集实参的时候,可变参数只能放在当前的最后即function foo(a,b,c,…value )

形参默认值

当不传入参数的时候默认使用形参里的默认值

<script type="text/javascript">
  // 定义一个点的坐标的构造函数
  function Point(x = 0, y = 0) {
    this.x = x
    this.y = y
  }

  let point = new Point(52,7)
  console.log(point)
  let point1 = new Point()
  console.log(point1)
</script>

promis对象

  • 解决回调地狱(回调函数的层层嵌套, 编码是不断向右扩展, 阅读性很差)
  • 能以同步编码的方式实现异步调用
  • 在es6之前原生的js中是没这种实现的, 一些第三方框架(jQuery)实现了promise
  1. 理解:
  • Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)
  • 有了promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称’回调地狱’)
  • ES6的Promise是一个构造函数, 用来生成promise实例*
  1. 使用promise基本步骤(2步):
  • 创建promise对象

  • 调用promise的then()

  1. promise对象的3个状态
  • pending: 初始化状态
  • fullfilled: 成功状态
  • rejected: 失败状态
  1. 应用:
  • 使用promise实现超时处理
  • 使用promise封装处理ajax请求
<script type="text/javascript">
    /*
    // 创建promise对象
    let promise = new Promise((resolve, reject) => {
      // 初始化promise状态: pending:初始化
      console.log(111) // 该函数同步执行,所以可以在222之前打印
      // 执行异步操作,通常是发送ajax请求,开启定时器
      setTimeout(() => {
        console.log(333)
        // 根据异步任务的返回结果去修改promise的状态
        // 异步任务执行成功
        // resolve('哈哈'); // 修改promise的状态为fullfilled:成功的状态
        // 异步任务失败
        reject('555') //修改promise的状态为rejected:失败的状态

      }, 2000)
    })
    console.log(222)

    promise
      .then((data) => {
        // 成功的回调
        console.log(data, '成功了!')
      }, (err) => {
        // 失败的回调
        console.log(err, '失败了!')
      })
	*/

	// 定义获取新闻的功能函数
    function getNews(url) {
      let promise = new Promise((resolve, reject) => {
        // 状态:初始化
        // 执行异步任务

        // 创建实例对象
        let xmlhttp = new XMLHttpRequest();

        // open设置请求的方式以及url
        xmlhttp.open('get', url)
        // 绑定监听 onload
        xmlhttp.onload = function () {
          // 请求成功
          // 修改状态
          resolve(xmlhttp.responseText) // 修改promise的状态为成功状态
          if (xmlhttp.status != 200) { // 请求失败
            reject('暂时没有新闻内容')
          }
        }
        // 发送
        xmlhttp.send()
      })
      return promise
    }

    getNews('http://localhost:3000/news?id=2')
      .then((data) => {
        console.log(data)
        // 发送请求获取评论内容
        let commentsUrl = JSON.parse(data).commentsUrl
        let url = 'http://localhost:3000' + commentsUrl
        // 发送请求
        return getNews(url)
      }, (error) => {
        console.log(error)
      })
      .then((data) => {
        console.log(data)
      }, (error) => {
        console.log(error)
      })
</script>

Symbol

前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境

Symbol:

  • 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象)*

  • 特点:

    • Symbol属性值对应的值是唯一的,解决命名冲突问题
    • Symbol值不能与其他数据进行计算,包括同字符串拼串
    • for in, for of遍历时不会遍历symbol属性。
  • 使用:

    • 调用Symbol函数得到symbol值
    // 创建symbol属性值
        let symbol = Symbol()
        console.log(symbol)
        let obj = {
          username: 'yoliu',
          age: 21
        }
        obj[symbol] = 'hello'
        console.log(obj)
    
    • 传参标识
    let symbol2 = Symbol('one')
        let symbol3 = Symbol('tow')
        console.log(symbol2 === symbol3) // false
        console.log(symbol2)  // Symbol('one')
        console.log(symbol3) // Symbol('two')
    
    • 内置Symbol值

      除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。

      - Symbol.iterator

      对象的Symbol.iterator属性,指向该对象的默认遍历器方法(后边讲)

Iterator遍历器

  • 概念: iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制
  • 作用:
    • 为各种数据结构,提供一个统一的、简便的访问接口;
    • 使得数据结构的成员能够按某种次序排列
    • ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。
  • 工作原理:
    • 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
    • 第一次调用next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
    • 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
      • value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
      • 当遍历结束的时候返回的value值是undefined,done值为false
  • 原生具备iterator接口的数据(可用for of遍历)
    • Array
    • arguments
    • set容器
    • map容器
    • String
      。。。
<script type="text/javascript">
    // 模拟指针对象(遍历器对象)
    function myIterator(arr) { // iterator接口
      let nextIndex = 0
      return { // 遍历器对象
        next: function () {
          return nextIndex < arr.length ? {
            vale: arr[nextIndex++],
            done: false
          } : {
            vale: arr[nextIndex++],
            done: true
          }
        }
      }
    }

    // 准备一个数据
    let arr = [1, 4, 6, 'abc']
    let iteratorObj = myIterator(arr)
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())

    // 将iterator接口部署到指定的数据类型上,可以使用for of去循环遍历
    // 数组、字符串、arguments、set容器、map容器
    for (let i of arr) {
      console.log(i)
    }

    let str = 'ajdkdff'
    for (let i of str) {
      console.log(i)
    }

    function fun() {
      for (let i of arguments) {
        console.log(i)
      }
    }
    fun(1, 4, 5, 'abc')

    let obj = {
      username: 'yoliu',
      age: 21
    }
    // for (let i of obj) {
    //   console.log(i) // error obj is not iterable
    // }

    // 等同于在指定的数据内结构上部署了iterator接口。。
    // 当使用for of去遍历某一个数据结构的时候,首先去找Symbol.iterator,找到了就去遍历,没有找到的话不能遍历  xxx is not iterable
    let targetData = {
      [Symbol.iterator]: function () {
        let nextIndex = 0
        return { // 遍历器对象
          next: function () {
            return nextIndex < this.length ? {
              vale: this[nextIndex++],
              done: false
            } : {
              vale: this[nextIndex++],
              done: true
            }
          }
        }
      }
    }

    // 使用三点运算符,结构赋值,默认去调用iterator接口
    let arr2 = [1, 6]
    let arr3 = [2, 3, 4, 5]
    arr2 = [1, ...arr3, 6]
    console.log(arr2) //1 2 3 4 5 6
    let [a, b] = arr2
    console.log(a, b)  //1 2
  </script>

Generator函数

  • 概念:
    • ES6提供的解决异步编程的方案之一
    • Generator函数是一个状态机,内部封装了不同状态的数据,
    • 用来生成遍历器对象
    • 可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果
  • 特点
    • function 与函数名之间有一个星号
    • 内部用yield表达式来定义不同的状态
    • generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑
    • 调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
    • 再次调用next方法会从上一次停止时的yield处开始,直到最后
    • yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。

async函数

ES2017 (ES8)标准引入了 async 函数,使得异步操作变得更加方便。

  • 概念: 真正意义上去解决异步回调的问题,同步流程表达异步操作

  • 本质: Generator的语法糖

  • 语法:

<script type="text/javascript" src="./js/jquery-1.10.1.min.js"></script>
  <script type="text/javascript">
    // async基本使用
    async function foo() {
      return new Promise(resolve => {
        // setTimeout(function () {
        //   resolve()
        // }, 2000)
        setTimeout(resolve, 2000)
      })
    }

    async function test() {
      console.log('开始执行', new Date().toTimeString())
      await foo()
      console.log('执行完毕', new Date().toTimeString())
    }
    test()

    // async里的await返回值
    function test2() {
      return 'xxx'
    }
    async function asyncPrint() {
      let result = await Promise.resolve('promise')
      console.log(result)
      result = await Promise.reject('失败了。。。')
      console.log(result)
    }
    asyncPrint()

    // 获取新闻内容
    async function getNews(url) {
      return new Promise((resolve, reject) => {
        $.ajax({
          method: 'GET',
          url, // 同名属性可以不写 等同于:url:url
          success: data => resolve(data),
          error: error => reject(false)
        })
      })
    }

    async function sendXml() {
      let result = await getNews('http://localhost:30001/news?id=7')
      console.log(result)
      if (!result) {
        alert('暂时没有评论内容')
        return
      }
      result = await getNews('http://localhost:3000' + result.commentsUrl)
      console.log(result)
    }
    sendXml()
</script>
  • 特点:

    1、不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行

    2、返回的总是Promise对象,可以用then方法进行下一步操作

    3、async取代Generator函数的星号,await取代Generator的yield

    4、语意上更为明确,使用简单,经临床验证,暂时没有任何副作用

Class

  1. 通过class定义类/实现类的继承
  2. 在类中通过constructor定义构造方法
  3. 通过new来创建类的实例
  4. 通过extends来实现类的继承
  5. 通过super调用父类的构造方法
  6. 重写从父类中继承的一般方法
  • 基本语法
<script type="text/javascript">
  // function Person(name, age) {
  //   this.name = name
  //   this.age = age
  // }
  // let person = new Person('yoliu', 21)
  // console.log(person)

  // 定义一个人物的类
  class Person {
    // 类的构造方法
    constructor(name, age) {
      this.name = name
      this.age = age
    }
    // 类的一般方法
    showName() {
      console.log(this.name)
    }
  }
  let person = new Person('yoliu', 21)
  console.log(person)
  person.showName()

  // 子类
  class StartPerson extends Person {
    constructor(name, age, salary) {
      super(name, age) // 调用父类的构造方法
      this.salary = salary
    }
    // 父类的方法重写
    showName() {
      console.log('调用子类的方法')
      console.log(this.name, this.age, this.salary)
    }
  }
  let p1 = new StartPerson('yoliu', 21, 88000)
  console.log(p1)
  p1.showName()
</script>

其他

字符串、数组的扩展

  • 字符串扩展
  1. includes(str) : 判断是否包含指定的字符串
  2. startsWith(str) : 判断是否以指定字符串开头
  3. endsWith(str) : 判断是否以指定字符串结尾
  4. repeat(count) : 重复指定次数
<script type="text/javascript">
  let str = 'asjdfkfjfmdls'
  console.log(str.includes('as'))
  console.log(str.startsWith('a'))
  console.log(str.endsWith('s'))
  console.log(str.repeat(3))
</script>
  • 数值扩展
  1. 二进制与八进制数值表示法: 二进制用0b, 八进制用0o
  2. Number.isFinite(i) : 判断是否是有限大的数
  3. Number.isNaN(i) : 判断是否是NaN
  4. Number.isInteger(i) : 判断是否是整数
  5. Number.parseInt(str) : 将字符串转换为对应的数值
  6. Math.trunc(i) : 直接去除小数部分
<script type="text/javascript">
  console.log(0b1010)   // 10
  console.log(0o56)   // 46
  console.log(Number.isFinite(Infinity))   // false

  console.log(Number.isNaN(NaN))

  console.log(Number.isInteger(123.12))   // false
  console.log(Number.isInteger(123.0))   // true

  console.log(Number.parseInt('123abc123')) // 123
  console.log(Number.parseInt('a123abc123')) // NaN

  console.log(Math.trunc(123.123))   // 123

</script>

数组扩展

  1. Array.from(v) : 将伪数组对象或可遍历对象转换为真数组

  2. Array.of(v1, v2, v3) : 将一系列值转换成数组

  3. find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素

  4. findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标

<script type="text/javascript">
    let btns = document.getElementsByTagName('button')
    Array.from(btns).forEach(function (item, index) {
      console.log(item)
    })

    let arr = Array.of(1, 4, 'abc', true)
    console.log(arr)

    let arr2 = [2, 3, 41, 5, 8, 95]
    let result = arr2.find(function (item, index) {
      return item > 4
    })
    console.log(result)   // 41

    result = arr2.findIndex(function (item, index) {
      return item > 4
    })
    console.log(result)   // 2
</script>

对象方法扩展

  1. Object.is(v1, v2) ,以字符串的形式来判断的
  • 判断2个数据是否完全相等
  1. Object.assign(target, source1, source2…)
  • 将源对象的属性复制到目标对象上
  1. 直接操作 proto 属性
<script type="text/javascript">
    console.log(0 == -0) // true
    console.log(NaN == NaN) // false NaN与任何数据都不相等
    console.log(Object.is(0, -0)) // false
    console.log(Object.is(NaN, NaN)) // true  因为字符串的NaN 和 NaN 相等

    let obj = {}
    let obj1 = {
      username: 'yoliu',
      age: 21
    }
    let obj2 = {
      sex: '女'
    }
    Object.assign(obj, obj1, obj2)
    console.log(obj)

    let obj3 = {}
    let obj4 = {
      qian: 88888888888
    }
    obj3.__proto__ = obj4
    console.log(obj3)
    console.log(obj3.qian)
</script>

拷贝

1、数据类型:
数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型

  • 基本数据类型:

    • 特点: 存储的是该对象的实际数据
  • 对象数据类型:

    • 特点: 存储的是该对象在栈中引用,真实的数据存放在堆内存里

2、复制数据

  • 基本数据类型存放的就是实际的数据,可直接复制
  • 克隆数据:对象/数组
    • 区别: 浅拷贝/深度拷贝
    • 判断: 拷贝是否产生了新的数据还是拷贝的是数据的引用
    • 知识点:对象数据存放的是对象在栈内存的引用,直接复制的是对象的引用
    • 常用的拷贝技术
      • arr.concat(): 数组浅拷贝
      • arr.slice(): 数组浅拷贝
      • JSON.parse(JSON.stringify(arr/obj)): 数组或对象深拷贝, 但不能处理函数数据
      • 浅拷贝包含函数数据的对象/数组
      • 深拷贝包含函数数据的对象/数组
  • 浅拷贝(对象/数组)特点:拷贝的引用,修改以后的数据会影响原数据
  • 深拷贝(深度克隆)特点:拷贝的时候生成新数据,修改拷贝以后的数据不会影响原数据

关于深浅拷贝的实例:

<script type="text/javascript">
    // // 不会影响原数据
    // let str1 = 'abcd'
    // let str2 = str1
    // console.log(str2) // abcd
    // str2 = ''
    // console.log(str1) // abcd
    // let bool1 = true
    // let bool2 = bool1
    // bool2 = false
    // console.log(bool1) //true



    // let obj = {
    //   username: 'yoliu',
    //   age: 21
    // }
    // let obj1 = obj
    // console.log(obj1)
    // obj1.username = 'sss'
    // console.log(obj.username)

    // // 拷贝数组/对象 没有生成新的数据而是复制了一份引用
    // let arr = [1, 4, {
    //   username: 'yoliu',
    //   age: 21
    // }]
    // let arr2 = arr
    // arr2[0] = 'abcd'
    // console.log(arr, arr2)

    /**
     * 拷贝数据:
     *    基本数据类型:    
            拷贝后会生成一份新的数据,修改拷贝后的数据不会影像原数据
          对象/数组:
            拷贝不会生成新数据,而是拷贝的是引用。修改拷贝以后的数据会影响原来的数据
        拷贝数据的方法:
          1. 直接赋值给一个变量    // 浅拷贝(浅克隆)
          2. Object.assign()   // 浅拷贝
          3. Array.prototype.concat()   // 浅拷贝
          4. Array.prototype.slice()    // 浅拷贝
          5. JSON.parse(JSON.stringfy()) // 深拷贝 但不能处理函数数据
     */    
     let obj = {username:'yoliu', age:21}
     let obj2 = Object.assign(obj)    
     console.log(obj2)
     obj.username = 'wade'
     console.log(obj)


     let arr = [1, 3, {username:'yoliu', age:21}]
     let testArr = [2, 4]
     let arr2 = arr.concat()
     console.log(arr2)
     arr2[1] = 'a'
     console.log(arr)
     arr2[2].username = 'a'
     console.log(arr)



     let arr3 = arr.slice()
     arr3[2].username = 'lll'
     console.log(arr)

     let arr4 = JSON.parse(JSON.stringify(arr))
     console.log(arr4)
     arr4[2].username = 'fkgfg'
     console.log(arr)
  </script>
  • 深度克隆
/* 
         思考:
          如何实现深度拷贝(克隆)
          拷贝数据里有对象/数组,
          拷贝的数据里不能有对象/数组,
          即使有对象/数组可以继续遍历对象/数组拿到每一项值,一直到拿到的是基本数据类型,
          然后在再去复制,就是深度拷贝
     */

    //  知识点储备
    /**
     * 如何判断数据类型:arr--->Array null ---> Null
     * 1. typeof 返回的数据类型:String、Number、Boolean、Undefined、Object、Function(null返回的是Object)
     * 2. Object.prototype.toString.call(obj)
     */
    let result = 'abcd'
    console.log(Object.prototype.toString.call(result))
    result = null
    console.log(Object.prototype.toString.call(result).slice(8, -1))
    result = [1, 3]
    console.log(Object.prototype.toString.call(result).slice(8, -1))

    // for in 循环 对象(属性名) 数组(下标)
    let obj = {
      username: 'yoliu',
      age: 21
    }
    for (let i in obj) {
      console.log(i)
    }
    let arr = [1, 3, 'abc']
    for (let i in arr) {
      console.log(i)
    }


    // 定义检测数据类型的功能函数
    function checkType(target) {
      return Object.prototype.toString.call(target).slice(8, -1)
    }
    // 实现深度克隆---> 对象/数组
    function clone(target) {
      // 判断拷贝的数据类型
      let result, targetType = checkType(target)
      if (targetType === 'Object') {
        result = {}
      } else if (targetType === 'Array') {
        result = []
      } else {
        return target
      }

      // 遍历目标数据
      for (let i in target) {
        // 获取遍历数据结构的每一项值
        let value = target[i]
        // 判断目标结构里的每一项值是否存在对象/数组
        if (checkType(value) === 'Object' || checkType(value) === 'Array') { // 说明对象/数组里又嵌套了对象/数组
          // 继续遍历获取到的value值
          result[i] = clone(value)
        } else { // 获取到的value值时基本数据类型或者是函数
          result[i] = value
        }
      }
      return result
    }
    let arr3 = [1, 2, {
      username: 'yoliu',
      age: 21
    }]
    let arr4 = clone(arr3)
    console.log(arr4)
    arr4[2].username = 'lili'
    console.log(arr3, arr4)

    let obj3 = {username:'kobe', age: 39} 
    let obj4 = clone(obj3)
    console.log(obj4)
    obj4.username = 'wade'
    console.log(obj3, obj4)

Set和Map容器

  • Set容器 : 无序不可重复的多个value的集合体
    • Set()
    • Set(array)
    • add(value)
    • delete(value)
    • has(value)
    • clear()
    • size
  • Map容器 : 无序的 key不重复的多个key-value的集合体
  • Map()
  • Map(array)
  • set(key, value)//添加
  • get(key)
  • delete(key)
  • has(key)
  • clear()
  • size
<script type="text/javascript">
    let set = new Set([1, 2, 4, 5, 2, 3, 6])
    console.log(set) // 1 2 4 5 3 6
    set.add(7)
    console.log(set.size, set)
    console.log(set.has(7))
    console.log(set.has(8))
    set.clear()
    console.log(set)

    let map = new Map([
      ['key', 'yoliu'],
      ['age', 21]
    ])
    console.log(map)
    map.set(78, 'haha') //添加
    console.log(map)
    map.delete('age')
    console.log(map)
</script>

for of 循环

for(let value of target){}循环遍历

  1. 遍历数组

  2. 遍历Set

  3. 遍历Map

  4. 遍历字符串

  5. 遍历伪数组

<script type="text/javascript">
    // 遍历数组实现去重
    let arr = [1, 2, 4, 5, 5, 6, 6, 2]
    let arr1 = arr
    arr = []
    let set = new Set(arr1)
    for (let i of set) {
      arr.push(i)
    }
    console.log(arr)
  </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值