ES6笔记分享 part 1
ECMAScript ES6 从一脸懵逼到灵活运用
var let const
var let const 的比较
声明与赋值
var
声明的变量是可以重新赋值的,也可以重复声明let
和const
声明的变量都是不可以重复声明的 即使在不同作用域内可以出现同名变量,但并不相同,只能在各自的作用域中使用
不同的是,
let
声明的变量是可以重新赋值的,但const
不行 注意:用
const
声明的变量并不是完全不可以改变的 如果用
const
来声明一个对象,虽然无法给这个对象重新赋值,但是我们可以改变对象的属性值(对象是引用类型变量,只改变对象的属性并不会影响指针指向) 如果你也不希望改变属性值的话可以使用
Object.freeze()
方法
变量作用域
var
为function scope即函数作用域在函数中声明的变量只能在函数中使用,否则就是一个全局变量
如果在在
if
和for
等语句里定义的变量你只希望在内部使用,var
就无法满足,因为它没有在函数里声明,所以会变成一个全局变量,污染全局作用域let
和const
是block scope即块级作用域一对大括号 { } 所包裹的内容即为一个块级作用域,声明的变量只能在块内使用,在块级作用域外调用则会报错
let 和 const 的使用场景
用
let
和const
代替IIFEIIFE 即 立即执行函数 ,应用之一就用来生成一个私有变量
// 例如我们在window对象中有一个name属性,如果直接这样声明一个name变量的话会覆盖属性name的值
// var name = 'Tom'; // 我们通常会用一个立即执行函数来使变量私有化
(function () {
var name = 'Tom';
})(); // 如果使用 let 或者 const 就可以简单实现,只需要用一对大括号包裹起来,就形成了一个块级作用域
{
let name = 'Tom';
}
for
循环for (var i = 0; i < 10; i++) { console.log(i); // 输出:0 1 2 3 ... 9 // 我们这里用setTimeout来模拟异步请求
setTimeout(function() {
console.log('i:' + i);
// 这里输出了10个 i:10
// 因为函数是延迟一秒执行的 此时 for 循环已经结束
}, 1000)
} // 将 var 改成 let 即可得到想要的结果,但不能使用 const !
...
临时性死区 Temporal Dead Zone
变量提升是 JavaScript 将变量的声明移至作用域的顶部
console.log(color); // 不会报错 而是输出 undefined
var color = 'yellow';
// 因为有了变量提升实际上这段代码是这样的
var color;
console.log(color); // 所以这里会输出 undefined
color = 'yellow';
/*
如果将 var 换成 let 则会报 ReferenceError
在ESMAScript 2015 中, let 也会将变量提块级作用域顶部,但你想在块级作用域中变量的声明之前引用的话就会报ReferenceError, 因为它是在临时性死区中的, const 亦是如此
我们要养成在变量之前不要使用它的好习惯
需要注意的是,因为 const 定义的是一个常量,所以声明的同时必须赋初始值,否则会报错
使用建议( in ES6 ):
默认使用 const
当变量需要重新绑定的时候使用 let
尽量不使用 var
*/
Arrow Function 箭头函数
优点:
- 简明的语法
- 可以隐式返回
- 不绑定
this
简明的语法
例如我们要用map
遍历一个数组使其中的数乘以二返回
const nums = [1, 3, 0, 5];
const double = nums.map(function (num) {
return num * 2;
});
console.log(double); // [2, 6, 0, 10]
// 改用箭头函数
const double2 = nums.map((num) => {
return num * 2;
});
console.log(double2); // [2, 6, 0, 10]
箭头函数写法:去掉function
关键字, 加上 =>
如果箭头函数只有一个参数的话,()
可以省略,没有参数或者有多个参数则必须使用括号并且参数之间用,
隔开
隐式返回
显式返回即return
关键字加上返回的内容。
箭头函数中的隐式返回:
去掉return
关键字 , 去掉 {}
, 将表达式写到一行中
用于我们只想简单返回一些内容时,使代码更加简洁
// like this
const double3 = nums.map((num) => num * 2);
注: 因为箭头函数都是匿名函数,匿名函数在递归或者作为回调函数等场景时非常好用,但如果你只想作为一个简单函数的话我们一般把它赋值给一个变量来使用
this问题
在使用箭头函数以前我们经常遇到这样的问题
const Tom = {
name: 'Tom',
hobbies: ['Coding', 'Sleeping', 'Reading'],
showHobbies: function () {
console.log(this); // 对象 Tom
this.hobbies.map(function (hobby) {
console.log(this); // 这里我们打印一下 this 发现竟然是 Window !
console.log(this.name + ' likes ' + hobby);
})
}
}
Tom.showHobbies();
/* 输出:
likes Coding
likes Coding
likes Reading
咦,你会发现 Tom 不见了,看来是 this.name 的 this 指向出了问题
*/
因为JS中的this
是在运行的时候才绑定的,
这里的showHobbies()
是由 对象Tom
调用的,所以this
指向的是对象Tom
而map()
方法里的回调函数他不是作为对象的方法调用,也没有使用apply
、call
等方法来改变this
指向,所以这里的this
指向的是 Window 或者说全局(严格模式下为undefined)
以前我们通常的做法是在这之前var self = this;
,然后用self
代替this
来使用
在ES6中我们可以借助箭头函数来代替这种 hack 写法,因为箭头函数没有自己的this
,它的this
值是继承它的父级作用域的(词法作用域,由上下文确定)
箭头函数不适用的场景
- 作为构造函数,向原型对象中添加方法
- 当你真的需要
this
的时候,例如事件绑定 - 需要使用
arguments
对象时
函数参数默认值
注意:参数中的变量是默认声明的,所以不能再函数内部再次用let
或者const
进行声明,这样会报错
// 直接在函数的形参后面赋值
function multiply (a = 1, b = 2) {
return a * b;
}
multiply(); // 2
multiply(3, 5); // 15
multiply(3); // 6
multiply(, 5); // error
// 一般情况下,我们使用带默认参数的函数应该是函数的最后一个参数
// 但如果非尾部的参数设置了默认值,实际上在我们调用这个函数的时候,这个参数是无法省略的
multiply(undefined, 5); // 5
// 不能使用 null
multiply(null, 5); // 0
模板字符串
在过去我们要组合 变量 和 字符串 的时候需要不停地用+
进行连接,这样既繁琐又容易出错而且不易检查。
有了 ES6 的模板字符串就变得容易多了
模板字符串 允许我们用一对反引号 ``来定义字符串,当字符串中需要引用变量的时候只需要用${ }
包裹就可以了
里面的变量可以是任意的 JS 表达式,包括对象的属性,甚至是一个函数
const name = 'Tom';
const age = 5;
const text = `${name} is ${age * 5} years old.`;
console.log(text); // "Tom is 25 years old."
未完待续。。。
ES6笔记分享 part 1的更多相关文章
- ES6笔记分享 part 2
ECMAScript ES6 从一脸懵逼到灵活运用 接 part 1 New String Methods const id = 'adcd123456x'; const fan = 'I love ...
- ES6笔记(5)-- Generator生成器函数
系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...
- ES6笔记系列
ES6,即ECMAScript 6.0,ES6的第一个版本是在2015年发布的,所以又称作ECMAScript 2015 如今距ES6发布已经一年多的时间,这时候才去学,作为一个JSer,羞愧羞愧,还 ...
- ES6笔记(1) -- 环境配置支持
系列文章 -- ES6笔记系列 虽然ES6已经发布一年多了,但在各大浏览器之中的支持度还不是很理想,在这查看ES6新特性支持度 Chrome的最新版本浏览器大部分已经支持,在Node.js环境上支持度 ...
- ES6笔记(2)-- let的块级作用域
系列文章 -- ES6笔记系列 一.函数级作用域 我们都知道,在ES6以前,JS只有函数级作用域,没有块级作用域这个概念 没有块级作用域,有利有弊,利于方便自由,弊于作用域内的变量容易被共享,例如这个 ...
- ES6笔记(3)-- 解构赋值
系列文章 -- ES6笔记系列 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组.对象.字符串的解构赋值等 一.数组的解构赋值 function ids() { ret ...
- ES6笔记(4)-- Symbol类型
系列文章 -- ES6笔记系列 Symbol是什么?中文意思是标志.记号,顾名思义,它可以用了做记号. 是的,它是一种标记的方法,被ES6引入作为一种新的数据类型,表示独一无二的值. 由此,JS的数据 ...
- ES6笔记(6)-- Set、Map结构和Iterator迭代器
系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...
- ES6笔记(7)-- Promise异步编程
系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...
随机推荐
- TCP/IP IGMP:Internet组管理协议
1.概述 IGMP协议,让一个物理网络上的所有系统知道主机所在的多播组,ICMP作为IP层的一部分,通过IP数据报进行传输,有固定的报文长度.通过IP首部协议字段值为2指明 类型为1说明是多播路由器发 ...
- MyBatis学习与使用(一)
写在前面—— 用 MyBatis 也做过几个项目了,但是一直没有很深入的去理解这个框架,最近决定从头开始学习和整理MyBatis. 之前开发的项目并不是我先创建的,等我介入的时候发现他们已经稍稍封装了 ...
- 洛谷$P$3168 任务查询系统 $[CQOI2015]$ 主席树
正解:主席树 解题报告: 传送门! 首先考虑如果是单点修改,那就是个线段树板子嘛$QwQ$ 然后现在是区间修改,对于区间修改,显然就考虑差分下,就变成单点修改辣$QwQ$ 同时单点查询前$k$小也就变 ...
- 使用EF操作Docker中的Mysql实例
为啥我会选择mysql呢?因为我的服务器配置较低,而SqlServer在docker中的实例,服务器的运行内存应当保持在2G+,我没有这个条件,它会爆出这样的错误 sqlservr: This pro ...
- 「算法竞赛进阶指南」0x01 最短Hamilton路径 解题报告
题目在这里啊题目在这里~ Hamilton路径:将所有点都遍历刚好一次的路径 思路: 数据范围比较小(1~20),所以我们可以考虑暴力中的枚举 数组f[i][j] i的二进制表示选取了哪些点 j表示 ...
- (httpd、php)2
(一)再说编译安装httpd2.4 新特性: 1:MPM(多处理模块)支持运行为DSO(动态共享,动态加载模式)机制,以模块形式按需加载,支持动态加载 2:event MPM生产环境可用 3:支持异步 ...
- V3微信支付开发笔录
真是坑爹啊,微信支付到处都是坑,一不小心就栽里面了, 文档也不怎么全,经过一周的奋斗终于把微信支付功能搞定,在此写下自己当时走入的误区和一些需要注意的地方,希望后边开发的朋友们可以少走弯路,少被微信坑 ...
- Spring Security 实战干货: 简单的认识 OAuth2.0 协议
1.前言 欢迎阅读 Spring Security 实战干货 系列文章 .OAuth2.0 是近几年比较流行的授权机制,对于普通用户来说可能每天你都在用它,我们经常使用的第三方登录大都基于 OAuth ...
- 2019 年百度之星 初赛一 1002 Game
传送门 Problem Description 度度熊在玩一个好玩的游戏.游戏的主人公站在一根数轴上,他可以在数轴上任意移动,对于每次移动,他可以选择往左或往右走一格或两格.现在他要依次完成 n 个任 ...
- 【转】VS2017缺少文件
在VS工程中,添加c/c++工程中外部头文件及库的基本步骤: 1.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录. 2.添加文件引用 ...