###函数和对象的扩展
####函数的扩展
es6支持函数的参数设置默认值,但是这些参数必须位于函数的尾部,并且参数的变量是默认声明的,因此不能用let/const再次声明
~~~
function func(x,y=5){
console.log(y); //5
let y=3; //error
}
~~~
扩展运算符,用于将数组(伪数组)展开成参数序列
~~~
console.log(...[1,2,3]); //1 2 3
[...document.getElementsByTagName("div")]; //[[object HTMLDivElement],[object HTMLDivElement],[object HTMLDivElement]]
~~~
扩展运算符有很多应用场景,这里列举三个
1. 数组合并
~~~
[1,2,3].concat([4,5,6]); //es5
[1,2,3,...[4,5,6]]; //es6
~~~
2.与解构结合(用于生成数组)
~~~
let [a,b,...c]=[1,2,3,4,5]; //a=1,b=2,c=[3,4,5] 扩展运算符必须放在最后
~~~
3.Math.max的参数不支持数组,在es5中需要用到apply。用扩展运算符可以解决该问题
~~~
Math.max.apply(Math,[1,2,3]); //es5
Math.max(...[1,2,3]); //es6 相当于Math.max(1,2,3)
~~~
箭头函数,如果不需要参数则用圆括号代替参数部分,如果函数体有多行代码则用大括号括起来
~~~
var func=x=>x*2; //var func=function(x){return x*2;}
var func=()=>true; //var func=function(){return true;}
var func=(x,y)=>{var z=x+y;console.log(z);} //var func=function(x,y){var z=x+y;console.log(z);}
var func=()=>({a:1,b:2}); //返回对象需要用圆括号包起来,圆括号代表函数体,花括号代表这是一个对象
~~~
函数绑定,使用a::b的形式取代传统的bind/call/apply
~~~
a::b; //b.bind(a);
a::b(...arguments); //b.apply(a,arguments);
~~~
####对象的扩展
es6允许在对象中只写key,这样默认了value等于key所代表的变量值
~~~
var [name,age]=["SunnyChuan",22];
var obj={name,age}; //obj={name:"SunnyChuan",age:22}
//相当于obj={name:name,age:age};
~~~
对象的方法也可以简写
~~~
var obj={
func(){
//函数体
}
}
//相当于
var obj={
func:function(){
//函数体
}
}
~~~
Object.assign(obj,obj1,obj2,...),将obj1/obj2/...与obj进行拼接(修改obj本身)
~~~
var [obj,obj1,obj2]=[{a:1},{b:2},{c:3}];
Object.assign(obj,obj1,obj2);
console.log(obj); //{a:1,b:2,c:3}
~~~
Object.is(obj1,obj2),布尔值,判断两个值是否严格相等,与===不同的是,+0不等于-0,NaN等于NaN
~~~
Object.is(100,100); //true
Object.is(NaN,NaN); //true
Object.is(+0,-0); //false
Object.is({a:1},{a:1}); //false
~~~
###Set和Map
####Set
Set类似于数组,但是里面成员的值不能重复。Set构造函数可以传入一个数组用于初始化
~~~
var s=new Set();
[1,2,3].map(i=>s.add(i));
for(var i of s){console.log(s)}; //1 2 3
var s=new Set([1,2,3]);
for(var i of s){console.log(s)}; //1 2 3
~~~
Set拥有以下属性和方法
1.size,返回成员个数
2.add(value),添加值,返回自身
3.delete(value),删除值,返回布尔值,代表是否删除成功
4.has(value),布尔值,表示是否含有value成员
5.clear(),无返回值,删除所有成员
遍历操作
1.keys()
2.values()
3.entries()
4.forEach()
由于Set中只有值,因此keys()等于values()
~~~
var s=new Set([1,2,3,4]);
for(var i of s)console.log(i); //1 2 3 4
for(var i of s.keys())console.log(i); //1 2 3 4
for(var i of s.values())console.log(i); //1 2 3 4
for(var [k,v] of s.entries())console.log(`${k} ${v}`); //1 1 2 2 3 3 4 4,key值等于value值
s.forEach((v,k)=>{console.log(`${v} ${k}`)}); //1 1 2 2 3 3 4 4
~~~
通过Set可以很方便地实现数组去重而不必借用一次循环
~~~
var deleteSample=arr=>{var s=new Set(arr);return [...s];}
console.log(deleteSample([1,1,2,2,3,3,4])); //[1,2,3,4]
~~~
####Map
对象只能使用字符串当作key,而Map可以使用任意类型作为key。Map构造函数可以传入一个数组用于初始化,该数组由若干个数组构成,每个数组包含key和value
~~~
var m=new Map(),obj={a:1};
m.set(obj,"key is Object"); //将obj作为key,value是一个字符串
var m=new Map([["a",1],["b",2],["c",3]]);
for(var [k,v] of m)console.log(`${k} ${v}`); //a 1 b 2 c 3
~~~
Map拥有以下属性和方法
1.size,返回成员个数
2.set(key,vaule),设置key所对应的value,如果key存在则覆盖旧的value,如果不存在则新建key并赋值value。返回Map本身
3.get(key),获取key所对应的value
4.has(key),布尔值,判断Map中是否存在key键
5.delete(key),删除key键,返回布尔值,表示是否删除成功
6.cleear(),没有返回值,删除所有成员
遍历操作
1.keys()
2.values()
3.entries()
4.forEach()
~~~
var m=new Map([["a",1],["b",2],["c",3]]);
for(var [k,v] of m)console.log(`${k} ${v}`); // a 1 b 2 c 3
for(var k of m.keys())console.log(k); //a b c
for(var v of m.values())console.log(v); //1 2 3
for(var [k,v] of m.entries())console.log(`${k} ${v}`); //a 1 b 2 c 3
m.forEach((v,k)=>{console.log(`${v} ${k}`)}); //1 a 2 b 3 c
~~~
通过扩展运算符可以将Map转换成数组
~~~
var m=new Map([["a",1],["b",2],["c",3]]);
console.log([...m.keys()]); //a b c
console.log([...m.values()]); //1 2 3
console.log([...m.entries()]); //[["a",1],["b",2],["c",3]]
console.log([...m]); //[["a",1],["b",2],["c",3]]
~~~
###Iterator和for...of循环
####Iterator
Iterator为各种数据结构提供统一的遍历机制。在es6中,数组/伪数组/Set/Map具备原生的Iterator接口
~~~
let arr=[1,2,3];
var it=arr[Symbol.iterator]();
it.next(); //{value:1,done:false}
it.next(); //{value:2,done:false}
it.next(); //{value:3,done:false}
it.next(); //{value:undefined,done:true}
~~~
####for...of循环
for...of循环内部调用的是Symbol.iterator方法,也就是说,只要是支持Symbol.iterator方法的数据结构就可以用for...of循环,与for...in不同的是,for...of可以返回键值和键名(默认数组只返回键值,可以通过keys()/values()/entries()进行修改),而for...in只能返回键名
~~~
var arr=[1,2,3];
for(var i in arr)console.log(i); //0 1 2
for(var i in arr)console.log(arr[i]); //1 2 3
for(var i of arr)console.log(i); //1 2 3
~~~
普通的对象不支持for...of循环,可以使用Object.keys方法将对象的键名生成一个数组,遍历这个数组。其实相当于for...in
~~~
var obj={a:1,b:2,c:3};
for(var k of Object.keys(obj))console.log(`${k} ${obj[k]}`); //a 1 b 2 c 3
for(var k in obj)console.log(`${k} ${v}`); //a 1 b 2 c 3
~~~
###Class
####创建Class和实例
es6支持类似于Java、C++等高级程序设计语言的类的写法,但是它的底层仍然使用的是es5的面向对象声明方式,相当于是语法糖,es6将定义在this上的属性使用es5的构造函数的方式,对方法使用原型的方式,和es5的混合模式是一样的
~~~
class MyClass{
constructor(x,y){
this.x=x;
this.y=y;
}
print(){
console.log(`(${this.x},${this.y})`);
}
}
var myclass=new MyClass(2,3);
myclass.print(); //(2,3)
myclass.hasOwnProperty("x"); //true
myclass.hasOwnProperty("print"); //false
~~~
可以通过Object.assign为类添加方法
~~~
Object.assign(MyClass.prototype,{printName(){/**/},printAge(){/**/}});
~~~
Class也可以使用表达式的形式定义,无论是表达式形式还是一般形式,Class均不存在变量声明提升,必须先声明后使用
~~~
var MyClass=class{/**/};
var other=new OtherClass(); //ReferenceError
var OtherClass=class{/**/};
~~~
####Class的继承
es6的Class继承和Java相似,使用extends关键字。必须在constructor中调用super方法,并且只有调用了super后才能使用this,也就是说super必须放在所有this的前面
~~~
class SubClass extends MyClass{
constructor(x,y,z){
super(x,y); //调用父类的构造函数
this.z=z;
}
print(x,y,z){
console.log(`(${this.x},${this.y},${this.z})`); //重写父类的print
}
}
var sub=new SubClass(2,3,4;
console.log(sub instanceof SubClass); //true
console.log(sub instanceof MyClass); //true
~~~
可以通过object.getPrototypeOf方法从子类上获取父类,用于判断一个类是否继承自另一个类
~~~
console.log(Object.getPrototypeOf(SubClass)===MyClass); //true
~~~
es6允许继承原生构造函数(Boolean/Number/String/Array/Date/Function/RegExp)
~~~
class MyNumber extends Number{
constructor(...agrgs){
super(...args);
}
//添加一些方法
}
~~~
####Class的取值和存值函数
es6支持类似于C#的get和get方法,但是调用它们的时候是以属性的形式调用,而不是方法
~~~
class MyClass{
constructor(x){
this.x=x;
}
get getX(){
return this.x;
}
set setX(xx){
this.x=xx;
}
}
var myclass=new MyClass(2);
console.log(myclass.getX); //2
myclass.setX=3;
console.log(myclass.getX); //3
~~~
####Class的静态方法
在一个方法上加上static关键字表示该方法是一个静态方法,它不能被实例所调用,只能直接通过类去调用
~~~
class MyClass{
static print(){
console.log("hello world");
}
}
var myclass=new MyClass();
myclass.print(); //TypeError
MyClass.print(); //"hello world"
~~~
静态方法可以被子类继承,在子类中仍然是静态方法,可以通过super调用父类的静态方法
~~~
class SubClass extends MyClass{
static print(){
super.print();
}
}
SubClass.print(); //"hello world"
~~~
###模块的import和export
####export
export命令用于规定模块的对外接口,允许其他模块通过import加载该模块
~~~
//export.js
export var obj={a:1,b:2,c:3};
export var name="SunnyChuan";
export var age=22;
~~~
如果觉得上面的形式较繁琐,可以简写为
~~~
var [obj,name,age]=[{a:1,b:2,c:3},"SunnyChuan",22];
export {obj,name,age};
~~~
模块输出的变量就是它的名字,可以通过as进行重命名
~~~
var [obj,name,age]=[{a:1,b:2,c:3},"SunnyChuan",22];
export {obj as o,name as n,age as a};
~~~
####import
export用于导出模块,import用于加载模块,注意要加载的模块的名字必须与导出的模块的名字相同。import具有声明提升,会提升到整个代码块的头部
~~~
//import.js
import {obj,name,age} from "./export.js";
//如果export的时候已经重命名了,可以import {o,n,a} from "./export.js";
console.log(obj); //{a:1,b:2,c:3}
console.log(name); "SunnyChuan"
console.log(age); 22
~~~
同export,在import的时候也可以为模块重命名
~~~
import {obj as o,name as n,age as a} form "./exoprt.js"
~~~
使用“*”加载整个模块,然后用as指定给一个对象,通过调用对象的属性使用相应模块,也可以使用module命令取代import实现整体加载
~~~
import * as qc from "./exports.js";
console.log(qc.obj); //{a:1,b:2,c:3}
console.log(qc.name); "SunnyChuan"
console.log(qc.age); 22
module qc from "./exports.js";
console.log(qc.obj); //{a:1,b:2,c:3}
console.log(qc.name); "SunnyChuan"
console.log(qc.age); 22
~~~
以上是我经常用到的es6的知识点,想要学习更多强大的功能(Proxy/Reflect/Symbol/二进制数组/Generator/异步编程)或者想要更加细致地学习es6,可以访问阮一峰的教程[ECMAScript 6入门](http://es6.ruanyifeng.com/),本人也是在这里学习的。
- html/css
- 不一样的css3之Transform
- 不一样的css3之Transition
- 不一样的css3之Animation
- Less初学
- Sass初学
- 水平垂直居中那些事
- css优先级
- css基础教学
- javascript
- 浅谈javascript事件处理程序
- cookie,localStorage,sessionStorage的区别
- Ajax
- 说说JSON
- 数组常用的方法
- 字符串常用的方法
- 闭包之我的理解
- 常用DOM操作
- 扒一扒所谓的面向对象
- JS Blob对象
- ES6学习笔记(一)
- ES6学习笔记(二)
- 用ES6书写React
- React+Redux实战总结
- 基于Express搭建开发环境
- 其他
- github初学
- 轻松配置Webpack
- asp.net学习笔记
- ado.net
- 如何使用ajax进行前后端交互
- 银行大厅自助服务系统需求分析
- 西电银行开发手册
- 接口
- ajax