ES6学习笔记1
本文参考自http://es6.ruanyifeng.com,写这篇博客主要是方便自己查找
一. let和const声明
1. let命令
<1> 没有变量提升
使用var声明时,如果变量在声明之前使用,他的值是undefined。
console.log(a); // 输出undefined
var a = 1;
// 上面这段代码也等价于
var a;
console.log(a);
a =1;
现在let声明的变量必须在声明之后使用,否则报错
console.log(a); // ReferenceError
let a = 1;
<2> 暂时性死区
暂时性死区简单理解就是let会和它当前所在的作用域绑定,不受作用域外部变量的影响。
var a = 1;
if(true) {
a = '123';
let a; // ReferenceError
}
报错是因为在当条件判断式这个封闭的作用域中,a变量是通过let声明的,导致a和这个块级作用域绑定在一起,在let声明之前使用变量自然会报错。
注:typeof在let出现之前一直是不可能报错的。通过typeof判断一个不存在的变量时,会返回undefined.
typeof test_undefined; // "undefined"
但现在let有暂时性死区的特性,在let声明之前使用变量都属于 死区,所以typeof现在也可能报错
typeof a; // ReferenceError
let a;
<3>.同一个作用域中,let不允许重复声明
<4>.块级作用域
在es6之前是不存在块级作用域的,只有全局作用域和函数作用域。es6的let和const声明都为js增加了块级作用域,块级作用域允许任意嵌套,内层作用域可以定义外层作用域的同名变量。
js块级作用域也是自执行函数(IIFE)很好的替代品
// IIFE
(function () {
var a = '';
...
}());
// 块级作用域写法
{
let a = '';
...
}
2. const命令
- 基本使用
const声明一个只读的常量。一旦声明,常量的值就不能改变,除非声明的是一个对象
const a = 1;
a = 2; //ReferenceError
const只声明不赋值也会报错
const a; //SyntaxError
const命令声明的常量也是不提升,同样存在暂时性死区,也有块级作用域的特性。
二.变量的结构赋值
1. 数组的解构赋值
- 解构赋值的概念
按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
这种写法属于模式匹配只要等号两边的模式相同,左边的变量就会被赋予对应的值
// es6之前给三个变量赋值
let a = 1;
let b = 2;
let c = 3;
// 结构赋值写法
let [a,b,c] = [1,2,3];
- 解构失败时,会赋值 undefined
let [a,b,c] = [1,2];
console.log(c); // 'undefiend'
- 如果等号两边的值类型不一样,会报错
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
- Set结构也适用于数组的解构赋值(伪数组应该都适用)
let [a,b,c] = new Set(1,2,3);
- 默认值
解构赋值可以指定默认值,默认值只会在一个数组成员严格等于undefined才会生效
let [a,b=0,c] = [1,undefined,3];
console.log(b); // undefined
当默认值是一个函数时,那么这个函数只有在用到的时候才生效
function fun() {
aelrt(1);
}
let [a=fun()] = []; // a对应的值没有找到,所以fun函数会执行
- 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [a=1, b =1] =[]; //a=1,b=1
let [a=b,b=1] = []; //ReferenceError: y is not defined
2. 对象的解构赋值
- 基本使用
由于对象的属性没有次序,所以变量必须与属性同名,才能取到正确的值。如果没有同名属性会赋值 undefined
let {a,b} = {a:1}; // a=1; b 为 undefined;
- 对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
// 例子1
const {log} = console;
log(1); // 输出 1
// 例子二
const {sin,cos,PI} = Math;
console.log(PI); //输出 3.14159
- 当变量名和属性名不一致时
// 对象属性和对应的变量同名时候的简写
let {a,b} = {a:1};
// 等价于
let {a:a,b:b} = {a:1};
// 对象属性和对应的变量不同名时
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz); // 'aaa'
console.log(foo); //error: foo is not defined
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
- 默认值
默认值生效的条件是,对象的属性值严格等于undefined。var {x = 3} = {}; x // 3 var {x, y = 5} = {x: 1}; x // 1 y // 5 var {x: y = 3} = {}; y // 3 var {x: y = 3} = {x: 5}; y // 5
3.字符串的解构赋值
const [a, b, c, d, e] = 'hello';
const {length: f} = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
f // 5
4.函数参数的解构赋值
- 函数的参数也可以使用解构赋值
function fun([a , b]) {
console.log(a + b);
}
fun([1,2]); // 输出3
- 函数参数的解构也可以使用默认值
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
5. 用途
三.ES6字符串的扩展
1.字符串的遍历器接口
现在字符串可以被 for…of…循环遍历了
for (let i of 'abc') {
console.log(i);
}
// "a"
// "b"
// "c"
2.JSON.stringify()方法优化
现在如果遇到0xD800到0xDFFF之间的单个码点,或者不存在的配对形式,它会返回转义字符串。
3.模板字符串
- 字符串中嵌入变量,使用 ${}包裹变量
let a = 'world'
let str = `hello ${a}`
- 如果字符串中出现 ``,需要使用反斜杠转义
let str = `hello \`world\``
- ${} 可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"
- ${}中执行函数
function fun() {
return 'hello world'
}
console.log(`${fun()}`); // 输出 hello world
四.字符串新增方法
1.实例方法:includes(), startsWith(), endsWith()
- 基本使用
传统上js用来确定一个字符串是否包含在另一个字符串中的方法只有indexof(),ES6中新增了三种方法
- includes():返回布尔值,表示是否找到了参数字符串。
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
- 这三个方法都支持第二个参数,表示开始搜索的位置
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
存在第二个参数时,endWidth针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束
2.把字符串重复nc次 repeat()
repeat方法返回一个新字符串,表示将原字符串重复n次。
let str = 'a';
str.repeat(3) // 'aaa'
str.repeat(0) // ''
str.repeat(1.9) // 'a'
如果repeat的参数是负数或者Infinity,会报错。
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
3.头部补全和尾部补全 padStart(),padEnd()
如果某个字符串不够指定长度,会在头部或尾部补全,并且返回一个新字符串。
'x'.padStart(5,'y'); // 'yyyyx'
'x'.padEnd(5,'y'); // 'yxxxx'
4. 头尾去空格trimStart(),trimEnd()
它们返回的都是新字符串,不会修改原始字符串。
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
5.实例方法:matchAll()
matchAll()方法返回一个正则表达式在当前字符串的所有匹配
五.数值的扩展
- 判断是否是整数 Number.isInteger()
此方法不适用于对数字精度要求高的场景Number.isInteger(25) // true Number.isInteger(25.1) // false
- 返回整数部分Math.trunc()
对于空值和无法截取整数的值,返回NaN。Math.trunc(2.333) // 2
Math.trunc(NaN); // NaN Math.trunc('foo'); // NaN Math.trunc(); // NaN Math.trunc(undefined) // NaN
- Math.sign()
Math.sign方法用来判断一个数到底是正数、负数、还是零
- 参数为正数,返回+1;
- 参数为负数,返回-1;
- 参数为 0,返回0;
- 参数为-0,返回-0;
- 其他值,返回NaN。
- 求立方根Math.cbrt()
5.Math.hypot()
返回所有参数的平方和的平方根