###函數和對象的擴展
####函數的擴展
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