es6常用基礎合集

es6常用基礎合集

ES6徹底改變了前端的編碼風格,可以說對于前端的影響非常巨大。值得高興的是,如果你熟悉ES5,學習ES6并不需要花費太多的時間就可以掌握,因為常用的基礎語法并不多,花少量的時間,就可以開始我們的ES6之旅了。

在學習之前,推薦大家使用babel官方提供的在線編譯工具,編寫自己的demo,會在右側(cè)實時顯示出編譯之后的代碼,以供參考學習 http://babeljs.io/repl

一、新的變量聲明方式 let/const

與var不同,新的變量聲明方式帶來了一些不一樣的特性,其中最重要的兩個特性就是提供了塊級作用域不再具備變量提升

通過2個簡單的例子來說明這兩點

{
    let a = 20;
}

console.log(a);  // a is not defined

而這個簡單的例子,會被編譯為:

{
    let _a = 20;
}

console.log(a);  // a is not defined

變量提升

// ES5
console.log(a);   // undefined
var a = 20;

// ES6
console.log(a); // a is not defined
let a = 20;

當然,你的代碼編譯成為了ES5之后,仍然會存在變量提升,這一點只需要我們記住即可。在實際使用中,也需要盡量避免使用變量提升的特性帶來的負面影響。只有在面試題中,才會對變量提升不停的濫用。

使用ES6,我們需要全面使用let/const替換var,那么什么時候用let,什么時候用const就成為了一個大家要熟練區(qū)分的一個知識點。

我們常常使用let來聲明一個值會被改變的變量,而使用const來聲明一個值不會被改變的變量,也可以稱之為常量

當值為基礎數(shù)據(jù)類型時,那么這里的值,就是指值本身。 而當值對應的為引用數(shù)據(jù)類型時,那么我這里說的值,則表示指向該對象的引用。這里需要注意,正因為該值為一個引用,只需要保證引用不變就可以,我們?nèi)匀豢梢愿淖冊撘盟赶虻膶ο?/p>

當我們試圖改變const聲明的變量時,則會報錯。

寫幾個例子,大家可以仔細揣摩一下:

let a = null;
a = 20;
const obDev = {
    a: 20,
    b: 30
}

obDev.a = 30;
console.log(obDev); // Object {a: 30, b: 30}
obDev = 123; // Assignment to constant variable.
const obDev = {
    a: 20,
    b: 30
}
const fn = function() {}
const a = obDev.a;

只要抓住上面我說的特性,那么在使用let/const時就會顯得游刃有余。 根據(jù)我自己的經(jīng)驗,使用const的場景要比使用let的場景多很多。

二、 箭頭函數(shù)的使用

之前我說ES6顛覆了js的編碼習慣,箭頭函數(shù)的使用占了很大一部分。

首先是寫法上的不同:

// es5
var fn = function(a, b) {
    return a + b;
}

// es6 箭頭函數(shù)寫法,當函數(shù)直接被return時,可以省略函數(shù)體的括號
const fn = (a, b) => a + b;

// es5
var foo = function() {
    var a = 20;
    var b = 30;
    return a + b;
}

// es6
const foo = () => {
   const a = 20;
   const b = 30;
   return a + b;
}

箭頭函數(shù)可以替換函數(shù)表達式,但是不能替換函數(shù)聲明

其次還有一個至關重要的一點,那就是箭頭函數(shù)中,沒有this。如果你在箭頭函數(shù)中使用了this,那么該this一定就是外層的this。

也正是因為箭頭函數(shù)中沒有this,因此我們也就無從談起用call/apply/bind來改變this指向。記住這個特性,能讓你在react組件之間傳值時少走無數(shù)彎路。

var person = {
    name: 'tom',
    getName: function() {
        return this.name;
    }
}

// 我們試圖用ES6的寫法來重構上面的對象
const person = {
    name: 'tom',
    getName: () => this.name
}
// 但是編譯結(jié)果卻是
var person = {
    name: 'tom',
    getName: function getName() {
        return undefined.name;
    }
};

在ES6中,會默認采用嚴格模式,因此this也不會自動指向window對象了,而箭頭函數(shù)本身并沒有this,因此this就只能是undefined,這一點,在使用的時候,一定要慎重慎重再慎重,不然踩了坑你都不知道自己錯在哪!這種情況,如果你還想用this,就不要用使用箭頭函數(shù)的寫法。

// 可以稍做改動
const person = {
    name: 'tom',
    getName: function() {
        return setTimeout(() => this.name, 1000);
    }
}

// 編譯之后變成
var person = {
    name: 'tom',
    getName: function getName() {
        var _this = this;  // 使用了我們在es5時常用的方式保存this引用

        return setTimeout(function () {
            return _this.name;
        }, 1000);
    }
};

先記住箭頭函數(shù)的寫法,并留意箭頭函數(shù)中關于this的特殊性,更過實踐與注意事項我們在封裝react組件時再慢慢來感受。

除此之外,箭頭函數(shù)中無法訪問arguments對象。

三、模板字符串

模板字符串是為了解決使用+號拼接字符串的不便利而出現(xiàn)的。它的功能非常強大,但是我們大多數(shù)時候使用它則非常簡單。看一個例子大家就明白怎么使用了。

// es6
const a = 20;
const b = 30;
const string = `${a}+${b}=${a+b}`;

// es5
var a = 20;
var b = 30;
var string = a + "+" + b + "=" + (a + b);

使用 `` 將整個字符串包裹起來,而在其中使用 ${} 來包裹一個變量或者一個表達式。

當然模板字符串還支持換行等強大的功能,更多的大家可通過參考資料進一步學習。

四、 解析結(jié)構

解析結(jié)構是一種全新的寫法,我們只需要使用一個例子,大家就能夠明白解析結(jié)構到底是怎么一回事兒。

// 首先有這么一個對象
const props = {
    className: 'tiger-button',
    loading: false,
    clicked: true,
    disabled: 'disabled'
}

當我們想要取得其中的2個值:loading與clicked時:

// es5
var loading = props.loading;
var clicked = props.clicked;

// es6
const { loading, clicked } = props;

// 給一個默認值,當props對象中找不到loading時,loading就等于該默認值
const { loading = false, clicked } = props;

// es5
var _props$loading = props.loading,
    loading = _props$loading === undefined ? false : _props$loading,
    clicked = props.clicked;

是不是簡單了許多?正是由于解析結(jié)構大大減少了代碼量,因此它大受歡迎,在很多代碼中它的影子隨處可見。

// 比如
// section1
import React, { Component } from 'react';

// section2
export { default } from './Button';

// section3
const { click, loading } = this.props;
const { isCheck } = this.state;

// more  任何獲取對象屬性值的場景都可以使用解析結(jié)構來減少我們的代碼量

另外,數(shù)組也有屬于自己的解析結(jié)構。

// es6
const arr = [1, 2, 3];
const [a, b, c] = arr;

// es5
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];

數(shù)組以序列號一一對應,這是一個有序的對應關系。

而對象根據(jù)屬性名一一對應,這是一個無序的對應關系。

根據(jù)這個特性,使用解析結(jié)構從對象中獲取屬性值更加具有可用性。

五、 函數(shù)默認參數(shù)

之前我們不能直接為函數(shù)指定默認參數(shù),因此很多時候為了保證傳入的參數(shù)具備一個默認值,我們常常使用如下的方法:

function add(x, y) {
    var x = x || 20;
    var y = y || 30;
    return x + y;
}

console.log(add()); // 50

這種方式并不是沒有缺點,比如當我傳入一個x值為false,這個時候任然會取到默認值,就不是我們的本意了。

來看看ES6的默認值寫法:

function add(x = 20, y = 30) {
    return x + y;
}

console.log(add());

//es6
function add() {
    var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 20;
    var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30;

    return x + y;
}

在實際開發(fā)中給參數(shù)添加適當?shù)哪J值,可以讓我們對函數(shù)的參數(shù)類型有一個直觀的認知。

const ButtonGroupProps = {
    size: 'normal',
    className: 'xxxx-button-group',
    borderColor: '#333'
}

export default function ButtonGroup(props = ButtonGroupProps) {
    ... ...
}

六、 展開運算符

在ES6中用...來表示展開運算符,它可以將數(shù)組方法或者對象進行展開。先來看一個例子它是如何使用的 。

// es6
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 10, 20, 30];

// 這樣,arr2 就變成了[1, 2, 3, 10, 20, 30];
// es5
var arr2 = [].concat(arr1, [10, 20, 30]);

當然,展開對象數(shù)據(jù)也是可以得到類似的結(jié)果

const obj1 = {
  a: 1,
  b: 2,
  c: 3
}

const obj2 = {
  ...obj1,
  d: 4,
  e: 5,
  f: 6
}
// 結(jié)果類似于 const obj2 = Object.assign({}, obj1, {d: 4})

展開運算符還常常運用在解析結(jié)構之中,例如我們在Raect封裝組件的時候常常不確定props到底還有多少數(shù)據(jù)會傳進來,就會利用展開運算符來處理剩余的數(shù)據(jù)

// 這種方式在react中十分常用
const props = {
  size: 1,
  src: 'xxxx',
  mode: 'si'
}


const { size, ...others } = props;

console.log(others) // {src: "xxxx", mode: "si"}

// 然后再利用暫開運算符傳遞給下一個元素,再以后封裝react組件時會大量使用到這種方式,正在學習react的同學一定要搞懂這種使用方式
<button {...others} size={size} />

展開運算符還用在函數(shù)的參數(shù)中,來表示函數(shù)的不定參。只有放在最后才能作為函數(shù)的不定參,否則會報錯

// 所有參數(shù)之和
const add = (a, b, ...more) => {
    return more.reduce((m, n) => m + n) + a + b
}

console.log(add(1, 23, 1, 2, 3, 4, 5)) // 39

展開運算符的運用可以大大提高我們的代碼效率,但是在剛開始使用的時候比較繞腦,掌握好了用起來還是非常爽的,記住這些使用場景,平時在用的時候可以刻意多運用就行了。

七、對象字面量 與 class

  • 當屬性與值的變量同名時。
const name = 'Jane';
const age = 20

// es6
const person = {
  name,
  age
}

// es5
var person = {
  name: name,
  age: age
};

那么這種方式在任何地方都可以使用,比如在一個模塊對外提供接口時

const getName = () => person.name;
const getAge = () => person.age;

// commonJS的方式
module.exports = { getName, getAge }

// ES6 modules的方式
export default { getName, getAge  }
  • 除了屬性之外,對象字面量寫法中的方法也可以有簡寫方式。
// es6
const person = {
  name,
  age,
  getName() { // 只要不使用箭頭函數(shù),this就還是我們熟悉的this
    return this.name
  }
}

// es5
var person = {
  name: name,
  age: age,
  getName: function getName() {
    return this.name;
  }
};
  • 在對象字面量中可以使用中括號作為屬性,表示屬性名也能是一個變量了
const name = 'Jane';
const age = 20

const person = {
  [name]: true,
  [age]: true
}

在ant-design的源碼實現(xiàn)中,就大量使用了這種方式來拼接當前元素的className,例如:

let alertCls = classNames(prefixCls, {
      [`${prefixCls}-${type}`]: true,
      [`${prefixCls}-close`]: !this.state.closing,
      [`${prefixCls}-with-description`]: !!description,
      [`${prefixCls}-no-icon`]: !showIcon,
      [`${prefixCls}-banner`]: !!banner,
 }, className);

ant-design是一個認可度非常高的UI組件庫,官方使用react的方式進行了實現(xiàn),除此之外,還有vue也有對應的實現(xiàn),有興趣的同學可以去他們的官網(wǎng)了解學習。https://ant.design/index-cn

  • class

ES6為我們創(chuàng)建對象提供了新的語法糖,這就是Class語法。如果你對ES5中面向?qū)ο蟮姆绞奖容^熟悉的話,Class掌握起來也是非常迅速的,因為除了寫法的不同,它并不會增加新的難以理解的知識點。我們先利用一個簡單的例子來看看寫法的不同

function Person(name, age){
    this.name = name;
    this.age = age;
}
// 原型方法
Person.prototype.getName = function(){
    return this.name
}

// es6
class Person{
    constructor(name, age){ //構造函數(shù)
        this.name = name;
        this.age = age;
    }
    getName(){ //原型方法
        return this.name;
    }
}

babel會將ES6的寫法編譯成為利用Object.defineProperty實現(xiàn)的方式,這個方法的具體用處大家可以在《JavaScript高級編程3》中學習了解,包括get,set,等都有詳細的說明

除此之外,我們還需要特別注意在實際使用中的幾種寫法方式的不同,在下面的例子注釋中,我說明了他們分別對應的ES5中的含義。

class Person {
  constructor(name, age) {  // 構造函數(shù)
    this.name = name;
    this.age = age;
  }

  getName() {   // 這種寫法表示將方法添加到原型中
    return this.name
  }

  static a = 20;  // 等同于 Person.a = 20

  c = 20;   // 表示在構造函數(shù)中添加屬性 在構造函數(shù)中等同于 this.c = 20

// 箭頭函數(shù)的寫法表示在構造函數(shù)中添加方法,在構造函數(shù)中等同于this.getAge = function() {}
  getAge = () => this.age   
}

箭頭函數(shù)需要注意的仍然是this的指向問題,因為箭頭函數(shù)this指向不能被改變的特性,因此在react組件中常常利用這個特性來在不同的組件進行傳值會更加方便。

  • 繼承 extends

相比ES5,ES6的繼承就要簡單很多,我們直接來看一個例子。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  getName() {
    return this.name
  }
}

// Student類繼承Person類
class Student extends Person {
  constructor(name, age, gender, classes) {
    super(name, age);
    this.gender = gender;
    this.classes = classes;
  }

  getGender() {
    return this.gender;
  }
}

我們只需要一個extends關鍵字,就可以實現(xiàn)繼承了,不用像ES5那樣去擔心構造函數(shù)繼承和原型繼承,除此之外,我們還需要關注一個叫做super的方法。

在繼承的構造函數(shù)中,我們必須如上面的例子那么調(diào)用一次super方法,它表示構造函數(shù)的繼承,與ES5中利用call/apply繼承構造函數(shù)是一樣的功能。

// 構造函數(shù)中
// es6
super(name, age);

// es5
Person.call(this);

super還可以直接調(diào)用父級的原型方法,super.getName,但是我自己從來沒這樣用過,也就不擴展說了。

繼承在react中有大量的使用場景,許多組件都利用繼承來創(chuàng)建。

import React, { Component } from 'react';

class App extends Component {

  defaultProps = {}
  state = {}
  componentWillMount() {}
  componentDidMount() {}

  btnClick = e => {}

  render() {}
}

其實只要我們ES5面向?qū)ο蟮闹R足夠扎實,ES6和react掌握起來也沒有太多的難度,所有的學習難點,并不在ES6這些不同的語法糖上,而在于ES5中的原理,因此我在前面分享ES5的核心知識的時候,很多讀者老爺都迫不及待的希望我能夠更多的說一說ES6的知識。其實我們都沒有必要那么著急,只要前面10多篇文章的知識足夠扎實,這篇文章所涉及到的常用的ES6知識,最多花30分鐘也就掌握了。這些寫法上的不同并不會造成大家理解上的困難,只需要有一個熟悉過程就行了。所以大家的重點,還是要回歸到基礎上來。

深入學習ES6推薦 http://es6.ruanyifeng.com/

參考:

前端基礎進階(十四):es6常用基礎合集

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)參數(shù)的默認值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,433評論 0 1
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,803評論 0 1
  • 一、ES6簡介 ? 歷時將近6年的時間來制定的新 ECMAScript 標準 ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,104評論 8 25
  • 三,字符串擴展 3.1 Unicode表示法 ES6 做出了改進,只要將碼點放入大括號,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,554評論 0 8
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,188評論 0 13