應該在項目中用起來的 ES6 語法(一)

學習過 ES 6 有一段時間了,也在現有的項目中投入了使用,新的語法讓代碼的可讀性大大提高,這對項目的可維護性是至關重要的,在這里記錄下一些在實戰項目中比較常用的語法,以及新語法對舊語法的對比。

干凈的作用域 let, const 和 {}

以往寫 JS 最怕的就是變量污染了,當項目太大,var聲明的變量到處都是,重復聲明 console 沒有報錯,很不好調試,有了letconst,當你變量重復聲明或者犯了其他錯誤時,console 都會報錯,讓代碼更加規范:

1. 用const聲明一個常量

const URL = 'http://www.google.com'; // 不再變化,嘗試修改它會報錯

// 舊的寫法
var URL = 'http://www.google.com'; // 修改不會報錯

2. 用 let 解決 for 循環索引變化的問題

// 循環結束`i`被垃圾回收,`i`只在循環體中生效
for (let i = 0; i < 6; i++) {
    // do something
}
console.log(i); // undefined 

// 舊的寫法,循環結束后`i`的值為 5,這并不是我們期望的
for (var i = 0; i < 6; i++) {
    // do something
}
console.log(i); // 5

3. 用{}替換難以理解的閉包作用域

{
    // do someting
}

// 舊的寫法(IIFE寫法),對新手來說這個語法很不友好
(function() {
    // do someting
}());

注意:大部分場景使用的還是const,而不是let

JS 的 const 和其他語言有點小區別,當我們定義的變量后續不會再改變的時候,我們就應該使用const,只有明確了變量會改變,才會使用let

// 定義一個常量
const URL = 'http://www.lxweimin.com/api/posts/id';

// 獲取一個 dom 元素
const $modal = $('.modal'); 

// 定義一個書的實體,即使你修改了書的屬性,也是用 const
const book = {};
book.title = '圍城';
book.author = '錢鐘書';

// webpack 引入一個模塊
const vue = require('vue');

快速提取參數,變量解構賦值

解構可以理解為從指定的數組或者對象中提取數組元素或者對象屬性的值,然后賦值到指定變量中:

1. 快速交換變量

// 交換`x`, `y`和`z`的值
let x = 1, y = 2, z = 3;
[x, y, z] = [z, x, y];
console.log(x, y, z); // 3 1 2

// 舊的寫法
var x = 1, y = 2, z = 3;
var temp = x; // 臨時變量
x = z;
z = y;
y = temp;
console.log(x, y, z); // 3 1 2

2. 定義函數默認值

let fn = function({
        foo = 1,
        bar = 'foo',
        hello = false
    }) {
    console.log(foo, bar, hello);
};
fn(); // 1, foo, false

// 舊的寫法
let fn = function(foo, bar, hello) {
    var foo = foo || 1;
    var bar = bar || 'foo';
    var hello = hello || false;

    console.log(foo, bar, hello);
};
fn(); // 1, foo, false

3. 快速提取模塊中的子模塊

// ES 6 的模塊語法
import {selector, spinner} from 'Bootstrap.js'
// require.js
const { SourceMapConsumer, SourceNode } = require("source-map");

4. 遍歷時快速提取變量

const books = [{
    title: '圍城', 
    author: '錢鐘書',
}, {
    title: '三國演義',
    author: '羅貫中'
}];

{ title, author } 相當于一個 `book` 變量
books.map(({ title, author }) => console.log(title, author));

// 舊的寫法
books.map(function(book) {
    console.log(book.title, book.author); 
});

很有用的字符串擴展

JS 的字符串函數一直都是殘缺不齊的,一個indexOf用來做了太多的功能,而 ES 6 提供了很多語義化的函數來方便開發:

1. 便捷函數includes(), startsWith(), endsWith()

// 這三個函數都返回布爾值,不需要再去繁瑣的判斷`indexOf`返回的數值了
'hello world'.includes('wor'); // true
'hello world'.startsWith('he'); // true
'hello world'.endsWith('he'); // false

// 舊的寫法,代替語意不明確的indexOf
'hello world'.indexOf('wor') !== -1;

2. 模板字符串,漂亮的寫法

新的模板字符串``可以使 html 片段的引入更加美觀與規范,嵌入的變量名的形式為${var},大括號中支持js的語法,非常實用:

const basket = { count: 1, onSale: 'iPhone' };

// 模板字符串,空格和縮進都會留著,即保留格式
$('#result').append(`
    There are <b>${basket.count}</b> items
    in your basket, <em>${basket.onSale}</em> // 這里替換為變量的值
    are on sale!
    <p>${basket.count + basket.add}</p>
`);

// 舊的寫法
$('#result').append(
    'There are <b>' + basket.count + '</b> ' +
    'items in your basket, ' +
    '<em>' + basket.onSale +
    '</em> are on sale!'
);

在模板字符串中使用函數

const books = [{
    title: '圍城', 
    author: '錢鐘書',
}, {
    title: '三國演義',
    author: '羅貫中'
}];

const html = `
    <ul>
        ${ books.map(book => 
        `<li>
            <div>${ book.title }</div>
            <div>${ book.author }</div>
        </li>`
        ).join('') }
    </ul>
`
console.log(html)
/** 
    <ul>
        <li>
            <div>圍城</div>
            <div>錢鐘書</div>
        </li><li>
            <div>三國演義</div>
            <div>羅貫中</div>
        </li>
    </ul>
*/

注意:使用模板字符串要注意防止 XSS 攻擊

function escapeHtml(text) {
    var map = {
        '&': '&',
        '<': '<',
        '>': '>',
        '"': '"',
        "'": '''
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

const html = `${escapeHtml(user_input)}`;

告別不嚴謹的 Number 類型判斷

1. Number.isFinite(), Number.isNaN(), Number.isInteger()

JS 一直有個讓人詬病的地方,就是類型不夠嚴謹,就連在類型判斷上都太過于靈活,新的幾個函數輕松解決這些問題,再也不用覺得 Number 類型不夠好了:

// 判斷是否為有限數值
Number.isFinite(7); // true
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false

// 判斷是否為 NaN 類型
Number.isNaN(NaN) // true

// 判斷是否為整數
Number.isInteger(25) // true

2. 常用的數學函數,取整,判斷正負

// 去除小數部分,返回整數部分
Math.trunc(5.333); // 5

// 判斷是否為正數,負數,0
// 參數為正數,返回+1;
// 參數為負數,返回-1;
// 參數為0,返回0;
// 參數為-0,返回-0;
// 其他值,返回NaN。
Math.sign(-5) // -1

對不好用的數組說再見

1. 用Array.from()將類似數組的對象轉換為數組

// 轉換arguments
const fn = function() {
    const args = Array.from(arguments);
    args.forEach((arg) => console.log(arg)); // 數組才能用 forEach 等方法
}

// 轉換 原生 dom 返回的 NodeList
const lis = document.querySelectorAll('li');
const arrLis = Array.from(lis);
arrLis.forEach((li) => console.log(li)); // 數組才能用 forEach 等方法

// 使用拓展符也可以達到這種效果
const fn = function() {
    const args = [...arguments];
    args.forEach((arg) => console.log(arg)); // 數組才能用 forEach 等方法
}
// 轉換NodeList
const arrLis = [...document.querySelectorAll('li')];
arrLis.forEach((li) => console.log(li)); // 數組才能用 forEach 等方法

2. Array.of()快速組合數組

const x = 'wynne', y = 'zheng';
console.log(Array.of(x, y)); // ['wynne', 'zheng']

// 舊的寫法
const x = 'wynne', y = 'zheng';
const arr = [x, y]; // ['wynne', 'zheng']

3. 超級實用的查找功能 find() & findIndex(),includes()

1.find()可以通過回調函數進行數組篩選,返回該成員,而findIndex()返回索引

const books = [{
    title: '圍城', 
    author: '錢鐘書',
}, {
    title: '三國演義',
    author: '羅貫中'
}];
const item = books.find(({ title, author }) => title === '圍城');
console.log(item); // { title: '圍城', author: '錢鐘書' }

// 舊的寫法
var books = [{
    title: '圍城', 
    author: '錢鐘書',
}, {
    title: '三國演義',
    author: '羅貫中'
}];
var item = null;
books.forEach(function() {
    if (value > 3) {
        item = value;
        return;
    }
});
console.log(item); // { title: '圍城', author: '錢鐘書' }

2. 判斷是否存在于數組中,用includes()代替語意差的indexOf

const books = [{
    title: '圍城', 
    author: '錢鐘書',
}, {
    title: '三國演義',
    author: '羅貫中'
}];
console.log(arr.includes( { title: '圍城', author: '錢鐘書' } ); // true

未完待續……

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

推薦閱讀更多精彩內容