1.let,const
let,const定义的变量,不是绑定在window下。
2.解构,ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
//数组解构
let [a, b, c] = [1, 2, 3];
//对象解构
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
//字符串解构
const [a, b, c, d, e] = 'hello';//a=h,b=e ...
3.字符
1.ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。
"\uD842\uDFB7"
// "𠮷"
"\u20BB7"
// " 7"
2.ES6 为字符串添加了遍历器接口(详见《Iterator》一章),使得字符串可以被for…of循环遍历。
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
3.模板字符串 `是反引号
`里面的内容被原样输出,包括换行`
`里面的${变量名}`
let func = (name) => `Hello ${name}!`;
func('Jack') // "Hello Jack!"
4.字符串新增了一些方法
1.row()
ES6 还为原生的 String 对象,提供了一个raw()方法。该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法。
String.raw`Hi\n${2+3}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hi\n5!"
2.传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。都支持第二个参数,表示开始搜索的位置。
- includes():返回布尔值,表示是否找到了参数字符串。
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
3.repeat方法返回一个新字符串,表示将原字符串重复n次。
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // "" 如果传的参数是小数,向下取整
4.ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
5.ES2019 对字符串实例新增了trimStart()和trimEnd()这两个方法。它们的行为与trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。
5.数值
1.二进制和八进制表示法
ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。
2.ES6 在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法。
Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。
Number.isNaN()用来检查一个值是否为NaN。
3.ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。目的,是逐步减少全局性方法,使得语言逐步模块化。
4.ES2016 新增了一个指数运算符(**)。
6.函数
1.函数参数赋默认值
function log(x, y) {
y = y || 'World';
console.log(x, y);
}
这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,则该赋值不起作用。就像上面代码的最后一行,参数y等于空字符,结果被改为默认值。所以es6用下面的方法
function log(x, y = 'World') {
console.log(x, y);
}
参数变量是默认声明的,所以不能用let或const再次声明。
function foo(x = 5) {
let x = 1; // error
const x = 2; // error
}
上面代码中,参数变量x是默认声明的,在函数体中,不能用let或const再次声明,否则会报错。
参数默认值可以与解构赋值的默认值,结合起来使用。
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
函数的length属性
length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。同理,后文的 rest 参数也不会计入length属性。
(function (a,b=1){}).length//1
2.rest参数(形式为…变量名),用于获取函数的多余参数,
3.ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
两种方法可以规避这种限制。第一种是设定全局性的严格模式,这是合法的。
第二种是把函数包在一个无参数的立即执行函数里面。
4.函数的name属性,返回该函数的函数名。
5.箭头函数
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
https://blog.csdn.net/w390058785/article/details/82884032
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
6.尾调用优化
尾调用:某个函数的最后一步是调用另一个函数。
function f() {
let m = 1;
let n = 2;
return g(m + n);
}
f();
// 等同于
function f() {
return g(3);
}
f();
// 等同于
g(3);
上面代码中,如果函数g不是尾调用,函数f就需要保存内部变量m和n的值、g的调用位置等信息。但由于调用g之后,函数f就结束了,所以执行到最后一步,完全可以删除f(x)的调用帧,只保留g(3)的调用帧。
这就叫做“尾调用优化”(Tail call optimization),即只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。这就是“尾调用优化”的意义。
尾递归:https://www.cnblogs.com/J1ac/p/9326444.html
由于尾递归只存在一个调用记录,所以永远不会发生"栈溢出"错误。
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
factorial(5) // 120
上面代码是一个阶乘函数,计算n的阶乘,最多需要保存n个调用记录,复杂度 O(n) 。
如果改写成尾递归,只保留一个调用记录,复杂度 O(1) 。return不用n*
function factorial(n, total) {
if (n === 1) return total;
return factorial(n - 1, n * total);
}
factorial(5, 1) // 120
第一次:4,5
第二次:3,20
第三次:2,60
第四次:1,120 返回120
7.proxy
在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
8.promise
三种状态:1、pending[待定]初始状态
2、fulfilled[实现]操作成功
3、rejected[被否决]操作失败
只能从1变成2,1变成2,不可以2变3
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
then()是用来进行链式编程下去的。
promise是用来解决问题:
- 异步无法保证输出顺序,通过嵌套达到输出有序。但promise容器本身不是异步的,里面需要放一个异步任务去执行他。
- 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
- promise可以支持多个并发的请求,获取并发请求中的数据
- 这个promise可以解决异步的问题,本身不能说promise是异步的
9.Iterator
作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。
使用和java的类似
10.async
async 函数是什么?一句话,它就是 Generator 函数的语法糖。
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
11.编程风格
1.静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。
2.单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾。
3.模块,import取代require。
4.ESLint 是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。
12.装饰器
类似 java的注解