一. ES6(ES2015)

1. 变量 let 和常量 const

  • var 的问题

    • 可以重复声明,没有报错和警告
    • 无法限制修改
    • 没有块级作用域, { }
  • let 和 const

    • 不能重复声明
    • 都是块级作用域, { } 块内声明的,块外无效
    • let 是变量,可以修改
    • const 是常量,不能修改
  • 块级作用域举例

    • 原来用 var 的方式,结果弹出的都是 3
    • 或者将变量 封装到函数里,限制作用域,但比较麻烦
    • 用 let 最简单,直接 var 改 let,解决作用域问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload= function () {
/*
var aBtn = document.getElementsByTagName('input')
for (var i=0; i < aBtn.length; i++) {
aBtn[i].onclick = function () {
alert(i)
}
}*/
var aBtn = document.getElementsByTagName('input')
for (let i = ; i < aBtn.length; i++) {
aBtn[i].onclick = function () {
alert(i)
}
}
/*
var aBtn = document.getElementsByTagName('input')
for (var i = 0; i < aBtn.length; i++) {
// 封装到函数里,限制作用域
(function (i) {
aBtn[i].onclick = function () {
alert(i)
}
})(i)
}*/
}
</script>
</head>
<body>
<input type="button" value="按钮1">
<input type="button" value="按钮2">
<input type="button" value="按钮3">
</body>
</html>

2. 箭头函数

引入箭头函数有两个方面的作用:简化函数和不需要绑定 this

x => x * x
上面的箭头函数相当于: function (x) {
return x * x;
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }return

x => {
if (x > ) {
return x * x;
}
else {
return - x * x;
}
}

如果参数不是一个,就需要用括号()括起来:

// 两个参数:
(x, y) => x * x + y * y // 无参数:
() => 3.14 // 可变参数:
(x, y, ...rest) => {
var i, sum = x + y;
for (i=; i<rest.length; i++) {
sum += rest[i];
}
return sum;
}

如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:

// SyntaxError:
x => { foo: x }
因为和函数体的{ ... }有语法冲突,所以要改为: // ok:
x => ({ foo: x })

箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

回顾前面的例子,由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:

var obj = {
birth: ,
getAge: function () {
var b = this.birth; //
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window或undefined
};
return fn();
}
};

现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj

var obj = {
birth: ,
getAge: function () {
var b = this.birth; //
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
obj.getAge(); //

如果使用箭头函数,以前的那种hack写法:

var that = this;

就不再需要了。

由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

var obj = {
birth: ,
getAge: function (year) {
var b = this.birth; //
var fn = (y) => y - this.birth; // this.birth仍是1990
return fn.call({birth:}, year);
}
};
obj.getAge(); //

3. ...扩展参数符

  • 参数扩展/展开 ...args

    • 收集剩余的参数,必须当到最后一个参数位置
    • 展开数组,简写,效果和直接把数组的内容写在这儿一样
  • 默认参数
function show(a, b, ...args) {
console.log(a)       // 1
console.log(b)       // 2
console.log(args)    // [3,4,5]
}
show(, , , , ) let arr1 = [, , ]
let arr2 = [, , ]
let arr3 = [...arr1, ...arr2]
console.log(arr3)       // [1,2,3,4,5,6] function show2(a, b=, c=) {
console.log(a, b, c) // 88 12 8
}
show2(, )

4. 解构赋值

解构赋值

  • 左右两个边结构必须一样
  • 右边必须是个东西
  • 声明和赋值赋值不能分开,必须在一句话里

数组:

let [a, b, c] = [, , ];
//等同于
let a = ;
let b = ;
let c = ;

对象:

var {
StyleSheet,
Text,
View
} = React; 等同于
var StyleSheet = React.StyleSheet;
var Text = React.Text;
var View = React.Text;

获取对象中的值:

const student = {
name: 'bahg',
age: ,
sex: 'girl'
}
const {name, age, sex} = student
console.log(name); // bahg
console.log(age); //
console.log(sex); // girl

5. 新增四个方法 map、reduce、filter、forEach

(1)map映射 (一对一,返回新数组)

let arr = [, , ]
let result1 = arr.map(item=>item*) // 简写
console.log(result1) // [ 24, 10, 16 ] let score = [, , , ]
let result2 = score.map(item => item >= ? '及格' : '不及格')
console.log(result2) // [ '不及格', '及格', '及格', '不及格' ] var users = [
{name: "张XX", "email": "zhang@email.com"},
{name: "江XX", "email": "jiang@email.com"},
{name: "李XX", "email": "li@email.com"}
];
var emails = users.map(function (user) { return user.email; });
console.log(emails.join(",")); // zhang@email.com, jiang@email.com, li@email.com

(2)reduce 汇总(多变一,返回新数组)

arr.reduce(function(prev,cur,index,arr){
...
}, init);
  • prev    表示上一次调用回调时的返回值,或者初始值 init;
  • cur      表示当前正在处理的数组元素;
  • index  表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
  • arr       表示原数组;
  • init      表示初始值

其实必需以及常用的参数只有两个:prev 和 cur。接下来我们跟着实例来看看具体用法吧~

请参考 https://www.cnblogs.com/cckui/p/9267542.htmlhttps://www.cnblogs.com/amujoe/p/11376940.html

(3)filter 过滤器(保留为true的,返回新数组)

var arr = [, , , ]
var result = arr.filter(item => (item % === ) ? true : false)
console.log(result) // Array(2)
var result = arr.filter(item => item % === )
console.log(result) // Array(2) var arr = [
{ title: '苹果', price: },
{ title: '西瓜', price: },
]
var result = arr.filter(json => json.price >= )
console.log(result) // Array(1)

(4)forEach 循环迭代(用于遍历数组,无返回值)

var arr = [, , , ]
var result = arr.forEach(item => console.log(item))
var result = arr.forEach((item, index)=>console.log(item, index))

注意:除了reduce方法之外的其他三个方法,都传入了一个匿名函数作为参数,而该匿名函数实际含有三个参数(我们这里只写了一个)。其依次代表数组遍历时的当前元素item,数组遍历时的当前元素的索引index,以及正在遍历的数组array。有了这三个参数,可以方便我们做很多事情,比如说将每一项数组元素翻倍,这时需要用到第一个参数item。但是,仅仅只是将item乘以2可不行,我们还得将其赋值给原来的数组,这时我们就得用到后面两个参数index和array。根据上述可知,array[index]是全等于item的。

此外,这三个方法除了传递一个匿名函数作为参数之外,还可以传第二个参数,该参数用于指定匿名函数内的this指向,例如:

// 只传一个匿名函数
arr.forEach(function(item,index,array){
console.log(this); // window
});
// 传两个参数
arr.forEach(function(item,index,array){
console.log(this); // [1, -2, 3, 4, -5]
},arr);

6. 字符串

(1)模板字符串

  • 使用反引号,${变量}
  • 可以折行
 let a =
let str1 = `asdf${a}`
console.log(str1) // asdf12 let title = '标题'
let content = '内容'
let str = `<div>
<h1>${title}</h1>
<p>${content}</p>
</div>`
console.log(str)

<div>
  <h1>标题</h1>
  <p>内容</p>
</div>

(2)两个新方法

startWith   endsWith

var url = 'http://qq.com'
console.log(url.startsWith('http'))
console.log(url.endsWith('com'))
// 都是 true

7. 类

  • 原来写法

    • 类和构造函数一样
    • 属性和方法分开写的
// 老版本
function User(name, pass) {
this.name = name
this.pass = pass
} User.prototype.showName = function () {
console.log(this.name)
}
User.prototype.showPass = function () {
console.log(this.pass)
} var u1 = new User('able', '')
u1.showName()
u1.showPass() // 老版本继承
function VipUser(name, pass, level) {
User.call(this, name, pass)
this.level = level
}
VipUser.prototype = new User()
VipUser.prototype.constructor = VipUser
VipUser.prototype.showLevel = function () {
console.log(this.level)
} var v1 = new VipUser('blue', '', )
v1.showName()
v1.showLevel()
  • 新版面向对象

    • 有了 class 关键字、构造器
    • class 里面直接加方法
    • 继承,super 超类==父类
class User {
constructor(name, pass) {
this.name = name
this.pass = pass
} showName() {
console.log(this.name)
}
showPass() {
console.log(this.pass)
}
} var u1 = new User('able2', '')
u1.showName()
u1.showPass() // 新版本继承
class VipUser extends User {
constructor(name, pass, level) {
super(name, pass)
this.level = level
}
showLevel(){
console.log(this.level)
}
} v1 = new VipUser('blue', '', )
v1.showLevel()

8. 模块化

ES5 不支持原生的模块化,在ES6中模块作为重要的组成部分被添加进来。模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过 import 来引用其他模块提供的接口。同时还为模板创造了命名空间,防止函数的命名冲突。

导出(export)导入 (import)

ES6 允许在一个模块 export 来导出多个变量或函数。定义好模块的输出以后就可以在另外一个模块通过 import 引入。

导出变量:

export var name = 'bahg'       // 导出变量
export const sqrt = Math.sqrt // 导出常量
export {name, sqrt} // 批量导出

导入变量:

import {name, age} from '...'

导出函数:

export function sum(a, b){
return (a + b)
}

导入函数:

import {sum} from '...'

9. Promise

  • 异步和同步

    • 异步,操作之间没有关系,同时执行多个操作, 代码复杂
    • 同步,同时只能做一件事,代码简单
  • Promise 对象

    • 用同步的方式来书写异步代码
    • Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
    • 改善了可读性,对于多层嵌套的回调函数很方便
    • 充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口
  • Promise 也是一个构造函数

    • 接受一个回调函数f1作为参数,f1里面是异步操作的代码
    • 返回的p1就是一个 Promise 实例
    • 所有异步任务都返回一个 Promise 实例
    • Promise 实例有一个then方法,用来指定下一步的回调函数
function f1(resolve, reject) {
// 异步代码...
}
var p1 = new Promise(f1);
p1.then(f2); // f1的异步操作执行完成,就会执行f2。
Promise 使得异步流程可以写成同步流程
// 传统写法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
}); // Promise 的写法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
  • Promise.all(promiseArray)方法

    • 将多个Promise对象实例包装,生成并返回一个新的Promise实例
    • promise数组中所有的promise实例都变为resolve的时候,该方法才会返回
    • 并将所有结果传递results数组中
    • promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象
var p1 = Promise.resolve(),
p2 = Promise.resolve(),
p3 = Promise.resolve();
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // [1, 2, 3]
});
  • Promise.race([p1, p2, p3])

    • Promse.race就是赛跑的意思
    • 哪个结果获得的快,就返回那个结果
    • 不管结果本身是成功状态还是失败状态

二. ES7 新特性(ES2016)

1. Array.prototype.includes

它是一个替代 indexOf,开发人员用来检查数组中是否存在值,indexOf 是一种尴尬的使用,因为它返回一个元素在数组中的位置,如果没有这个元素则返回 -1。它返回的是一个数字,而不是一个布尔值。开发人员需要实施额外的检查。在ES6,要检查是否存在值你需要做一些如下图所示小技巧,因为他们没有匹配到值,Array.prototype.indexOf 返回- 1变成了true(转换成true),但是当匹配的元素为0位置时候,该数组包含元素,却变成了false。例如:

let arr = ['react', 'angular', 'vue']

// WRONG
if (arr.indexOf('react')) { // 0 -> evaluates to false, definitely as we expected
console.log('Can use React') // this line would never be executed
} // Correct
if (arr.indexOf('react') !== -) {
console.log('Can use React')
}

然而在 ES7 中:

let arr = ['react', 'angular', 'vue']
  console.log(arr.includes('vue'))  // true
// Correct
if (arr.includes('react')) {
console.log('Can use React')
}

还能在字符串中使用 includes:

let str = 'React Quickly'

// Correct
if (str.toLowerCase().includes('react')) { // true
console.log('Found "react"')
}

includes也可以在NaN(非数字)使用。最后 ,includes第二可选参数fromIndex,这对于优化是有好处的,因为它允许从特定位置开始寻找匹配。更多例子:

console.log([, , ].includes()) // === true)
console.log([, , ].includes()) // === false)
console.log([, , NaN].includes(NaN)) // === true)
console.log([, , -].includes(+)) // === true)
console.log([, , +].includes(-)) // === true)
console.log(['a', 'b', 'c'].includes('a')) // === true)
console.log(['a', 'b', 'c'].includes('a', )) // === false)

2. Exponentiation Operator(求幂运算)

求幂运算大多数是做一些数学计算,对于3D,VR,SVG还有数据可视化非常有用。在ES6或者早些版本,不得不创建一个循环,创建一个递归函数或者使用 Math.pow

在 ES6 中,可以使用 Math.pow 创建一个短的递归箭头函数:

calculateExponent = (base, exponent) => base*((--exponent>)?calculateExponent(base, exponent):base)
console.log(calculateExponent(,) === Math.pow(,)) // true
console.log(calculateExponent(,) === Math.pow(,)) // true

然而在 ES7 中:

let a =  **
let b = **
console.log(a === Math.pow(,)) // true
console.log(b === Math.pow(,)) // true let a =
a **=
let b =
b **=
console.log(a === Math.pow(,)) // true
console.log(b === Math.pow(,)) // true

三. ES8 新特性(ES2017)

1. Object.values()

Object.values() 是一个与 Object.keys() 类似的新函数,但返回的是 Object 自身属性的所有值,不包括继承的值。

假如要遍历如下对象 obj 的所有值:

const obj = {a: , b: , c: }

不使用 Object.values():ES7

const vals = Object.keys(obj).map(key => obj[key])
console.log(vals)

使用 Object.values():ES8

const vals = Object.values(obj)
console.log(vals)

从上述代码中可以看出 Object.values() 为我们省去了遍历 key,并根据这些 key 获得 value 的过程。

2. Object.entries()

Object.entries() 函数返回一个给定对象自身可枚举属性的键值对的数组。

下面我们来遍历上文中 obj 对象的所有属性的 key 和 value:

不使用 Object.values():ES7

Object.keys(obj).forEach(key => {
console.log('key:' + key + ' value:' + obj[key])
})

使用 Object.values():ES8

for(let [key, value] of Object.entries(obj)) {
console.log(`key:${key} value:${value}`)
}

3. String padding(字符串填充)

(1)String.prototype.padStart

padStart()在开始部位填充,返回一个给出长度的字符串,填充物给定字符串,把字符串填充到期望的长度。从字符串的左边开始(至少大部分西方语言),一个经典例子是使用空格创建列:

console.log('react'.padStart(10).length)         // "       react" is 10
console.log('backbone'.padStart(10).length) // " backbone" is 10

它对于财务方面非常有用:

console.log('0.00'.padStart(20))
console.log('10,000.00'.padStart(20))
console.log('250,000.00'.padStart(20))
如果是为会计做账之类的,这个很实用,帐做的很整齐
         0.00
10,000.00
250,000.00

(2)String.prototype.padEnd

padEnd顾名思义就是才能够字符串的尾端右边开始填充。第二个参数,实际上可以用任何长度的字符串。例如:

console.log('react'.padEnd(10, ':-)'))         // "react:-):-" is 10
console.log('backbone'.padEnd(10, '*')) // "backbone**" is 10

在赏几个例子作为总结:

// String.prototype.padStart(targetLength [, padString])
'hello'.padStart(); // ' hello'
'hello'.padStart(, ''); // '00000hello'
'hello'.padStart(); // 'hello'
'hello'.padStart(, ''); // '1hello'
'hello'.padStart(); // 'hello'
'hello'.padStart(, ''); // 'hello'; // String.prototype.padEnd(targetLength [, padString])
'hello'.padEnd(); // 'hello '
'hello'.padEnd(, ''); // 'hello00000'
'hello'.padEnd(); // 'hello'
'hello'.padEnd(, ''); // 'hello1'
'hello'.padEnd(); // 'hello'
'hello'.padEnd(, ''); // 'hello';

4. Object.getOwnPropertyDescriptors

该函数用来获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

const obj = {
name: 'bahg',
get age() {
return ''
}
};
console.log(Object.getOwnPropertyDescriptor(obj, "name"))
console.log(Object.getOwnPropertyDescriptor(obj, "age")) 打印结果:
  1. {value: "bahg", writable: true, enumerable: true, configurable: true}
    1. configurable: true
    2. enumerable: true
    3. value: "bahg"
    4. writable: true
    5. __proto__: Object

{set: undefined, enumerable: true, configurable: true, get: ƒ}configurable: trueenumerable: trueget: ƒ age()set: undefined__proto__: Object

5. 函数参数列表结尾允许逗号

6. 异步函数 async/await

async function show() {
console.log()
await
console.log()
}
  异步函数(或者async/await)特性操作是Promise最重要的功能。这种想法是为了在写异步代码中简化它,因为人类大脑最讨厌这种平行非序号思维了。它只是不会演变这种方式。本来以为Promise的到来已经是摆脱node异步的福音了,在ES8,异步函数是那么给力。开发者定义一个asyc函数里面不包含或者包含 await 基于Promise异步操作。在这引擎之下一个异步函数返回一个Promise,无论无何你在任何地方不会看到这样的一个词Promise。例如,在ES6中我们可以使用Promise,Axios库向GraphQL服务器发送一个请求:
axios.get(`/q?query=${query}`)
.then(response => response.data)
.then(data => {
this.props.processfetchedData(data) // Defined somewhere else
})
.catch(error => console.log(error))
任何一个Promise库都能兼容新的异步函数,我们可以使用同步try/catch做错误处理
async fetchData(url) => {
try {
const response = await axios.get(`/q?query=${query}`)
const data = response.data
this.props.processfetchedData(data)
} catch (error) {
console.log(error)
}
}
异步函数返回一个Promise,所以我们像下面可以继续执行流程:
async fetchData(query) => {
try {
const response = await axios.get(`/q?query=${query}`)
const data = response.data
return data
} catch (error) {
console.log(error)
}
}
fetchData(query).then(data => {
this.props.processfetchedData(data)
})

本文参考 https://www.cnblogs.com/blueball/p/12409085.html

ES6,ES7,ES8 常用特性总结的更多相关文章

  1. ES6/ES7/ES8常用特性和新特性

    转自:https://www.jianshu.com/p/9da4aa1c9970

  2. es6/es7/es8常用新特性总结(超实用)

    本文标题有误导性,因为我其实想写node8的新特性,说实话一下子从node v1.x跳跃到node 8.x+ 真有点受宠若惊的感觉.一直觉得node 数组. 对象.序列等的处理没有python方便,因 ...

  3. ES6/ES7/ES8新特性

    ES6 变量的改变 let const 2. 字符串新增方法 let str = 'react'; str.includes('re') // true str.repeat(3) // reactr ...

  4. ES6的一些常用特性

    由于公司的前端业务全部基于ES6开发,于是给自己开个小灶补补ES6的一些常用特性.原来打算花两天学习ES6的,结果花了3天才勉强过了一遍阮老师的ES6标准入门(水好深,ES6没学好ES7又来了...) ...

  5. es6,es7,es8

    概述 ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言.目前JavaScript使用的ECMAScript版本为ECMAScript-262. ECMAScript 标 ...

  6. ES6十大常用特性

    .   Default Parameters(默认参数) in ES6 2.    Arrow Functions (箭头函数)in ES6 3.    Block-Scoped Constructs ...

  7. ES6 ES7 ES8 相关用法

    set Set作为ES6新的数据解构(类数组),它的成员都是唯一的,因为最直接的使用场景便是去重.并.差.交集的使用.它使用的算法叫做“Same-value-zero equality”,类似精确运算 ...

  8. 【JavaScript】--- ES6/ES7/ES8

    一.async async其实是ES7才有有的关键字,async的意思是异步,顾名思义是有关异步的操作 async用于声明一个函数是异步的. 通常情况下async.await都是跟随promise一起 ...

  9. ES6,ES7,ES8 常用

    ES6常用新特性 let && const let 命令也用于变量声明,但是作用域为局部 { let a = 10; var b = 1; } 在函数外部可以获取到b,获取不到a,因此 ...

随机推荐

  1. 大数据MapReduce相关的运维题

    1.在集群节点中/usr/hdp/2.4.3.0-227/hadoop-mapreduce/目录下,存在一个案例 JAR 包 hadoop-mapreduce-examples.jar.运行 JAR ...

  2. 基于udp协议的套接字通信

    服务端: import socket server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) server.bind(('127.0.0.1',8 ...

  3. liunx系统二进制包安装编译mysql数据库

    liunx系统二进制包安装编译mysql数据库 # 解压二进制压缩包 [root@localhost ~]# tar xf mysql-5.5.32-linux2.6-x86_64.tar.gz -C ...

  4. 关于XSS弹窗的小姿势

    最近快比赛了想刷刷题,做合天XSS进阶的时候遇到了过滤了alert然后还要弹窗效果的题目,这让我这个JS只学了一点点的菜鸡倍感无力.     在百度了其他资料后,发现confirm('xss')和pr ...

  5. 设计模式 - 迭代器模式详解及其在ArrayList中的应用

    基本介绍 迭代器模式(Iterator Pattern)是 Java 中使用最多的一种模式,它可以顺序的访问容器中的元素,但不需要知道容器的内部细节 模式结构 Iterator(抽象迭代器):定义遍历 ...

  6. CCS进阶——div的宽度和高度是由什么决定的?

    核心知识 文档流/普通流(Normal Flow) 内联元素的宽高(高度是由行高决定的,宽度=内容+border+marging+padding) 块级元素的宽高(高度是内部文档流元素的高度总和,宽度 ...

  7. vue中 $refs的基本用法

    骚年,我看你骨骼惊奇,有撸代码的潜质,这里有324.57GB的前端学习资料传授于你!什么,你不信??? 先随便看几个图: 肯定没看够.再来个GIF图热个身??? 那么问题来了,如果你也想入坑前端或者学 ...

  8. 通过fiddler抓取IDEA的请求

    2019独角兽企业重金招聘Python工程师标准>>> 因为fiddler默认是代理的8888端口,所以设置一下IDEA的请求使用本地的8888作为代理发出. 1."EDI ...

  9. qt creator源码全方面分析(4-2)

    目录 global头文件 global.h xx.h global头文件 插件的本质就是动态链接库,对于库,需要导出符号,供用户导入使用.在qt creator的源码中,存在固定的导入导出模式. gl ...

  10. 详解十大经典数据挖掘算法之——Apriori

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第19篇文章,我们来看经典的Apriori算法. Apriori算法号称是十大数据挖掘算法之一,在大数据时代威风无两,哪 ...