(一)let和const命令

第一章

es6标准入门这本书我读了好几遍,都是比较易懂的语法糖,但是每次读都有新的体会。为了能在新的工作中用到它,从入职跟谁学之前突击看了一遍算起,已经用ES6实战了10个月。借助这次跟大家分享机会,重新整理,把我的心得体会和理解分享给大家,希望对我和对大家都有收获。

草案阶段

Stage 0 - Strawman(展示阶段)      

Stage 1 - Proposal(征求意见阶段)

Stage 2 - Draft(草案阶段)

Stage 3 - Candidate(候选人阶段)

Stage 4 - Finished(定案阶段)

一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。

认识Babel

配置文件.babelrc

{
    "presets": ["es2015", "react", "stage-0"],
    "plugins": [
        "transform-es2015-modules-amd"
    ],
    "env": {
        "build": {
            "optional": ["optimisation", "minification"]
        }
    }
}

这个是BOSS系统的一个配置文件

第二章 let 和const 命令

1、什么是状态提升

1)变量的声明被提升到函数顶部
2)初始化操作仍旧留在原处执行
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();

请仔细观察输出值,为什么?

ES6中,通常用let和set声明,let表示变量,const表示常量。

1)let和const都是块级作用域
2)不存在状态提升
3)const声明不允许修改绑定,但是允许修改值。

const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const obj = {name:'liang'};
obj.name='zhang';

2、块级作用域 特点

1)在一个函数内部
2)在一个代码块内部
3)离开作用作用域,立刻销毁
4)不允许重复声明

实例:

let abc = 1;
{
    let abc = 3;
    console.log('{}'+abc);
}

可以任意嵌套
{{{{{let insane = 'Hello World'}}}}};

{{{{
  {let insane = 'Hello World'}
  console.log(insane); // 报错
}}}};

不允许重复声明

// 报错
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块级作用域写法
{
  let tmp = ...;
  ...
}

4、临时性死区(TDZ Tempporal Dead Zone)

// if (true) {
//   // TDZ开始
//   tmp = 'abc'; // ReferenceError
//   console.log(tmp); // ReferenceError

//   let tmp; // TDZ结束
//   console.log(tmp); // undefined

//   tmp = 123;
//   console.log(tmp); // 123
// }

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

怎样避免暂时性死区
1)良好的编码习惯
2)避免重复的命名

5、循环中的块作用域绑定

回顾红宝书for循环中的实例
我们还可以在循环中使用,最出名的一道面试题:循环中定时器闭包的考题
在for循环中使用var声明的循环变量,会跳出循环体污染当前的函数。

for(var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i) //5, 5, 5, 5, 5
  }, 0)
}
console.log(i) //5 i跳出循环体污染外部函数

//将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无法污染外部函数

5.1、循环中的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、循环中的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不报错?

总结
1)for-in for-of中let和const表现一致
2)for循环中的特例

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;
// 暂时死区问题
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);

最佳实践

在实际开发中,我们选择使用var、let还是const,取决于我们的变量是不是需要更新,通常我们希望变量保证不被恶意修改,而使用大量的const,在react中,props传递的对象是不可更改的,所以使用const声明,声明一个对象的时候,也推荐使用const,当你需要修改声明的变量值时,使用let,var能用的场景都可以使用let替代。

你可能感兴趣的:((一)let和const命令)