之前做vue和react的時候,發現文檔什么的最新版本都建議用es6寫法,對es6友好度更高,加之現在es6也越來越普及,兼容性問題直接用babel轉碼就好了,特別方便,於是我開始學着用es6寫代碼,下面總結下一般es6常用的新特性:
1,申明變量let和const:
js由於沒有塊級作用域,變量在申明他們的函數體內以及這個函數體內嵌套的任何函數體內都是有定義的(申明提前),例如:
function test(){
console.log(i); //undefined
for(var i=0;i<10;i++){}
console.log(i); //10
}
es6通常用let和const申明變量,const是申明常亮(申明后值不可修改,修改會報錯),let是變量,都是塊級作用域,在{}內有效:
function test(){
console.log(i); //報錯
for(let i=0;i<10;i++){}
console.log(i);
}
這樣代碼更加嚴謹,不用擔心內部變量被外面修改用了,更加安全。
2,函數
函數參數默認值:
es5給函數參數指定默認值的時候如下:
//es5
function aa(num){ num=num||100; return num; } console.log(aa(0)); //如果沒有傳入參數或者傳入0的話,結果就變成了100,不是我們指定的值
這樣就會帶來以上問題,結果跟我們設定的不一樣,es6新特性解決了這個問題
//es6
function aa1(num=100){ return num; } console.log(aa1()); //沒傳入參數100
console.log(aa1(0)); //0
console.log(aa1(200)); //200
箭頭函數:
箭頭函數寫法更加簡潔,省略了function關鍵字申明,省略return,例如
[1,2,3].map( x => x + 1 ) //相當於:
[1,2,3].map(function(x){ return x + 1 })
注意,箭頭函數的this是定義時的this,不是運行時的,比如在vue中method找this.data的時候找不到,原因是this指向的不是運行時vue的實例,而是定義時的windos,例如
$.each(['a','b','c'],function(i,n){ console.log(this); //n
}); $.each(['a','b','c'],(i,n)=>{ console.log(this); //window
});
3,模板字符串:
第一:es5在字符串拼接的時候,常常會用+號把值和字符拼接起來,如果要拼接dom元素的話,會很麻煩,es6很好的解決了這個問題
//es5
const name='han meimei';
console.log('hellow '+name);
//es6
const name1='han meimei';
console.log(`hellow ${name1}`); //注意,是鍵盤1左邊那個字符符號,不是普通的單引號哦!
第二:es5常用反斜杠(\)來做多行字符串的拼接,es6只需要用(`)就可以了,這樣以后拼接dom串的時候就方便多啦!
//es5
var wrap="<div> \
<span>AAA</span>\
</div> \
";
console.log(wrap);
//es6
var wrap1=`
<div>
<span>AAA</span>
</div>
`;
console.log(wrap1);
4,Promise
Promise的出現是為了防止異步調用出現很多層回調函數,顯得代碼臃腫,可以通過鏈式調用的方式書寫異步代碼,保證了代碼的線性邏輯,跟Jquery的Deferred用法類似,es7還推出了更加簡潔的寫法Async/await,關於es6 Promise用法,我之前一篇文章寫過了,可以查閱
5,Class 類
es6新增加了class關鍵字來定義聲明一個類,還多了extends繼承關鍵字,使得類的聲明的繼承更加方便,像極了java語言,在es5中我們一般這樣寫:
//es5
function Person(name){
this.name=name;
}
Person.prototype.sayName=function(){
console.log('name: '+this.name);
}
function Student(name,age){
Person.call(this,name); //調用父類構造函數
this.age=age;
}
Student.prototype.sayAge=function(){
console.log('age: '+this.age);
}
Student.prototype=new Person(); //Student.prototype.constructor就是構造對象Person
Student.prototype.constructor=Student; //之前的構造器指向了Person,現在要重新指回來
//從而Student.prototype===stu.constructor.prototype,很多人忽略了這點
Student.prototype.sayAll=function(){
console.log('name: '+this.name);
console.log('age: '+this.age);
}
var stu=new Student('tom',19);
console.log(Student.prototype===stu.constructor.prototype); //true
stu.sayName();
stu.sayAll();
//stu.sayAge(); //報錯,因為Student.prototype=new Person();對原型重新賦了值
es6更加簡潔:
//定義類
class Person{
constructor(name){ //構造函數
this.name=name;
}
sayName(){
console.log('name: '+this.name);
}
}
//繼承
class Student extends Person{ //這點和java語言很像,都是通過關鍵字extends
constructor(name,age){
super(name); //調用父類構造函數,這點跟java又一樣
this.age=age;
}
sayAge() {
console.log('age: '+this.age);
}
sayAll() {
console.log('sayAll:');
console.log('name: '+this.name);
console.log('age: '+this.age);
}
}
var stu=new Student('jack',20);
console.log(Student.prototype===stu.constructor.prototype); //true
stu.sayName();
stu.sayAge();
stu.sayAll();
es6用更加簡潔的方式完美的實現了類的繼承,特別好用!!!
6,export和import
es6之前,都是用requireJS進行模塊化開發,es6export導出模塊、import導入模塊,可以直接支持module了,現在的vue和react,都是用es6開發了,對於組件的引入就用到這個知識點了
//全部導入
import people from './person'
//整個模塊導入並且使用as關鍵字重命名 //該模塊的所有導出都會作為對象的屬性存在
import * as person "./person.js"
console.log(person.sex)
console.log(person.num)
console.log(person.getNum())
//導入部分
import {name, age} from './person'
// 導出默認, 有且只有一個默認
export default App
//1.當用export default people導出時,就用 import people 導入(不帶大括號) //2.一個文件里,有且只能有一個export default。但可以有多個export。 //3.當用export name 時,就用import { name }導入(記得帶上大括號) //4.當一個文件里,既有一個export default people, 又有多個export name 或者 export age時,導入就用 import people, { name, age } //5.當一個文件里出現n多個 export 導出很多模塊,導入時除了一個一個導入,也可以用import * as example
7,Spread operator 展開運算符
Spread operator也是es6一個新特性,寫法是...,也就是三個點
用來組裝數組
//數組組裝
const arr1=[1,2,3];
const arr2=[...arr1,4,5,6];
console.log(arr2); //[1, 2, 3, 4, 5, 6]
//函數調用
function print(a,b,c){
console.log(a,b,c);
}
var arr=[1,2,3];
//es5
print.apply(null,arr);
//es6
print(...arr); //1 2 3
//替換push方法 //es5
var a1=[1,2,3];
var a2=[4,5,6];
Array.prototype.push.apply(a1,a2); //[1, 2, 3, 4, 5, 6]
//es6
a1.push(...a2); //[1, 2, 3, 4, 5, 6]
8,對象的擴展:
初始化簡寫,鍵值對重名的情況:
//es5
var a=1,b=2; var obj={ a:a, b:b } console.log(obj); //{a: 1, b: 2}
//es6
let a=1,b=2; let obj={ a, b } console.log(obj); //{a: 1, b: 2}
對象方法簡寫:
//es5
var person={ run:function(){ console.log('run'); } } person.run(); //es6
let person={ run(){ console.log('run'); } } person.run();
es6的Object.assign()這個方法來實現淺復制,類似於Jquery的$.extend,第一個參數是目標對象,后面的是被合並的源對象,然后返回目標對象,注意如果出現同名屬性,會被最后一個值覆蓋
let obj = { name1: 'foo' }; let obj1 = { name2: 'bar' }; let obj2 = { name3: 'baz' }; Object.assign(obj,obj1,obj2); console.log(obj); //為了不改變源對象本身,通常會把目標對象傳為{},返回值作為新目標對象
var obj1={ name1: 'foo' }; var obj2={ name2: 'bar' }; var obj3={ name3: 'baz' } var obj=Object.assign({},obj1,obj2,obj3); console.log(obj); //{name1: "foo", name2: "bar", name3: "baz"}
9,解構賦值
為了簡化提取數組或對象中的值,es6新加了解構的特性
es5中提取對象信息方法常用如下:
var people={ name:'Li Lei', age:19 } var name=people.name; var age=people.age; console.log('name:'+name); console.log('age:'+age);
es6簡化的這個步驟,如下:
//對象
const people={ name:'luo', age:19 } const {name,age}=people; console.log(`${name}------${age}`); //數組
const color=['red','blue']; const [first,second]=color; console.log(first); console.log(second);
總體來說,es6新特性還有很多,但是日常開發中用到這些主要的已經夠用了,我在之前的react和vue中就主要用到這幾大模塊,已經足夠啦,還有很多有意思的細微的方法比如操作字符串,數組去重的等,都挺有意思的,回頭等我慢慢挖掘!