學(xué)習(xí)過 ES 6 有一段時間了逛揩,也在現(xiàn)有的項目中投入了使用,新的語法讓代碼的可讀性大大提高麸俘,這對項目的可維護性是至關(guān)重要的辩稽,在這里記錄下一些在實戰(zhàn)項目中比較常用的語法,以及新語法對舊語法的對比疾掰。
干凈的作用域 let, const 和 {}
以往寫 JS 最怕的就是變量污染了搂誉,當(dāng)項目太大,var
聲明的變量到處都是静檬,重復(fù)聲明 console 沒有報錯炭懊,很不好調(diào)試,有了let
和const
拂檩,當(dāng)你變量重復(fù)聲明或者犯了其他錯誤時侮腹,console 都會報錯,讓代碼更加規(guī)范:
1. 用const
聲明一個常量
const URL = 'http://www.google.com'; // 不再變化稻励,嘗試修改它會報錯
// 舊的寫法
var URL = 'http://www.google.com'; // 修改不會報錯
2. 用 let
解決 for
循環(huán)索引變化的問題
// 循環(huán)結(jié)束`i`被垃圾回收父阻,`i`只在循環(huán)體中生效
for (let i = 0; i < 6; i++) {
// do something
}
console.log(i); // undefined
// 舊的寫法,循環(huán)結(jié)束后`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
和其他語言有點小區(qū)別煤篙,當(dāng)我們定義的變量后續(xù)不會再改變的時候斟览,我們就應(yīng)該使用const
,只有明確了變量會改變辑奈,才會使用let
:
// 定義一個常量
const URL = 'http://www.reibang.com/api/posts/id';
// 獲取一個 dom 元素
const $modal = $('.modal');
// 定義一個書的實體苛茂,即使你修改了書的屬性已烤,也是用 const
const book = {};
book.title = '圍城';
book.author = '錢鐘書';
// webpack 引入一個模塊
const vue = require('vue');
快速提取參數(shù),變量解構(gòu)賦值
解構(gòu)可以理解為從指定的數(shù)組或者對象中提取數(shù)組元素或者對象屬性的值妓羊,然后賦值到指定變量中:
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. 定義函數(shù)默認(rèn)值
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 } 相當(dāng)于一個 `book` 變量
books.map(({ title, author }) => console.log(title, author));
// 舊的寫法
books.map(function(book) {
console.log(book.title, book.author);
});
很有用的字符串?dāng)U展
JS 的字符串函數(shù)一直都是殘缺不齊的胯究,一個indexOf
用來做了太多的功能,而 ES 6 提供了很多語義化的函數(shù)來方便開發(fā):
1. 便捷函數(shù)includes()
, startsWith()
, endsWith()
// 這三個函數(shù)都返回布爾值躁绸,不需要再去繁瑣的判斷`indexOf`返回的數(shù)值了
'hello world'.includes('wor'); // true
'hello world'.startsWith('he'); // true
'hello world'.endsWith('he'); // false
// 舊的寫法裕循,代替語意不明確的indexOf
'hello world'.indexOf('wor') !== -1;
2. 模板字符串,漂亮的寫法
新的模板字符串``
可以使 html 片段的引入更加美觀與規(guī)范涨颜,嵌入的變量名的形式為${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!'
);
在模板字符串中使用函數(shù)
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)}`;
告別不嚴(yán)謹(jǐn)?shù)?Number 類型判斷
1. Number.isFinite()
, Number.isNaN()
, Number.isInteger()
JS 一直有個讓人詬病的地方,就是類型不夠嚴(yán)謹(jǐn)弹灭,就連在類型判斷上都太過于靈活督暂,新的幾個函數(shù)輕松解決這些問題,再也不用覺得 Number
類型不夠好了:
// 判斷是否為有限數(shù)值
Number.isFinite(7); // true
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
// 判斷是否為 NaN 類型
Number.isNaN(NaN) // true
// 判斷是否為整數(shù)
Number.isInteger(25) // true
2. 常用的數(shù)學(xué)函數(shù)穷吮,取整逻翁,判斷正負(fù)
// 去除小數(shù)部分,返回整數(shù)部分
Math.trunc(5.333); // 5
// 判斷是否為正數(shù)捡鱼,負(fù)數(shù)八回,0
// 參數(shù)為正數(shù),返回+1驾诈;
// 參數(shù)為負(fù)數(shù)缠诅,返回-1;
// 參數(shù)為0乍迄,返回0管引;
// 參數(shù)為-0,返回-0;
// 其他值闯两,返回NaN褥伴。
Math.sign(-5) // -1
對不好用的數(shù)組說再見
1. 用Array.from()
將類似數(shù)組的對象轉(zhuǎn)換為數(shù)組
// 轉(zhuǎn)換arguments
const fn = function() {
const args = Array.from(arguments);
args.forEach((arg) => console.log(arg)); // 數(shù)組才能用 forEach 等方法
}
// 轉(zhuǎn)換 原生 dom 返回的 NodeList
const lis = document.querySelectorAll('li');
const arrLis = Array.from(lis);
arrLis.forEach((li) => console.log(li)); // 數(shù)組才能用 forEach 等方法
// 使用拓展符也可以達(dá)到這種效果
const fn = function() {
const args = [...arguments];
args.forEach((arg) => console.log(arg)); // 數(shù)組才能用 forEach 等方法
}
// 轉(zhuǎn)換NodeList
const arrLis = [...document.querySelectorAll('li')];
arrLis.forEach((li) => console.log(li)); // 數(shù)組才能用 forEach 等方法
2. Array.of()
快速組合數(shù)組
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()
可以通過回調(diào)函數(shù)進行數(shù)組篩選漾狼,返回該成員重慢,而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. 判斷是否存在于數(shù)組中,用includes()
代替語意差的indexOf
const books = [{
title: '圍城',
author: '錢鐘書',
}, {
title: '三國演義',
author: '羅貫中'
}];
console.log(arr.includes( { title: '圍城', author: '錢鐘書' } ); // true
未完待續(xù)……