ES6新特性(2015)【学习总结于记录】

ES6新特性(2015)

ES6的特性比较多,在ES5发布近6年(2009-11 至 2015-6)之后才将其标准化。两个版本之间时间跨度很多。
所以ES6中的特性比较多。
常用的:

类
模块化
箭头函数
函数参数默认值
模板字符串
解构赋值
延展操作符(展开操作符)
对象属性简写
Promise
Let与Const
Apply和Call
  1. 类(calss)

对熟悉Java,object-c,c#等纯面向对象语言的开发者来说,都会对class有一张特殊的情怀。ES6引入了class,让javascript的面向对象编程变得更加简单和易于理解。

class Animal{
  //构造函数,实例化的时候会被调用,如果不指定,那么会有一个不带参数的默认构造函数
  constructor(name,color){
    this.name = name;
    this.color = color;
  }
  //toString 是原型对象上的属性
  toString(){
    console.log('name:'+this.name+',color:'+this.color)
  }
}
var animal = new Animal('dog','white'); //实例化Animal
animal.toString();
console.log(animal.hasOwnProperty('name'));//true
console.log(animal.hasOwnProperty('toString'));//false
console.log(animal.__proto__.hasOwnProperty('toString'));//true
class Cat extends Animal{
  constructor(action){
    //子类必须要在constructor中指定super函数,否则在新建实例的时候会报错
    //如果没有置顶constructor,默认带super函数的constructor将会被添加
    super('cat','white');
    this.action = action;
  }
  toString(){
    console.log(super.toString());
  }
}
var cat = new Cat('catch');
cat.toString();
//实例cat是Cat和Animal的实例,和ES5完全一致。
console.log(cat instanceof Cat);//true
console.log(cat instanceof Animal);//true
  1. 模块化(Module)

ES5不支持原生的模块化,在ES6中模块作为重要的组成部分被添加进来。模块的功能主要由export和import组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过export来规定对外暴露的接口,通过import来引用其他模块提供的接口,同时还为模块创造了命名空间按,防止函数的命名冲突。
ES6允许在一个模块中使用export来导出多个变量或函数
(export)导出变量

//test.js
export var name = 'nick'

ES6将一个文件视为一个模块,上面的模块通过export向外输出了一个变量。一个模块也可以同时往外面输出多个变量。

//test.js
var name = "nick";
var age = "24";
export {name,age};

导出函数

//myModule.js
export function myModule(someArg){
  return someArg;
}

导入(import) 定义好模块的输出以后就可以在另外一个模块通过import引用。

import {myModule} from 'myModule';//main.js
import {name,age} from 'test';//test.js

一条import语句可以同时导入默认函数和其他变量 import defaultMethod,{otherMethod} from ‘xxx.js’

  1. 箭头函数(Arrow)

这是ES6中最激动的特性之一。=>不只是关键字function的简写,还带来了其他好处。箭头函数与包围它的代码共享一个this,能很好的解决this的指向问题。有经验的js开发都熟悉诸如var self=this或var that=this这种引用外围this的模式,但借助=>就不需要这种模式了。
复习一下this的认识:

  1. 在函数体外,this指向的就是window对象
  2. 在函数体内,谁调用函数this就指向谁
  3. 在构造函数中,this指向的是新创建的对象
  4. 在html标签中,this指的是当前的这个标签元素
  5. 在ES6中,对于箭头函数,要看它在哪里创建的,和当前函数的作用域

箭头函数的结构。
箭头函数的箭头=>之前是一个空括号,单个的参数名,或用括号起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用话括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)

//箭头函数的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
  alert("foo")
}
e=>{
  if(e==0){
    return 0;
  }
  return 1000/e;
}

不论是箭头函数还是bind,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么必须自己保存这个引用。

  1. 函数参数默认值

ES6支持在定义函数的时候为其设置默认值

function foo(height=50,color='red'){
  //todo
}

这样写一般没问题,但当参数的布尔值为false时,就会出问题了,比如,这样调用foo函数

foo(0,"")

因为0的布尔值为false,这样height的取值将是50,同理color的取值为’red’。
所以说,函数参数默认值不仅能是代码变得更加简洁而且能规避一些问题。

  1. 模板字符串

ES6支持模板字符串,是的字符串的拼接更加简洁,直观
不使用模板字符串

var name = 'your name is '+first+' '+last+'.'

使用模板字符串

var name = `your name is ${first} ${last}.`

在ES6中通过${}就可以完成字符串的拼接,只需要将变量放在大括号之中。

  1. 解构赋值

解构赋值语法是js的一种表达式,可以方便的从数组或者对象中快速提取值赋给定义的变量。
从数组中获取值并赋值到变量中,变量的顺序与数组中对象顺序对应。

var foo = ['one','two','three','four'];
var [one,two,three] = foo;
console.log(one);//'one'
console.log(two);//'two'
console.log(three);//'three'
//如果想要忽略某些值,可以按照下面的写法获取想要的值
var [first,,,last] = foo;
console.log(first);//'one'
console.log(last);//'four'
//也可以这样写
var a,b;//先声明变量
[a,b]=[1,2];
console.log(a);//1
console.log(b);//2

如果没有从数组中的获取到值,可以为变量设置一个默认值

var a,b;
[a=5,b=7]=[1];
console.log(a);//1
console.log(b);//7

通过解构赋值可以方便的交换两个变量的值

var a=1;
var b=3;
[a,b]=[b,a];
console.log(a);//3
console.log(b);//1

获取对象中的值

const student={
  name:'nick',
  age:'18',
  city:'wuhan'
}
const {name,age,city}=student;
console.log(name);//"nick"
console.log(age);//"18"
console.log(city);//"wuhan"
  1. 延展操作符(Spread operator)

延展操作符 … 可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开,还可以构造对象时,将对象表达式按key-value的方式展开。
函数调用:

myFunction(...iterableObj);

数组构造或字符串

[...iterableObj,'4',...'hello',6];

构造对象时,进行克隆或者属性拷贝(ECMAScript2018规范新增特性)

let objClone={...obj};

应用场景
在函数调用时使用延展操作符

function sum(x,y,z){
  return x+y+z;
}
const numbers=[1,2,3];
//不使用延展操作符
console.log(sum.apply(null,numbers));
//使用延展操作符
console.log(sum(...numbers));//6

构造数组
没有展开语法的时候,只能组合使用push,splice,concat等方法,来将已有数组元素变成新数组的一部分。有了展开语法构造新数组会变得简单,更优雅:

const stuendts=['jam','tom'];
const persons=['tony',...stuendts,'anna','jack'];
console.log(persons);//['tony','jam','tom','anna','jack']

和参数列表展开类似,…在构造数组时,可以在任意位置多次使用。
数组拷贝

var arr=[1,2,3];
var arr2=[...arr];//等同于arr.slice()
arr2.push(4);
console.log(arr2);//[1,2,3,4]

展开语法和Object.assign()行为一致,执行的都是浅拷贝(只遍历一层)
连接多个数组

var arr1=[0,1,2];
var arr2=[3,4,5];
var arr3=[...arr1,...arr2];//将arr2中所有元素附加到arr1后面并返回
//等同于
var arr4=arr1.concat(arr2);

在ECMAScript2018延展操作符增加了对对象的支持

var obj1={foo:'bar',x:42};
var obj2={foo:'baz',y:13};
var cloneObj={...obj1};
//克隆后的对象:{foo:'bar',x:42}
var mergeObj={...obj1,...obj2};
//合并后的对象{foo:'baz',x:42,y:13}

在react中应用
通常在封装一个组件时,会对外公开一些props用于实现功能,大部分情况下在外部使用都应显示的传递props。但是当传递大量的props时,会非常繁琐,这时可以使用…(延展操作符,用于取出参数对象的所有可遍历属性)来进行传递。
一般情况下如下写:

<CustomComponent name='jam' age={21} />

使用…等同于上面的写法

const params={
  name:'jam',
  age:21
}
<CustomComponent {...params} />

配合结构赋值避免传入一些不需要的参数

var params={
  name:'123',
  title:'456',
  type:'aaa'
}
var {type,...other}=params;
<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />
  1. 对象属性简写

在ES6中允许在设置一个对象的属性的时候不指定属性名。
不使用ES6

const name="jack",age=18,city="wuhan";
const student={
  name:name,
  age:age,
  city:city
}
console.log(student);//{name:"jack",age:18,city:"wuhan"}

对象中必须包含属性和值,显得非常冗余
使用ES6

const name="jack",age=18,city="wuhan";
const student={
  name,
  age,
  city
}
console.log(student);//{name:"jack",age:18,city:"wuhan"}

对象中直接写变量,非常简洁。

  1. Promise

promise是异步编程的一种解决方案,比传统的解决方案callback更加优雅,它最早由社区提出和实现的,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象
不使用ES6 嵌套两个setTimeout回调函数

setTimeout(function(){
  console.log('hello');//1秒后输出"hello"
  setTimeout(function(){
    console.log("hi");//2秒后输出"hi"
  },1000)
},1000)

使用ES6

var waitSecond=new Promise(function(resolve,reject){
  setTimeout(resolve,1000);
})
waitSecond.then(function(){
  console.log("hello") //1秒后输出"hello"
  return waitSecond;
}).then(function(){
  console.log("hi") //2秒后输出"hi"
})

上面的代码使用两个then来进行异步编程串行化,避免了回调地狱。

  1. 支持let与const

在之前js是没有块级作用域的,const与let填补了这方面的空白,const与let都是块级作用域
使用var定义的变量为函数级作用域

{
  var a=10;
}
console.log(a);//10

使用let与const定义的变量为块级作用域

{
  let a=10
}
console.log(a);//-1 or Error a is not defined

let块级作用域变量
–没有变量的提升,必须先声明后使用
–let声明的变量,不能与前面let,var,const声明的变量重名
const定义只读变量
–const声明变量的同时必须赋值,const声明的变量必须初始化,一旦初始化完毕不允许修改
–const声明变量也是一个块级作用域变量
–const声明的变量没有变量的提升。必须先声明后使用
–const声明的变量,不能与前面let,var,const声明的变量重名

  1. apply和call

apply和call都是对象本身没有某个属性或者方法,去引用其他对象的属性或方法,也就是说两者都可以改变this的属性。
不同之处
apply(this的指向,数组/arguments)
call(this的指向,参数1,参数2,参数3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值