## 三、const和let

**3.1 const**

const用来定义常量,所谓的常量就是值一旦给定后就不变,一次定义终身不变的量
const a = 10; a = 20;
上面的a就是一个常量,若给a重新赋值,你会发现报错了 注意:
const通常会定义两种东西:
l 定义函数
l 定义一些特殊的字符串和常数
常量名一般都是全大写,如果由多个单词组成,用下划线隔开,暗示这个是常量

**3.2 let**
let用来定义块级作用域的变量,只要有“{}”包裹,就表示块级作用域。
*注意:不是JSON,if语句体、函数体、while、for是块,for循环的()也是块
注意:我们通常会在for使用let,此时循环中自动加了闭包*:

var arr = [];
for(let i = 0; i < 10;i++){
arr.push(function(){
console.log(i);
});
}
arr[4](); //4

let和for是绝配,let平时没啥用。
var声明的变量,在for循环之外可以访问,导致i变量到最终值的时候,arr[4]()虽然是闭包访问,但是同一个i,所以i就是一个统一的值。
而let相当于每一次都有不同的i,都是新的i,但是i是可以访问上一次的自增或自减的值。

**总结:
**l const用来定义常量,通常定义函数和常数
l let用来定义{}块级的作用域的变量,通常用来定义for循环的变量
常量是块级作用域,很像使用let,语句定义的变量,常量的值不能通过重新赋值来改变,并且不能重新声明。****

## **四、变量的解构赋值**

**4.1数组解构**
数组可以解构,当等号右侧是数组的时候,等于左侧可以将变量装入[]中接收,一一对应接收。

var [a,b,c] = [1,2,3];
console.log(a); //1
console.log(b); //2
console.log(c); //3

上面代码表示,可以从数组中提取值,按照对应位置,给变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

如果数组较为复杂,此时左侧结构的那些变量,也要有相同的结构:

var [a,b,[c,d]] = [1,2,[3,4]];
console.log(a); //1
console.log(b); //2
console.log(c); //3
console.log(d); //4

如果结构不同呢?

var [a,b,c] = [1,2,[3,4]];
console.log(a); //1
console.log(b); //2
console.log(c); //[3,4]

另外一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组,这种情况解构依然可以成功。

var [a, [b], d] = [1, [2, 3], 4];
console.log(a); // 1
console.log(b); // 2
console.log(d); // 4
如果解构不成功,变量的值等于undefined

**4.2对象解构**
对象的结构和数组有个不同点,数组的元素是按顺序排列的,数组的取值由他的位置决定。
而对象的属性(键名)没有顺序,但是变量必须与属性同名,才能取到正确的值。

var {name,id,sex} = {"id":1001,"name":"张三","sex":"男"};
console.log(id); //1001
console.log(name); //张三
console.log(sex); //男

上面的例子,等号左边的变量顺序与等号右边3个同名属性的顺序不一致,但是对取值完全没影响
如果变量没有对应的同名属性,导致取不到值,所以是undefined。
如果变量名和属性名不一致,必须写成下面这样:

var {foo: baz} = {foo : 'aaa', bar : 'bbb'}
console.log(baz); //aaa

var {first :f ,last :l} = {first :'hello', last :'world'}
console.log(f); //hello
console.log(l) //world

这实际上说明,对象的解构赋值是上面形式的简写
上面代码中,foo是匹配模式,baz才是变量,真正被赋值的是变量baz,而不是模式foo。
也就说,对象的解构的内部机制,是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者。

**4.3默认值**
结构赋值允许指定默认值

var [a = 1] = []
var [b = 1] = [88]
console.log(a);//1
console.log(b);//88
var [c = 1] = [undefined]
var [d = 1] = [null]
console.log(c);//1
console.log(d);//null

注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值,所以,只有当一个数组成员严格等于undefined,默认值才会生效
如果一个数组值是null,默认值不会生效,因为null不严格等于undefined。

**4.4扩展运算符(spread operator)**
扩展运算符(spread)是三个点(...)。将一个数组转为用逗号分隔的参数序列,还能强制展开一个对象,通常用于对象的赋值,使用灵活广泛。

l 第一个作用:称为“展开运算符”,作用和字母意思用于,就是把东西展开,可以用在数组和对象上。

var obj1 = {
"a" :100,
"b" :200,
"c" :300,
}
var obj2 = {
...obj1,
"d" :888
}
console.log(obj1)
console.log(obj2)
console.log(obj1 === obj2);

数组也可以强制展开,通常数组的赋值,比如有两个数组合成一个数组:

**4.5剩余操作符(rest operator)**
l 第二、三个作用:叫“剩余操作符”是解构的一种,意思是把剩余的参数放到一个数组中赋值给它。一般针对数组或对象。

var [a,b,...c] = [1,2,3,4,5,6];
console.log(a);//1
console.log(b);//2
console.log(c);//[3,4,5,6]

注意“...”只能出现最后一个参数,并且通过这个例子发现...能将零散的值收纳为数组。
逻辑上,“...”是一个运算符。“...”能将数组打散为零散值。

l 补充个知识点,在ES6中当一个对象的key和value一致时,可以省略value。

**l 应用场景2:**
以后的函数大概率都是接收一个JSON当参数,并且用ES6解构语法写形参变量。
调用函数的时候传的参数,一般是k:v,省略v

var name = "小明";
var height = 170;
var weight = 100;

function mm({height,name,weight}){
console.log("姓名是:" + name)
console.log("身高是:" + height)
console.log("体重是:" + weight)
};

// mm({name:name,"height":height,"weight":weight})
mm({name,height,weight})

红色部分的语句是在创建JSON,绿色的部分是在进行结构。
调用函数时参数顺序打乱也不影响结构,因为解构,会自动匹配key。
()
**l 展开运算符和剩余操作运算符的区别**
关于展开运算符与剩余操作符的直之间的区别,简单的说,在某种程度上,剩余操作符和展开运算符相反,展开运算符会“展开”数组变成多个元素,剩余操作符会收集多个元素和“压缩”成一个单一的元素。

**4.6对象解构的翻译问题**
注意:babel会将“[]”和“{}”解构变为一个个的var。
但是babel不能翻译“对象解构”,只能翻译数组解构。
原因:object-rest-spread 还处于stage阶段(属于实验性属性)。
解决方法:安装babel插件transform-rest-spread,放到.babelrc文件配置上,即可使用。

{
"presets":["es2015","es2016"],
"plugins":["transform-object-rest-spread"]
}
.babelrc的presets是用来定义预设,plugins定义插件。
安装依赖:
cnpm install babel-plugin-transform-object-rest-spread

**

## 五、数组方法

**
ES6中对数组新增了四大“金刚”函数:forEach()、map()、filter()、reduce(),都是一些语法糖。forEach()是es5语法
**5.1 forEach()遍历数组**
forEach()方法用来循环遍历数组,方法中的function回调函数接收3个参数
第1个是遍历的数组内容(item);第2个是对应的数组索引(index),第3个是数组本身(array)。

var arr = ["白板","幺鸡","红中","发财","三饼"];
arr.forEach(function(item,index,array){
console.log(item,index,array)
});
注意:forEach()没有return返回值。

**5.2 map()映射**
map方法的作用不难理解,“映射”也就是原数组被“映射”成对应的新数组。

var arr = [10,20,30,40,50,99];
var newArr = arr.map(function(item,index,array){
return item * 2; //返回一个新的结果,给变量接收,原数组不变
});

map函数的本质是依次遍历原数组的每一项,将每一项都执行一遍函数中的语句,返回一个新的数组。
注意:
l 函数需要有return值,如果没有,数组所有项都被映射成undefined。
l map返回的数组一定和原数组的长度一样。
l
在实际使用时,可以利用map()方便获取对象数组中的特定属性值们
**5.3 filter()过滤**
filter为“过滤、筛选”之意,指原数组中filter某些项后,返回过滤后的新数组,用法和map相似。
比如想从原数组中,挑选所有的偶数,返回新的数组。

var arr = [312,55,77,11,13,15,18,26,30,40,50,99];
var newArr = arr.filter(function(item,index,array){
return item % 2 == 0;
});
console.log(arr)
console.log(newArr)

描述:arr中的每一项会依次的执行函数,filter的callback函数需要返回布尔值true或false。true则将值放到新数组中,false无情地将你抛弃…
l filter和map相同点:都会遍历数组的每一项
l filter和map不同点:map返回数组不会少项,filter可能少项。

**5.4 reduce()迭代**

arr.reduce(callback[,initialValue])
第一个参数的callback回调函数有四个参数,第二个为设定的初始值(可选)。
callback函数有四个参数:
previous :上一次叠加的结果值或初始值
current : 当前会参与叠加的项
index :当前值的下标
array :原数组本身

求数组的最大值【经典面试】:
var arr = [43,5,4,6,4567,78,8,69,568];
// var max = Math.max.apply(null,arr);
// console.log(max)

var max = arr.reduce(function(prev,cur){
console.log(prev) //43、43、43、43、4567、4567、4567...
return prev > cur ? prev : cur;
});
console.log(max); //4567

reduce的机理:从下标1的项开始遍历,每次return的值将作为遍历的下一项的prev的值,这一次的遍历是cur,prev有种累加的感觉。
reduce可以设置初始参数(参数自定义),当reduce有第二个参数时,此时reduce遍历将从第0项开始遍历,而不是第1项开始。

**5.5数组用途-写纯函数**
上面的四大“金刚”map、filter、reduce特别有用,做“函数式”编程。
什么是纯函数?
纯函数是指不依赖于且不改变它作用域之外的变量状态的函数。
l 这个函数内部不改变传入的参数。
l 传入这个函数一定有参数,一定会返回某一个确定的值。
l 函数中的语句,不能有随机性,比如Math.random()、new Date(),传入的参数相同,返回的值必定相同;
l 这个函数里面不能有任何异步语句,比如$.get()、fs.readFile()、setInterval()

**l【例子1】请写一个纯函数addItem(),接收arr、n当做参数,能够将arr的尾部增加n。**

var arr = [99,77,66];
function addItem(arr,n){
return [...arr,n];
}
var arr2 = addItem(arr,88); //返回一个新数组
console.log(arr); //原数组不变
console.log(arr2);

**【例子4】请写一个纯函数changeItem,接受arr、n、a当做参数,能够将arr第下标为n的那项改变值为a。**

var arr = ["白板","幺鸡","二条","三万"];
function changeItem(arr,n,a){
return arr.map((item,index)=> index == n ? a : item )
}
var arr2 = changeItem(arr,2,"九条");
console.log(arr);
console.log(arr2);

**l 纯函数的条件:**
l 一个函数的返回结果只依赖于它的参数
l 不依赖外部状态
l 执行过程中没有副作用

**什么叫函数执行过程没有副作用?**
一个函数执行过程中对外部产生了编号,那么就说这个函数是有副作用的。

l 更改指定id的name属性

const changeName = function(arr,id,name){
return arr.map(function(item){
if(item.id == id){
return {...item,name}
}
return item;
});
}

var jieguo = changeName(arr,2,"小兰")
console.log(jieguo);

顺口溜:删filter、改map、增map或...

**总结
为什么要煞费苦心地构建纯函数?因为纯函数非常“靠谱”,执行一个纯函数你不用担心它会干什么坏事,它不会产生不可预料的行为,也不会对外部产生影响。不管何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会非常方便。
l 使用纯函数的好处
最主要的好处是没有副作用。纯函数不会修改作用域之外的状态,做到这一点,代码就变得足够简单和清晰:当你调用一个纯函数,你只要关注它的返回值,而不用担心因为别处的问题导致错误。

纯函数是健壮的,改变执行次序不会对系统造成影响,因此纯函数的操作可以并行执行。
纯函数非常容易进行单元测试,因为不需要考虑上下文环境,只需要考虑输入和输出。

函数是接受一些输入,并产生一些输出的过程。这些输入称为参数,输出称为返回值。
纯函数的返回值只由它调用时的参数决定,它的执行不依赖于系统的状态(比如:何时、何处调用它)。**

ES6学习笔记第一天的更多相关文章

  1. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  2. ES6学习笔记之变量的解构赋值

    变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...

  3. ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能

    前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...

  4. JS&ES6学习笔记(持续更新)

    ES6学习笔记(2019.7.29) 目录 ES6学习笔记(2019.7.29) let和const let let 基本用法 let 不存在变量提升 暂时性死区 不允许重复声明 块级作用域 级作用域 ...

  5. ActionBarSherlock学习笔记 第一篇——部署

    ActionBarSherlock学习笔记 第一篇--部署          ActionBarSherlock是JakeWharton编写的一个开源框架,使用这个框架,可以实现在所有的Android ...

  6. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  7. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  8. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  9. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

随机推荐

  1. 微信小程序-- WXML语法

    页面数据 test.js test.wxml 运行结果:

  2. python 中初始化二维数组的方法

    最好的方法是: 初始化4*3的二维数组 a = [[0 for col in xrange(3)] for row in xrange(4)] 而不可以用: a = [[0]*3]*4 [0]*3是生 ...

  3. B站直播 DEMO ijkplayerDemo

    http://blog.csdn.net/kengsir/article/details/51750879 一. 下载ijkplayer ijkplayer下载地址 下载完成后解压, 解压后文件夹内部 ...

  4. 洛谷 P1858 多人背包 DP

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 洛谷 P1858 多人背包 题目描述 求01背包前k优解的价值 ...

  5. Leetcode674.Longest Continuous Increasing Subsequence最长连续递增序列

    给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3. 尽管 [1,3,5,7] 也 ...

  6. vs2015卸载、vs2008安装Visual Assist x

    卸载2015 参考博文 1. 手动卸载VS2015的主要部分: win10系统: 控制面板---程序和功能--Microsoft Visual Studio 2015---更改卸载 2. 下载工具并解 ...

  7. VM虚拟机下安装无线网卡教程

    前言: 由于最近学习olsrd需要,然后需要无线网卡支持.所以将教程分享如下. 实体机:Windows 7 虚拟机:Ubuntu 14.04 无线网卡:Tenda W311M V3.0 虚拟机软件:V ...

  8. JavaScript实现,控制一个文本框只能输入正整数,如输入不符合条件则文本框全部字体标红

    腾讯2014年研发职位笔试题Web前端方向简单题第一题. 代码: <html> <head> <title>test JavaScript</title> ...

  9. 杨柳目-杨柳科-Info-新闻:让中国人焦虑的杨絮背后,隐藏着“拯救”北京的秘密!

    ylbtech-杨柳目-杨柳科-Info-新闻:让中国人焦虑的杨絮背后,隐藏着“拯救”北京的秘密! 1.返回顶部 1. 春天来了,北京和其他很多城市满城飞絮的日子也到了.库叔作为敏感体质,不得不戴上口 ...

  10. 【Leetcode堆】数据流中的第K大元素(703)

    题目 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数 ...