浅谈ES6

<b>1.var、let、const声明变量,有什么区别?</b>

<b>(1)作用域:</b>
<b>var</b> 声明的变量不用多说,我们之前写js都是用这个来声明,但很少有人理解它的作用域,可以这样来说,var声明的变量属于<b>function scope(方法作用域)</b>,可以简单的这样理解:如果一个变量用var定义且只在方法体中被声明过,那么这个变量就是局部变量,反之便是全局变量。可这样有时候并不是我们想要的,比如:

var a = 0;
if (a < 5){
  var b = 'Madman';
  console.log(a);  //0
  console.log(b); //Madman
}
console.log(a); //0
console.log(b); //Madman

我们发现,这四个都能打印出来对应的值。a 就不用多说了, b虽然被定义在 if 语句中,但是使用 var 定义,并没有在方法体内,所以 b 也是全局变量,然而我们只是想在这里被使用一次。ES6为了弥补这一不足,引入了 let 以及 const 。

<b>let 和 const :</b> 这两个在 ES6 中同样定义变量,但是它们属于 <b>block scope(块级作用域)</b>,这个其实很好理解,如果上面例子中的 b 使用 let \ const 来定义,那么最后一个 console 会报 not defined 。因为 if 循环算是一个块级区域。

<b>(2)重复声明:</b>
var 可以重复声明同一个变量名,而 let 和 const 在同一个作用域下,只能被声明一次。

var a = 'Madman';
var a = '疯子';
let b = '李小呆';
let b = '哈哈哈';  //  错误
const c = 'php';
if(a == 'Madman'){
  const c = 'java';
}
console.log(c);  // php

上面例子中我们可以看到,在同一个作用域下不能用 let 和 const 声明相同名称的变量,所以在全局中使用 let 声明第二次 b 的时候,会报错;而我用 const 定义了两次变量 c ,但是它们不在同一个作用域下,故是两个变量。

<b>(3)重新赋值</b>
说一下 let 和 const 的区别,let 声明的变量是可以重新赋值的 ,而 const 声明的变量不可以重新赋值。
当然,如果只是单纯这样说的话表达的不是很明白,举个例子吧:

let a = 'Madman';
a = '李小呆'; 
const b = '哈哈哈';
b = '呵呵呵';  //错误!不可以被重复赋值

当然,const 声明的变量只是没办法重新赋值,但有一种情况却是可以:

const person = {
  name : 'Madman',
  age : 23
}
person = {
  name : '李小呆'
}   //错误
person.age = 18 ;
console.log(person);   //{name : 'Madman', age : 18} 
//可以看出,person对象的 age 属性被成功的修改。

person 是一个对象,对象是一种引用类型的值,当我给它赋值一个新的对象的时候,其实这个指针就指向了新的引用地址;而如果我们只是改变对象里的属性的话,这个对象本身的引用地址并没有发生变化。
如果连对象的属性都不想让它变化,那就使用const Madman = Object.freeze(person)

<b>2.let 和 const 经常会被用在哪些地方?</b>

<b>(1)for 循环</b>
在接触 ES6 之前呢,我们经常用到的 for 循环都是通过 var 来定义循环的次数的,比如:

for ( var v = 0; v<10 ; v++){
  console.log(v);
}

很明显,上面代码输出的结果是0到9;那么我们如果使用setTimeout(function(){})模拟一下ajax请求;

for ( var v = 0; v<10 ; v++){
  console.log(v);
  setTimeout(function(){
    console.log(`v:${v}`);
  })
}

此时,我们看到被 var 定义的变量 v 在 for 循环之后被打印了十次;可我们想让它输出像上面一样的结果,而并非 for 执行完之后再去执行setTimeout里面的语句;
那么,我们把 var 改成 let 试试:



可以看到,结果如我们所愿,为什么呢?
其实非要讲真正的原理我也不是很理解,但你可以这样理解,被let 定义的变量 v ,此时属于块级作用域,它只在一个 for 循环块中有效,所以每次结束这个块时,它都会等setTimeout执行完并输出v。

<b>(2)变量提升</b>
我们先来看一段代码:

<script>
  console.log(color);  //undefined
  var color = 'blue';
</script>

这里为什么是undefined? 熟悉的人会知道在 js 中会有变量提升这以说法,那么什么是<b>变量提升?</b>

  • JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
  • JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
  • JavaScript 只有声明的变量会提升,初始化的不会。

说了这么多,什么意思呢?其实上面的代码就相当于:

var color;  //定义的变量被提升到代码的最顶部
console.log(color);  //这个时候输出,js 能找到color 这个变量,但是这个变量没被初始化值,所以是undefined
color = 'blue';  //声明被提升到了代码的顶部,但是初始化仍在console 后面。

那么,如果换成 let 或者 const 呢?

console.log(userName);
let userName = 'Madman';

为什么?我们来看看gitHub上的解释:



通俗来说,这种现象叫做hoist,在 var 中有,同样在 let/const 中也有。

就和上面所提及到的一样,在声明代码之前使用后面用 var 声明的变量会返回一个 undefined,这个值是默认的在初始化的时候赋进去的。

但是如果是在声明之前使用后面会用 let/const 声明的变量会抛出一个错误。这个因为变量在声明代码之前是不可用的(没有被初始化)。进入作用域和使用作用域的值得这段时期就叫做时间死区(Temporal Dead Zone)。

注解:
时间死区(Temporal Dead Zone): 在进入一个scope之后,let/const也会有一个hoist,这个过程和var 一样,区别是 var 在hoist之后,被初始化为了 undefined,但是let/const没有初始化,直到真正声明它的地方。

<b>3.箭头函数</b>

ES6 推出的箭头函数有四个特点:

  • 简明的语法;
const arr1 = [5,8,10,12,15];
const arr2 = arr1.map(function (arr) {
    return arr*2;
});
console.log(arr2);
const arr3 = arr1.map((arr) => { //箭头函数
    return arr*2;
});
console.log(arr3);
const arr4 = arr1.map(arr => { //箭头函数,单个参数可以不要那一对括号
    return arr*2;
});
console.log(arr4)
const arr5 = arr1.map((arr,i) => { //箭头函数,多个参数用逗号分割
    return `${i} : ${arr *2}`;
});
console.log(arr5);
  • 可以隐士返回;
const arr1 = [5,8,10,12,15];
const arr2 = arr1.map((arr) => {
  return arr*2;  //  像这种带有return 的被称为显示返回
})
const arr3 = arr1.map((arr) => arr*2);
//这中把代码写在一行,不写return 以及去掉 '{}' 的被称为隐式返回;
  • 箭头函数都是匿名函数
function sayName(name){
  alert(`hi,${name}`);
}
sayName('Madman'); //很显然,这是一个命名函数

//那如何用箭头函数来实现呢?一般我们把箭头函数赋给一个变量
const sayHi = name => alert(`hi,${name}`);
sayHi('Madman');

const a = 0;
const hh = a => {
                if(a<5) {
                    alert(a);
                }
            }
 hh(a);
//其实这样看起来怪怪的 -O-
  • this 的理解;
const madman = {
            name : 'Madman',
            hobbies :['睡觉','吃饭','打豆豆'],
            printHobbies :function () {
                this.hobbies.map(function(hobby){ //这里的this会指向madman
                   console.log(`${this.name} love ${hobby}`); //这里的this会指向windows对象
                });
            }
        };
madman.printHobbies()

来看一下控制台的结果:


可以发现,this.name 并没有被打印出来。那么我们来试试箭头函数:

const madman = {
            name : 'Madman',
            hobbies :['睡觉','吃饭','打豆豆'],
            printHobbies :function () {
                this.hobbies.map((hobby) =>{
                   console.log(`${this.name} love ${hobby}`);
                });
            }
        };
madman.printHobbies();

来看一下控制台的结果:



为什么呢?
<b>因为箭头函数没有自己的 this 值,它的 this 值是继承它的父作用域。</b>

<b>4.参数默认值</b>

之前,我们一般调用方法的时候会给参数一个默认值,比如:

function multiply(a,b){
  a = a || 3;
  b = b || 5;
  return a * b;
}

那么,我们来看一下ES6是如何给参数赋默认值的;

function multiply(a = 3, b = 5){ //是不是很简单明了且具有可读性
  return a * b;
}
multiply();  //15
multiply(1,1);  //1
multiply(2);  //10
multiply(undefined,2);  //6 ,这里底层是通过判断typeof === 'undefined' ? 默认值 || 其他
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容