在近期的Vue開發(fā)中闪朱,使用了大量的ES6語法,因此覺得有必要找個(gè)時(shí)間來整理下近期的學(xué)習(xí)筆記钻洒。ES6相對(duì)ES5增加了許多新的特性奋姿,給我們的開發(fā)提供了方便。并且ES6也是未來開發(fā)的潮流素标,所以我覺得大家很有必要去掌握這一技能胀蛮。
在我們正式學(xué)習(xí)ES6前,我們需要先去學(xué)習(xí)下轉(zhuǎn)碼器糯钙。常用的轉(zhuǎn)碼器有Babel和Traceur粪狼。這里推薦一篇常見的ES6轉(zhuǎn)碼工具有興趣的可以去看看。
接下來我們就一起去見證ES6的神奇之處吧任岸!
1.let和const
let與var類似是用來聲明變量的再榄,const用來聲明常量。在實(shí)際用途中它們存在著許多區(qū)別享潜,廢話不多說困鸥,直接看代碼。
{
var a = 100;
let b = 200;
}
console.log(a); //100
console.log(b); //b is not defined -- Error
是不是感覺很奇怪剑按,為什么a有值而b卻not defined呢疾就?因?yàn)镋S5只有全局作用域和函數(shù)作用域,沒有塊級(jí)作用域艺蝴。而let則實(shí)際上為JavaScript新增了塊級(jí)作用域猬腰。用它所聲明的變量,只在let命令所在的代碼塊內(nèi)有效猜敢。
let不存在變量提升姑荷。那么什么是變量提升呢?簡(jiǎn)單來說就是無論聲明在什么地方缩擂,都會(huì)被視為聲明在頂部鼠冕。下面來看個(gè)例子。
//ES5
console.log("ES5:");
var a = [];
for (var i = 0; i < 10; i++) {
var c = i;
a[i] = function () {
console.log(c);
};
};
a[5](); //結(jié)果:9
是不是有許多小伙伴在疑惑為什么輸出的不是5呢胯盯?變量i是var聲明的懈费,在全局范圍內(nèi)都有效。所以每一次循環(huán)博脑,新的i值都會(huì)覆蓋舊值憎乙,導(dǎo)致最后輸出的是最后一輪的i的值薄坏。而使用let則不會(huì)出現(xiàn)這個(gè)問題。
//ES6
console.log("ES6:");
var b = [];
for (var j = 0; j < 10; j++) {
let d = j;
b[j] = function () {
console.log(d);
};
};
b[5](); 結(jié)果://5
同時(shí)let也是不允許重復(fù)聲明的寨闹。
{
var a = 100;
var a = 200;
console.log(a); //200
}
// 模塊內(nèi)部不允許用let命令重復(fù)聲明
{
var a = 1;
let a = 2;
console.log(a); // 報(bào)錯(cuò)
}
下面再來說說 const胶坠。const也用來聲明變量,但是聲明的是常量繁堡,一旦聲明沈善,常量的值就不能改變。它和let一樣只在聲明的區(qū)域內(nèi)有用椭蹄。
{
var a = 100;
const a = 200;
console.log(a); // 報(bào)錯(cuò)
}
const聲明對(duì)象
const person = {};
person.name = "Zhangsan";
person.age = 30;
console.log(person.name); //Zhangsan
console.log(person.age); //30
console.log(person); //Object {name: "Zhangsan", age: 30}
const對(duì)象凍結(jié)
const person = Object.freeze({});
person.name = "Zhangsan";
person.age = 30;
console.log(person.name); //undefined
console.log(person.age); //undefined
console.log(person); //Object
2.模板字符串
相對(duì)于es5的' '+變量這種字符串拼接方法闻牡,es6的模板字符串要方便許多。
var a = '張三';
var age = 18;
var b = '我的名字是'+a+'我今年'+age+'歲了'; // es5
var c = `我的名字是${a}我今年${age}歲了`; // es6
當(dāng)然簡(jiǎn)單的兩行代碼可能它的優(yōu)勢(shì)沒有那么的明顯绳矩,一旦代碼量變多罩润,你就能體會(huì)到它的便利了。
3.函數(shù)
函數(shù)默認(rèn)參數(shù)
function num(n) {
n = n || 200; //當(dāng)傳入n時(shí)翼馆,n為傳入的值割以,沒有則默認(rèn)200
return n;
}
es6為參數(shù)提供了默認(rèn)值。在定義函數(shù)時(shí)便初始化了這個(gè)參數(shù)应媚,直接看代碼严沥。
function num(n = 200) {
return n;
}
console.log(n()); // 200
console.log(n(100)); // 100
箭頭函數(shù)
箭頭函數(shù)的基本用法。
// es5
function breakfast(dessert,drink){
return dessert+drink;
}
// es6
let breakfast = (dessert,drink) => dessert + ' ' + drink;
console.log(breakfast('面包','牛奶'));
箭頭函數(shù)的this指向綁定定義是所在的作用域中姜,而普通函數(shù)this指向運(yùn)行時(shí)所在的作用域(全局對(duì)象)消玄,箭頭函數(shù)沒有自己的this而是引用外層的this。
// es5
cartView: function() {
var _this = this;
this.$http.get("data/cartData.json", {"id": 123}).then(function(res) {
_this.productList = res.data.result.list;
console.log(_this.productList);
});
}
// es6
cartView(){
this.$http.get("data/cartData.json", {"id": 123}).then((res) {
this.productList = res.data.result.list;
console.log(this.productList);
});
}
4.解構(gòu)
數(shù)組和對(duì)象是JS中最常用也是最重要表示形式丢胚。為了簡(jiǎn)化提取信息翩瓜,ES6新增了解構(gòu),這是將一個(gè)數(shù)據(jù)結(jié)構(gòu)分解為更小的部分的過程携龟。
// es5提取對(duì)象
let people = {
name : 'json',
age : 18,
sex : 'male'
}兔跌;
let name = people.name;
let age = people.age;
...
// es6
let people = {
name : 'json',
age : 18,
sex : 'male'
};
let {name, age, sex} = people;
相比于es5是不是簡(jiǎn)便了許多骨宠,當(dāng)然數(shù)組的方法與對(duì)象的類似浮定。下面我們?cè)賮砼e個(gè)栗子,函數(shù)參數(shù)解構(gòu)賦值的默認(rèn)值层亿。
fun ({x, y} = { x: 0, y: 0 }) {
return [x, y];
};
console.log(fun({x: 100, y: 200})); //[100, 200]
console.log(fun({x: 100})); //[100, undefined]
console.log(fun({})); //[undefined, undefined]
console.log(fun()); //[0, 0]
講了這么多,可能有人就會(huì)問了這個(gè)解構(gòu)到底有什么用呢立美?其實(shí)它適合于各種與數(shù)組匿又,對(duì)象,函數(shù)打交道的場(chǎng)景建蹄。下面我們來舉個(gè)運(yùn)用最廣的例子—變量交換碌更。直接上代碼裕偿。
//ES5
console.log("ES5:");
var a = 100;
var b = 200;
console.log("交換前:");
console.log("a = " + a); //a = 100
console.log("b = " + b); //b = 200
var temp;
temp = a;
a = b;
b = temp;
console.log("交換后:");
console.log("a = " + a); //a = 200
console.log("b = " + b); //b = 100
//ES6
console.log("ES6:");
var x = 100;
var y = 200;
console.log("交換前:");
console.log("x = " + x); //x = 100
console.log("y = " + y); //y = 200
[x, y] = [y, x];
console.log("交換后:");
console.log("x = " + x); //x = 200
console.log("y = " + y); //y = 100
5. ...操作符
- 展開操作符
let str2 = ['蘋果','梨子'];
console.log(str2);//["蘋果", "梨子"]
console.log(...str2);//蘋果 梨子
- 剩余操作符
fun(a,b,...c){
console.log(a,b,...c);//...c指展開數(shù)組
}
fun('蘋果','香蕉','橘子','梨子','李子');//蘋果 香蕉 橘子 梨子 李子
6.class、 extends痛单、 super
這三個(gè)特性涉及了ES5中最令人頭疼的的幾個(gè)部分:原型嘿棘、構(gòu)造函數(shù),繼承...看到它們是不是開始懷疑人生了旭绒。
別怕有來了ES6我們以后再懷疑吧鸟妙!
ES6提供了更接近傳統(tǒng)語言的寫法,引入了Class(類)這個(gè)概念挥吵。新的class寫法讓對(duì)象原型的寫法更加清晰重父、更像面向?qū)ο缶幊痰恼Z法,也更加通俗易懂忽匈。
class MyClass {
constructor() { // 構(gòu)造函數(shù)
// ...
}
get prop() { // 取值
return 'getter';
}
set prop(value) { // 存值
console.log('setter: '+value);
}
}
let inst = new MyClass();
inst.prop = 123;
// setter: 123
console.log(inst.prop);
// 'getter'
extends用法
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
this.color = color; // 正確
}
}
在子類的構(gòu)造函數(shù)中房午,只有調(diào)用super之后,才可以使用this關(guān)鍵字丹允,否則會(huì)報(bào)錯(cuò)郭厌。這是因?yàn)樽宇悓?shí)例的構(gòu)建,是基于對(duì)父類實(shí)例加工雕蔽,只有super方法才能返回父類實(shí)例沪曙。父類的靜態(tài)方法,也會(huì)被子類繼承萎羔。
注意液走,super雖然代表了父類Point的構(gòu)造函數(shù),但是返回的是子類ColorPoint的實(shí)例贾陷,即super內(nèi)部的this指的是ColorPoint缘眶,因此super()在這里相當(dāng)于Point.prototype.constructor.call(this)。
super這個(gè)關(guān)鍵字髓废,既可以當(dāng)作函數(shù)使用巷懈,也可以當(dāng)作對(duì)象使用。在這兩種情況下慌洪,它的用法完全不同顶燕。
作為函數(shù)時(shí),super()只能用在子類的構(gòu)造函數(shù)之中冈爹,用在其他地方就會(huì)報(bào)錯(cuò)涌攻。
class A {}
class B extends A {
m() {
super(); // 報(bào)錯(cuò)
}
}
第二種情況,super作為對(duì)象時(shí)频伤,在普通方法中恳谎,指向父類的原型對(duì)象;在靜態(tài)方法中,指向父類因痛。
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
let b = new B();
上面代碼中婚苹,子類B當(dāng)中的super.p()就是將super當(dāng)作一個(gè)對(duì)象使用。這時(shí)鸵膏,super在普通方法之中膊升,指向A.prototype,所以super.p()就相當(dāng)于A.prototype.p()谭企。這里需要注意廓译,由于super指向父類的原型對(duì)象,所以定義在父類實(shí)例上的方法或?qū)傩栽蘖菬o法通過super調(diào)用的责循。
7.Promise
在promise之前代碼過多的回調(diào)或者嵌套,可讀性差攀操、耦合度高院仿、擴(kuò)展性低。通過Promise機(jī)制速和,大大提高了代碼可讀性歹垫;用同步編程的方式來編寫異步代碼,保存線性的代碼邏輯颠放,極大的降低了代碼耦合性而提高了程序的可擴(kuò)展性排惨。
this.$http('/api/getData').then((res) => {
res = res.data;
this.dataList = res.result;
}).catch((err) => {
...
});
這是一個(gè)vue的異步請(qǐng)求,用的就是promise機(jī)制碰凶,這樣的好處是不會(huì)因?yàn)槎鄬拥幕卣{(diào)而降低代碼的可讀性暮芭。
當(dāng)然這只是promise的冰山一角,想要更好的掌握它還是需要更加深入的去學(xué)習(xí)它欲低。
8.Set
實(shí)例的方法分為兩大類:操作方法(用于操作數(shù)據(jù))和遍歷方法(用于遍歷成員)辕宏。下面先介紹四個(gè)操作方法。
- 操作方法:
add(value):添加某個(gè)值砾莱,返回Set結(jié)構(gòu)本身瑞筐。
delete(value):刪除某個(gè)值,返回一個(gè)布爾值腊瑟,表示刪除是否成功聚假。
has(value):返回一個(gè)布爾值热押,表示該值是否為Set的成員抚太。
clear():清除所有成員俭茧,沒有返回值戚啥。 - 遍歷方法:
keys():返回鍵名的遍歷器
values():返回鍵值的遍歷器
entries():返回鍵值對(duì)的遍歷器
forEach():使用回調(diào)函數(shù)遍歷每個(gè)成員
由于 Set 結(jié)構(gòu)沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個(gè)值)
let str = [1,2,3,2,4,3,5,6,4,1,7];
console.log('str的長(zhǎng)度為:'+str.length); // 長(zhǎng)度為11
let s = new Set(str);
console.log(s);
console.log('去重后的長(zhǎng)度為:'+s.size);//長(zhǎng)度為7
console.log( Array.from(s));//Array.from 將Set轉(zhuǎn)換為數(shù)組形式
let set = new Set(['red', 'green', 'blue']);
var arr = new Set();
for (let item of set.keys()) {
console.log(item);// red green blue
arr.add(item);//將item添加到arr set結(jié)構(gòu)中
}
console.log(arr);
arr.forEach((value, key) => console.log(key + ' : ' + value));
9.import 和 export
//全部導(dǎo)入
import mallHeader from '../components/header.vue'
//導(dǎo)入部分
import {name, age} from './example'
// 導(dǎo)出默認(rèn), 有且只有一個(gè)默認(rèn)
export default App
// 部分導(dǎo)出
export class App extend Component {};
小結(jié)
這些僅僅是es6家族中的冰山一角挪略,想要更加全面的去掌握這一技能波材,就需要我們更加系統(tǒng)的去學(xué)習(xí)它酿愧。感謝花了這么長(zhǎng)時(shí)間游岳,閱讀文章的小伙伴們政敢,希望能對(duì)你們帶來幫助。有錯(cuò)誤的地方希望大佬們多多包涵胚迫,給我反饋喷户!