es6新特性

108 阅读3分钟

let

1、let定义变量的方式

   // 1、 错误的方式
    console.log(a)
    let a = 1
    

2、 let定义的变量所在的范围会形成作用域

    if (true) {
        // var定义的变量在它所在的范围没有形成作用域
        // var a = 1

        // var定义的变量在它所在的范围形成作用域
        let a = 1
    }

    console.log(a)

3、

    let arr = [1, 2, 3, 4, 5]
    for (let i = 0; i < arr.length; i++) {
        console.log(i)
    }


    let arr = []
    for (let i = 0; i < 3; i++) {
        arr[i] = function() {
            console.log(i)
        }
    }

    arr[0]()
    arr[1]()
    arr[2]()

4、let定义的变量的值是可以修改的

    let a = 1
    a = 2
    console.log(a);
    

const

使用const声明的变量不能修改

  const myName = 'zs'
   myName = 'ls'

注意:使用const声明变量的同时需要初始化

   const myName = '';

使用const声明的变量如果指是对象,那么修改对象中的属性的值是允许的

  const myObj = {
age:18
}

     myObj.age = 20

不能重新指向新的对象

   myObj = {
       age:18
    }
    

数组解构:简化对数组元素提取的操作

1、根据数组下标获取数据

   const arr = [100, 200, 300]
    const foo = arr[0]
    const bar = arr[1]
    const baz = arr[2]

2、基本的解构方式

    const [foo,bar,baz] = arr
     console.log(foo,bar,baz)

3、提取数组中的最后一个元素

    // const [,,baz] = arr
    // console.log(baz);

4、剩余运算符 ...

需求:第一个元素单独提取,剩下的元素打包提取

注意:剩余运算符声明的变量只能放在最后!!!!

     const [foo,...rest] = arr
    console.log(foo);
     console.log(rest);

5、

     const [foo] =arr
     console.log(foo);

6、默认解构

   const [foo,bar,baz=456,more=123] = arr
     console.log(more,baz);

需求:获取一个路径字符串中的最后一个目录,输出baz

    // 1、按照指定的字符切割字符串得到数组

    // 2、解构数组

    // 3、输出结果 
    const path = "foo/bar/baz"
    var arr = path.split('/')
    const [, , baz] = arr
    console.log(arr)

对象解构

    const obj = {
        myName: 'zs',
        age: 18,
        getAge: function() {
            return this.age
        }
    }

1、 对象解构基本方式

    const {
        myName: myNameVal
    } = obj

    console.log(myNameVal);

2、 解构默认值

    const {
        myName: myNameVal = 'jack'
    } = obj

    console.log(myNameVal);

3、

    const {
        getAge: getAgeFunc
    } = obj
    const age = getAgeFunc()
    console.log(age);



    const {
        getAge
    } = obj
    const age = getAge()
    console.log(age);
    

模板字符串

1、 普通字符串

    const str = "学习es6,很强大"
    const str = "学习es6,\n很强大"

2、 模版字符串

   // 允许换行
    const str = `学习es6,
                很强大`
    const str = `学习es6,很强大`

    //可以使用插值表达式, 重点掌握!!! $ {}
    let lang = 'javascript'
    const str = `学习${lang},很强大,${1+1+1},${Math.random()},${lang?1:0}`

模版字符串标签函数

const str = console.log`hello javascript`


function myTagFunc(strings,myName,gender){
console.log(strings)
console.log(myName);
console.log(gender);

const sex = gender==='female' ? '女' :'男'
const newStr = strings[0] + myName + strings[1] + sex + strings[2]

return newStr
}

模版字符串标签函数

  const myName = "zs"
  const gender = "female"

 const str = myTagFunc`hi,${myName} is a ${gender}`
  console.log(str);
  

操作字符串的扩展方法

startsWith\endsWith\includes

 const str = 'Error: foo is not defined.'

需求:判断str是否以Error开头

    console.log(str.startsWith("Error"))

需求:判断str是否以.结尾

  console.log(str.endsWith('.'))

需求:判断str是否包含foo

       console.log(str.includes("foo1"))

函数参数默认值

注意:含默认的参数,只能放在最后

function foo(bar,enable=""){
console.log(bar);
console.log(enable);

// 第一种防止函数内部出错的方式,也叫增强代码健壮性
 let str
 if(enable){
    // 把字符串全部转成大写
    str = enable.toUpperCase()
 }

// 第二种方式,给函数参数提供默认值
const str = enable.toUpperCase()

console.log(str)
console.log('foo函数执行了')
}

 // foo("bar","enable")

  foo("bar")

函数剩余参数

注意:剩余参数智能放在参数列表的最后一个位置

function fun(n,...args){
console.log(n)
console.log(args)


}

 fun(1,2,3,4,5)
 fun(1,2,3)
fun(2,3,4,5,6,9,0)

展开/延展操作符

// 展开数组
const arr = ['foo', 'bar', 'baz']
console.log.apply(console, arr)
    // 展开的数据
console.log(...arr)
const newArr = [...arr]
console.log(newArr)

箭头函数

函数的基本定义方式

    function plus(a) {
        return a + 1
    }

基本定义方式

    const plus = (a) => {
        console.log(this)
        return a + 1
    }

    const res = plus(1)
    console.log(res)

    // 注意:
    // 1、 箭头函数中没有this
    plus(1)

    // 2、 箭头函数简写
    // 2.1、 只有一个参数的时候才能省略括号
    const plus = a => {
        return a + 1
    }

    const plus = (a, b) => {
        return a + b
    }

    // 2.2、 函数体中的代码之后一行的时候, 可以吧 {} 和return去掉
    const plus = a => a + 1

    const plus = a => {
        console.log('plus invoke')
        return a + 1
    }


    console.log(plus(1));

案例:

    // 1、 箭头函数中更没有this
    setTimeout(() => {
        console.log(this)
        console.log(1)
    }, 1000)

    const person = {
        myName: 'javascript',
        getMyName: function() {
            console.log(this)
            setTimeout(() => {
                console.log(`hi,myName is ${this.myName}`)
            }, 1000)
        }
    }

    person.getMyName()

    // 2、作为回调函数,在异步编程中使用
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

需求:过滤出数值中的偶数

1、判断偶数是 对2取余 %

    arr.filter(function(item) {
        let res
        if (item % 2 === 0) {
            res = item
        }
        return res
    })

2、案例用箭头函数简写

    const newArr = arr.filter(item => item % 2 === 0)
    console.log(newArr)

对象字面量增强

对象中属性与方法的简洁表示法

1.对象字面量是什么?创建对象的一种方式

    const person={ name:‘zhangsan’, age:34 }

2.属性的简洁表达式==>键名和变量或常量名一样的时候,可以只写一个

const age=23;
const person={ name:‘zhangsan’, // age:age, //这里可以简写 age }
console.log(person)

3.方法的简洁表示法==>方法可以省略冒号和function 关键字

const person={
 // speak:function(){
 } speak(){
 console.log(‘这是方法的简写形式’)
        }
 }
 person.speak();//方法的调用

对象中[]方括号语法

1.方括号语法的用法

    const prop=‘age’;
    const person={}; //之前的写法
    person[prop]=23;//将age属性添加到了person对象中
    console.log(person)//{age:23}

2.增强以后:方括号语法可以写到对象字面量中

    const prop=‘age’;
    const person={
    [prop]:12//prop为一个变量
 }
    console.log(person);//{age:23}

3.方括号中可以放什么

${} 模板字符串

      [值或通过计算可以得到值得(表达式)]
    const attr=‘age’;
    const func=()=>‘age2’;
    const people={
    [prop]:23,//[] 里面可以是常量
    [func()]:45,//[] 可以是一个计算的结果
    [‘sex’+‘3’]:34//[]里面也可以是 字符串拼接
 }
    console.log(people);

4.方括号语法和点语法的区别

点语法是方括号语法的特殊形式, 当我们的属性名为合法标识符的时候 可以使用点语法,特殊的属性名 需要使用方括号语法。

对象赋值 Object.assign()

面试题or笔试题:描述深浅拷贝,举例子说明

1.浅拷贝和深拷贝都能创建出一个新的对象,

但浅拷贝在复制引用类型时,只复制引用地址,新旧对象还是共享同一块内存,修改对象属性会影响原对象;

而深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象

2.浅拷贝常见方法

 Object.assign()

  扩展运算符

 Array.concat()

   Array.slice()

3.深拷贝常见方法

      _.cloneDeep()

      JSON.stringify()

  手写递归方法

案例

  const source1 = {
        a: 123,
        b: 123
    }

    const source2 = {
        b: 678,
        d: 789
    }

    const target = {
        a: 456,
        c: 789
    }

过程

       const source1 = {
        a: 123,
        b: 678,
        d: 789
    }

    const target = {
        c: 789,

        a: 123,
        b: 678,
        d: 789
    }

1、过程

2、函数最终的值是存放target,并且会返回target对象

3、浅拷贝 newObj和target是同一个对象

     const newObj = Object.assign(target, source1, source2)
    console.log(newObj);
    console.log(newObj === target)

    // 深拷贝、 浅拷贝
    const obj = {
            myName: 'zs',
            age: 18
        }

浅拷贝

    const newObj = obj
    newObj.myName = 'lis'
    console.log(obj);
    console.log(newObj);

    // 复制对象, 修改新对象的值, 不影响就对象的值
    const newObj = Object.assign({}, obj)
    newObj.myName = 'aaa'
    console.log(obj);

    // 注意:!!!!!!!
    // 生成一个新的对象

    function fun(obj) {
        // todo
        console.log(obj)
        obj.myName = 'lisi'
        return obj
    }

    const oldObj = {
        myName: 'zs'
    }

    const newObj = fun(oldObj)
    console.log(newObj);
    console.log(oldObj);

应用:简化对象参数接收

    function Block(options) {
        console.log(this)
            // this.width = options.width
            // this.height = options.height
            // this.x = options.x
            // this.y = options.y

        this.z = 10

        return Object.assign(this, options)
    }

    const block1 = new Block({
        width: 100,
        height: 200,
        x: 50,
        y: 50
    })
    console.log(block1)

判断值是否相等

console.log(0 === false)

console.log(+0 === -0)
console.log(NaN === NaN)

console.log('-------------------------')

// object.is
console.log(Object.is(+0, -0));
console.log(Object.is(NaN, NaN));

class关键字定义类

原来定义类的方式
      function Person(name, age) {
        this.myName = name
        this.age = age
    }

    Person.prototype.sayHi = function() {
        console.log(`hi,myName is ${myName}`)
    }


    const p1 = new Person("zs", 18)
    p1.sayHi()
class关键字定义类
    class Person {
        constructor(name, age) {
            this.myName = name
            this.age = age
        }

        sayHi = function() {
            console.log(`hi,myName is ${this.myName}`)
        }

        // 静态成员/方法
        static create(name, age) {
            const p = new Person(name, age)
            return p
        }
    }

    // const p1 = new Person("zs",18)
    // p1.sayHi()

    const p1 = Person.create("lisi", 25)
    p1.sayHi()
    

extends

继承

    class Person{
constructor(name,age) {
    this.myName = name
    this.age = age
}
sayHi = function (){
    console.log('sayHi()')
       }
}

class Student extends Person{
constructor(name,age,number) {
    super(name,age) // super可以理解为父类构造函数
    this.number = number
}
}

const s1 = new Student("tom",20,101010)
console.log(s1);

set

Set数据结构
    const s = new Set()
1、 添加数据
    const res = s.add(1)
    console.log(res)
链式调用
    s.add(1).add(2).add(3).add(4).add(5)
    console.log(s)
2、 获取数据

2.1、 forEach()

    s.forEach(i => console.log(i))

2.2、for..of

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

3、 获取Set中存储的数据的个数

    console.log(s.size)

4、 判断指定的数是否在Set数据结构中

    console.log(s.has(3))

5、 删除指定的数据

    console.log(s.delete(5)); // s.delete()返回值表示删除是否成功

6、 清空Set数据

    s.clear()
    console.log(s);

7、 特性: Set中保存的数据是不能重复的。 如果给他重复的数据, Set会自动把重复的数据给删除

需求: 把一个数组中的重复的元素给删除(数组去重)
    const arr = [1, 3, 4, 6, 2, 4, 7, 5, 8]

    const s = new Set(arr)
    const newArr = Array.from(s)
    console.log(newArr);

    // 简化
    const newArr = Array.from(new Set(arr))

    // 简化: 使用延展操作符
    const newArr = [...new Set(arr)]
    console.log(newArr);

map

Map数据结构
const map = new Map()

新增数据

    map.set("myName","zs")

获取数据

   console.log(map.get("myName"));

根据key判断是否存在

   console.log(map.has("myName"));

删除

        delete()

清空

    clear()

key使用变量的方式来进行增、删除、清空

遍历map中的数据

   map.forEach((value,key)=>{
console.log(value,key)
 })
 
 

_for_of...

for...of 遍历获取数据

1、遍历数组

    const arr = [100, 200, 300]
    for (let item of arr) {
        console.log(item)
    }

2、遍历Set

3、遍历Map

    const m = new Map()
    m.set('foo', 1)
    m.set('bar', 2)

    for (let [key, value] of m) {
        console.log(key + ":" + value)
    }

4、注意:for...of 不能遍历对象

    const obj = {
        myName: 'sz',
        age: 18
    }

    for (let item of obj) {
        console.log(item)
    }

5、

  • Object.keys() 获取对象中的所有的key

  • Object.values() 获取对象中的所有的value

  • Object.entries() 获取对象中的所有键值对

     const obj = {
         myName: 'ZS',
         age: 18
     }
    
     const res = Object.keys(obj)
     console.log(res);
    
     const res = Object.values(obj)
     console.log(res)
    
     const res = Object.entries(obj)
     console.log(res)
    
     for (let key of Object.keys(obj)) {
         console.log(key)
     }
    
     // 遍历对象中的所有值
    
     // 遍历对象中的所有的键值对,并输出
     
    

es7新特性

es2016新内容

    const arr = [1, true, NaN, 23, "hello"]

indexOf 判断某个元素是否在数组中,返回这个元素在数组中的索引;如果元素不在数组中,返回-1

    console.log(arr.indexOf(true));
    console.log(arr.indexOf(null));
    console.log(arr.indexOf(NaN)); // 陷阱 -1

includes 判断数组是否包含指定的元素

    console.log(arr.includes(1));
    console.log(arr.includes(NaN)); //true

指数运算符 **

  • 需求:计算2的3次方

      console.log(Math.pow(2, 3));
      console.log(2 ** 3);