第一章
es6標(biāo)準(zhǔn)入門這本書我讀了好幾遍檬果,都是比較易懂的語法糖,但是每次讀都有新的體會。為了能在新的工作中用到它选脊,從入職跟誰學(xué)之前突擊看了一遍算起,已經(jīng)用ES6實戰(zhàn)了10個月脸甘。借助這次跟大家分享機會恳啥,重新整理,把我的心得體會和理解分享給大家丹诀,希望對我和對大家都有收獲钝的。
草案階段
Stage 0 - Strawman(展示階段)
Stage 1 - Proposal(征求意見階段)
Stage 2 - Draft(草案階段)
Stage 3 - Candidate(候選人階段)
Stage 4 - Finished(定案階段)
一個提案只要能進入 Stage 2,就差不多肯定會包括在以后的正式標(biāo)準(zhǔn)里面铆遭。
認(rèn)識Babel
配置文件.babelrc
{
"presets": ["es2015", "react", "stage-0"],
"plugins": [
"transform-es2015-modules-amd"
],
"env": {
"build": {
"optional": ["optimisation", "minification"]
}
}
}
這個是BOSS系統(tǒng)的一個配置文件
第二章 let 和const 命令
1硝桩、什么是狀態(tài)提升
1)變量的聲明被提升到函數(shù)頂部
2)初始化操作仍舊留在原處執(zhí)行
console.log(s);
var s = 2;
console.log(s);
function a() {
if(false) {
var str ;
str='liang';
console.log(str);
} else {
console.log(str);
}
}
a();
請仔細(xì)觀察輸出值,為什么枚荣?
ES6中碗脊,通常用let和set聲明,let表示變量橄妆,const表示常量衙伶。
1)let和const都是塊級作用域
2)不存在狀態(tài)提升
3)const聲明不允許修改綁定,但是允許修改值害碾。
const 實際上保證的矢劲,并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址所保存的數(shù)據(jù)不得改動慌随。對于簡單類型的數(shù)據(jù)(數(shù)值芬沉、字符串、布爾值)阁猜,值就保存在變量指向的那個內(nèi)存地址丸逸,因此等同于常量。但對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組)蹦漠,變量指向的內(nèi)存地址椭员,保存的只是一個指向?qū)嶋H數(shù)據(jù)的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址)笛园,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的隘击,就完全不能控制了。因此研铆,將一個對象聲明為常量必須非常小心埋同。
const obj = {name:'liang'};
obj.name='zhang';
2、塊級作用域 特點
1)在一個函數(shù)內(nèi)部
2)在一個代碼塊內(nèi)部
3)離開作用作用域棵红,立刻銷毀
4)不允許重復(fù)聲明
實例:
let abc = 1;
{
let abc = 3;
console.log('{}'+abc);
}
可以任意嵌套
{{{{{let insane = 'Hello World'}}}}};
{{{{
{let insane = 'Hello World'}
console.log(insane); // 報錯
}}}};
不允許重復(fù)聲明
// 報錯
function func() {
let a = 10;
var a = 1;
}
// 報錯
function func() {
let a = 10;
let a = 1;
}
function func(arg) {
let arg; // 報錯
}
function func(arg) {
{
let arg; // 不報錯
}
}
3凶赁、es5的塊級作用域是怎么樣的
(function () {
var tmp = ...;
...
}());
// es6塊級作用域?qū)懛?{
let tmp = ...;
...
}
4、臨時性死區(qū)(TDZ Tempporal Dead Zone)
// if (true) {
// // TDZ開始
// tmp = 'abc'; // ReferenceError
// console.log(tmp); // ReferenceError
// let tmp; // TDZ結(jié)束
// console.log(tmp); // undefined
// tmp = 123;
// console.log(tmp); // 123
// }
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
怎樣避免暫時性死區(qū)
1)良好的編碼習(xí)慣
2)避免重復(fù)的命名
5、循環(huán)中的塊作用域綁定
回顧紅寶書for循環(huán)中的實例
我們還可以在循環(huán)中使用虱肄,最出名的一道面試題:循環(huán)中定時器閉包的考題
在for循環(huán)中使用var聲明的循環(huán)變量致板,會跳出循環(huán)體污染當(dāng)前的函數(shù)。
for(var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i) //5, 5, 5, 5, 5
}, 0)
}
console.log(i) //5 i跳出循環(huán)體污染外部函數(shù)
//將var改成let之后
for(let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i) // 0,1,2,3,4
}, 0)
}
console.log(i)//i is not defined i無法污染外部函數(shù)
5.1咏窿、循環(huán)中的let聲明
var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
})
}
funcs.forEach(function(func) {
func();
});
const Obj = {
id:1,
name:'liang'
}
for(let i in Obj){
console.log(i);
}
const iterable = ['mini', 'mani', 'mo'];
for (let value of iterable) {
console.log(value);
}
5.2斟或、循環(huán)中的const聲明
var funcs = [];
for (const i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
})
}
funcs.forEach(function(func) {
func();
});
// 錯誤
const Obj = {
id:1,
name:'liang'
}
for(const i in Obj){
console.log(i);
}
const iterable = ['mini', 'mani', 'mo'];
for (const value of iterable) {
console.log(value);
}
為什么for-in 和for-of中用const不報錯?
總結(jié)
1)for-in for-of中l(wèi)et和const表現(xiàn)一致
2)for循環(huán)中的特例
for(let i =0;i<10;i++){
console.log(i);
}
for(let i =0;i<10;i++){
const i = 'abc';
console.log(i);
}
var tmp = 123;
// 暫時死區(qū)問題
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
//正常
let i = 2;
if(i){
let i =3;
console.log(i);
}
let tmp = 123;
if (tmp) {
let tmp = 456;
console.log(tmp);
}
6集嵌、全局塊作用域綁定
//瀏覽器中演示
var abc = 'liang';
console.log(window.abc);
console.log(window.abc === abc)
let abc = 'liang';
console.log(window.abc);
console.log(window.abc === abc)
7萝挤、跨模塊常量
兩種方式
import moment from 'moment';
const yyyyMMdd = 'yyyy-MM-dd';
const YYYYMMDD = 'YYYY-MM-DD';
const YYYYMMDDHHmmss = 'YYYY-MM-DD HH:mm:ss';
const CHINAYYYYMMDDHHmmss = 'YYYY年MM月DD日 HH:mm:ss';
const YYYYMMDDHHmm = 'YYYY-MM-DD HH:mm';
const HHmmss = 'HH:mm:ss';
const HHmm = 'HH:mm';
const CHINAMMDD = 'MM月DD日';
const dateFormat = {
yyyyMMdd: (date) => {
return moment(date).format(yyyyMMdd);
},
YYYYMMDD: (date) => {
return moment(date).format(YYYYMMDD);
},
YYYYMMDDHHmmss: (date) => {
return moment(date).format(YYYYMMDDHHmmss);
},
CHINAYYYYMMDDHHmmss: (date) => {
return moment(date).format(CHINAYYYYMMDDHHmmss);
},
CHINAMMDD: (date) => {
return moment(date).format(CHINAMMDD);
},
YYYYMMDDHHmm: (date) => {
return moment(date).format(YYYYMMDDHHmm);
},
HHmmss: (date) => {
return moment(date).format(HHmmss);
},
HHmm: (date) => {
return moment(date).format(HHmm);
},
toMoment: (date) => {
return moment(date);
},
timeStampMillisecond: (date) => {
return +moment(date);
},
};
const fenToYuan = function (num) {
if (typeof num !== 'number' || isNaN(num)) {
return null;
} else if (num === 0) {
return 0;
}
return (num / 100).toFixed(2);
};
export { dateFormat, fenToYuan };
export const A = 1;
export const B = 2;
8、案列
const self = this;
const { mobile, followupName, startTime, endTime, type } = self.state.searchParams;
const omobile = mobile || '';
const ofollowupName = encodeURI(followupName || '');
const ostartTime = startTime || '';
const oendTime = endTime || '';
const otype = (type === undefined || type === null) ? '&type=' : self.handleType(type);
最佳實踐
在實際開發(fā)中根欧,我們選擇使用var怜珍、let還是const,取決于我們的變量是不是需要更新凤粗,通常我們希望變量保證不被惡意修改酥泛,而使用大量的const,在react中侈沪,props傳遞的對象是不可更改的揭璃,所以使用const聲明,聲明一個對象的時候亭罪,也推薦使用const瘦馍,當(dāng)你需要修改聲明的變量值時,使用let应役,var能用的場景都可以使用let替代情组。