es6新增特性总结

1.let和const关键字

var/let/const的共同点:在函数内部都可以访问到在外部通过var/let/const声明的变量或常量。

let:

变量不能重复声明。

let a = 1;
let a = 2;
//报错:Uncaught SyntaxError: Identifier ‘a’ has already been declared

块级作用域。在if-else语句、while循环、for循环中使用了let声明的变量,都会产生块级作用域。

let flag = true
 if(flag){
    var a = 11
}
console.log(a) //11
//而把var换成let后就报错
let flag = true
 if(flag){
    let a = 11
}
console.log(a) //Uncaught ReferenceError: a is not defined

没有变量提升,必须先定义才能使用。 变量提升:在代码执行前,会先收集通过var声明的变量,把这些变量提到作用域的最顶端,而赋值操作不变。
let声明的变量是独立的,不能被window调用。

let a = 10
console.log(window.a) //undefined
var b = 10
console.log(window.b) //10

let doSth = function(){
      console.log('123');
}
window.doSth()//ncaught TypeError: window.doSth is not a function

var doSth = function(){
      console.log('123');
}
window.doSth()//123
//不会影响作用域链
{
    let a = 10
    function fun(){
        console.log(a)//10
    }
    fun()
}

const:

初始化常量,必须给初始值,否则报错(Uncaught SyntaxError: Missing initializer in const declaration)。
在同一个作用域内,const定义的常量不能修改其值。在同一个作用域内,const定义的常量不能重复声明。但是在不同的作用域,用const声明一样的变量没问题。另外,如果const声明的变量是个引用数据类型,比如对象,那么对对象进行修改的时候,不会报错。

const a = 10
a = 100 // Uncaught TypeError: Assignment to constant variable.
//const定义的常量不能重复声明
const a = 10
const a = 100//Uncaught SyntaxError: Identifier 'a' has already been declared

但是在不同的作用域,用const声明一样的常量没问题。

const a = 100
function fn(){
     const a = 200
     console.log(a)//200
}
fn()

如果const声明的变量是个引用数据类型,比如对象,那么对对象进行修改的时候,不会报错

const obj = {
     name:'yy'
}
obj.name = 'gg'
console.log(obj)

没有变量提升。
具有块级作用域。
const声明的常量也是独立的,不能被window调用

const a = 10
console.log(window.a)

const声明的数组和对象,对其修改不会报错

const arr = [1,2,3,4]
arr.push(5)
console.log(arr)// [1,2,3,4,5]

2.解构赋值

//对象的解构赋值
const obj = {
        name:'yy',
        age:18,
        sayHello:function(){
            console.log('你好')
        }
    }
let {name,age,sayHello} = obj
sayHello() //'你好'

//还有数组的解构赋值,用的少就不细说了

3.箭头函数

//声明函数
let add1 = (a) =>{
    console.log(a*2)
}
//调用函数
add1(3)//6

//箭头函数与普通函数的区别
//1.this是静态的,this始终指向函数声明时所属的那个作用域。普通函数中的this与调用它的对象有关。
window.name = '杨洋'
let getName = () =>{
    console.log(this.name)
}
getName() //杨洋
const obj = {
    name:'李易峰'
}
//通过call方法看能不能改变this的指向?不能
getName.call(obj)//杨洋

//2.箭头函数不能作为构造函数去使用
let Person = (name,age) =>{
        this.name = name
        this.age = age
    }
let person = new Person('杨洋',18)
console.log(person)//Uncaught TypeError: Person is not a constructor

//3.不能使用arguments
let person = (name,age) =>{
    console.log(arguments) //Uncaught ReferenceError: arguments is not defined
}
person('杨洋',18)

//4.可以简写
let person = name =>{ //只有一个参数的时候可以不用写括号
    console.log(name)//杨洋
}
person('杨洋')
//代码体只有一行的时候省去花括号
let person = name => console.log(name) //杨洋
person('杨洋')

4.模板字符串:使用反引号``代替双引号创建字符串

const name='小刘',age='18'
console.log(`我是新来的同学${name},今年${age}岁。`)

let num = Math.round('12.339')
console.log(`${num}`)

//模板字符串可以再嵌套模板字符串
const arr = [
       {title:'响应式布局'},
       {title:'Vue'},
       {title:'React'},
]
      
function template(){ //模板字符串可以再嵌套模板字符串
       return `<ul>
              ${arr.map(item=>`<li>${item.title}</li>`).join('')}
        </ul>`
}
document.body.innerHTML = template()

5.标签模板

       let name = '杨洋'
       let age = 18
       console.log(tag`我是${name},今年${age}岁。`)//如果在模板字符串前面加个标签
       function tag(strings,...args){ //strings:数组,数组元素是模板字符串中${}前后的元素截取出来的  args:${}内的变量组成的数组
            // console.log(strings)
            console.log(args)
       }
    //有个细节,strings的数组长度大于变量的个数
//标签模板实例
       const arr = [
           {title:'bootstrap框架',author:'杨老师'},
           {title:'Vue框架',author:'李老师'},
           {title:'React框架',author:'盛老师'},
       ]

       function template(){
           return `<ul>
                ${arr.map(item=>{
                    return links`<li>作者:${item.author},课程:${item.title}</li>`
                }).join('')}
           </ul>`
       }
       function links(strings,...args){
            return strings.map((str,key)=>{
                return str + (args[key]?args[key].replace('框架',"<a href='https://www.baidu.com'>框架</a>"):'')
            }).join('')
       }
       document.body.innerHTML = template()

6.扩展运算符

//扩展运算符能将数组转为逗号分割的参数列表:[1,2,3] =>  1,2,3

            //扩展运算符的使用:  
            //数组克隆
            const fruits = ['苹果','梨','橘子']
            const newFruits = [...fruits]
            console.log(newFruits)//['苹果','梨','橘子']
            const num = [{a:1},{b:2},{c:3}]
            const newNum = [...num]// 扩展运算符拷贝数组,如果数组中有引用类型的数据,则是浅拷贝。如果改变克隆数组某元素的值,原数组的值也会改变,要注意
            console.log(newNum)//[{a:1},{b:2},{c:3}]
            const newNum1 = JSON.parse(JSON.stringify(newNum))//深拷贝一份
            newNum1[0].a = 11
            console.log(num)//原数组就不会被改变了

            //数组合并
            const flowers1 = ['月季','玫瑰']
            const flowers2 = ['牡丹','菊花']
            const newFlowers = [...flowers1,...flowers2]
            console.log(newFlowers)

            //将伪数组转为真正的数组
            let items = document.querySelectorAll('.item')
            let newItems = [...items]
            console.log(newItems)//转成真正的数组后就能使用forEach()

7.新增了一些字符串和数组方法


//7.1 新增的字符串方法
const str = '我们都有一个家'
console.log(str.includes('一')) //true
console.log(str.startsWith('我们')) //false,判断某个字符串是否在原字符串的头部
console.log(str.endsWith('家')) //true,判断某个字符串是否在原字符串的尾部
//7.2 新增的数组方法
const arr = [4,9,16,25]

//7.2.1 includes方法(es7新增的方法)
console.log(arr.includes(9)) //true
//注意,数组元素是引用类型的时候,使用includes()无法查找。
const arr = [{name:'yy'},{name:'uu'},{name:'jj'}]
console.log(arr.includes({name:'uu'}))//false

//7.2.2 map()方法:得到一个经过处理后的新数组
let newArr = []
arr.map(item=>{
        newArr.push(Math.sqrt(item))
    })
console.log(newArr)//[2,3,4,5]

//7.2.3 filter()方法:过滤操作,得到想要的结果
let newArr1 = arr.filter(item=>{
    return item > 10
})
console.log(newArr1)

//7.2.4 reduce(prev,current,index,arr)
let total = arr.reduce((prev,current)=>{ //求和
    return prev + current
})
console.log(total)

const arr1 = [[1,2],[3],[4,6]]
let newArr2 = arr1.reduce((prev,current)=>{ //二维数组变成一维数组(数组扁平化)
    return prev.concat(current)
})
console.log(newArr2)

const arr2 = [1,2,[3,4,[5,6]],7,8]
function flatten(arr){
        let newArr = arr.reduce((pre,cur)=>{ //多维数组变为一维数组(数组扁平化)
              return pre.concat(Array.isArray(cur)?flatten(cur):cur)
        },[])
        return newArr
}
console.log(flatten(arr2))

//需求:把“我正在学习php和css”中的php和css替换成超链接
 const arr = ['php','css']
const str = '我正在学习php和css'
let replaceStr = arr.reduce((pre,cur)=>{
     return pre.replace(cur,`<a href='javascript:;'>${cur}</a>`)
},str)
document.body.innerHTML  = replaceStr

//7.2.5 some(callback):检查数组中的每个元素是否符合条件,只要有一个满足条件就返回true,都不满足返回false
const ageArr = [16,17,18,19,20]
console.log(ageArr.some(item=>item>17))

//7.2.6 Array.from(new Set(arr)):数组去重
const arr3 = [1,1,2,3,4,5,5,5,6]
console.log(Array.from(new Set(arr3))) //[1,2,3,4,5,6]
//数组去重的其它方法:利用reduce()或者Object.keys(obj)
let arr31 = arr3.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
        return pre.concat(cur)
    }else{
        return pre
    }
},[])
console.log(arr31)//[1,2,3,4,5,6]

let obj = {}
arr3.forEach(item=>{
    obj[item] = 1
})
let newArr32 = Object.keys(obj).map(item=>{
    return Number(item)
})
console.log(newArr32)//[1,2,3,4,5,6]

//7.2.7 find()和findIndex()
 const arr = [{name:'yy'},{name:'uu'},{name:'jj'}]
    let res = arr.find(item=>{ //查找数组中符合回调函数要求的第一个数组元素。意思就是:如果有多个元素元素都符合此要求,只返回符合的第一个
      return item.name === 'uu'
    })
    console.log(res)

    let index = arr.findIndex(item=>{ //查找数组中的指定元素的索引值
      return item.name === 'uu'
    })
    console.log(index)//1

    const Arr=[1,2,3,4];
    var num = Arr.find(function(value){
      return value > 2
    })
    console.log(num)

    const Arr1 = [1,2,3,4];
    var num1 = Arr1.findIndex(function(value){
      return value > 2
    })
    console.log(num1)//2
    //rest参数:...args,es6中引入这个参数获取多余的实参,代替es5中的arguments。

	function sum(){
	    console.log(arguments)
	}
	sum(1,2,3)//结果不是个数组
	
	function sum1(...args){
	    console.log(args)
	}
	sum1(1,2,3)//[1,2,3]
	
	function multiple(a,...args){
	     return args.map(item=>{
	          return a * item
	   })
	}
	let result = multiple(3,4,5,6,7)
	console.log(result)//[12,15,18,21]
	
	//rest参数必须放到最后
	function sum(a,b,...args){
	    console.log(a,b,args)
	}
	sum(1,2,3,4,5,6,7)//1 2  [3, 4, 5, 6, 7]

8.Symbol

Symbol是es6引入的新的原始数据类型,是js的第七种数据类型,是类似于字符串的数据类型。

在对象中,凡是属性名属于Symbol类型的,这个属性就是独一无二的,在对象中就不会产生命名冲突的问题。

Symbol不能用于和其它数据类型运算。
Symbol定义的对象不能用for…in获取对象属性,但是可以使用Reflect.ownKeys获取对象的所有属性名。

//创建Symbol
let s = Symbol()
console.log(typeof s)//symbol
//创建Symbol时,可以给Symbol函数传递参数,表示对Symbol实例的描述,容易区分不同的Symbol值。
let s1 = Symbol('哈哈')
let s2 = Symbol('哈哈')
console.log(s1)//Symbol(哈哈)
//注意:Symbol函数的参数只是对当前Symbol值的描述,两个参数一致的Symbol函数,它们的返回值是不相等的
console.log(s1 === s2)//false
//Symbol函数的参数是个对象,会自动调用对象的toString()方法
const obj = {
    toString() {
        return 222
    }
};
let sym = Symbol(obj);
console.log(sym) //Symbol(222)

var fruits = {
        type1:'苹果',
        type2:'橘子', 
}
    //我想把otherFruits对象中的两个属性添加到fruits对象中去,但是我不确定fruits对象是否已经有了这两个属性
    //所以,我把otherFruits对象中的两个属性的属性值设置成Symbol对象,即独一无二的,这样可以避免把fruits对象中的属性给覆盖掉
    let mySymbol1 = Symbol()
    let mySymbol2 = Symbol()
    let otherFruits = {
        type1:mySymbol1,
        type2:mySymbol2
    }
    fruits[otherFruits.type1] = '哈密瓜'
    fruits[otherFruits.type2] = '红柚'
    //但是这添加的Symbol属性,怎么输出呢?
    console.log(fruits[mySymbol1],fruits[mySymbol2])//哈密瓜  红柚


//Symbol.for创建
let s3 = Symbol.for('哈哈')
console.log(typeof s3)//symbol

//Symbol的内置属性

9.迭代器(Iterator)

迭代器:一种数据接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就能实现遍历操作。

es6创建了一种新的遍历方式for…of循环,迭代器使用for…of循环就能进行遍历操作。

原生具备迭代器接口的数据结构有Array、Arguments、Set、Map、String、TypedArray、NodeList

迭代器工作原理:
(1)创建一个指针对象,指向当前数据结构的起始位置。这个对象是由Symbol(Symbol.iterator)这个函数创建
(2)第一次调用对象的next方法,指针自动指向第一个数据成员
(3)接下来不断调用next方法,指针一直往后移动,直至到最后一个成员
(4)每调用一次next方法,都会返回一个包含value和done的对象

     
	const arr = [1,2,3,4]
	//创建指针对象
	let iterator = arr[Symbol.iterator]()
	//调用对象的next方法
	console.log(iterator.next())
	console.log(iterator.next())
	console.log(iterator.next())
	console.log(iterator.next())
	console.log(iterator.next())

10.生成器

生成器就是一个特殊的函数,异步编程一种新的解决方案。

11.Promise承诺

1.把本来异步的代码写成同步的形式
2.链式调用的原理,每调用一个方法这个方法都会返回一个promise

var pro = new Promise((resolve, reject) => {
      setTimeout(() => {
        const num = prompt() //方法用于显示可提示用户进行输入的对话框
        if (num > 10) {
          resolve()
        } else {
          reject()
        }
      }, 3000)
    })
 pro.then(() => {
      // 写成果兑现的时候具体要做的事情
      console.log('承诺兑现,你真棒')
    }).catch(() => {
      // 写承诺失败要做的具体事情
      console.log('承诺失败,你真菜')
    }).finally(() => {
      console.log('不管承诺成功与否我都会出来')
    })
  • 15
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值