es6
变量声明
| var | 有变量提升问题 | 没有作用域 |
| let | 没有变量提升 | 没有作用域 |
| const | 没有变量提升 | const 定义的常量,无法再重新赋值,而且必须初始化 |
解构赋值
把某个对象中的属性,当做变量给解放出来,今后就能够当做变量直接使用了
person = { name:"zs", age:11, sex:"男" };
const { name: name123, age } = person;
console.log(name123); //'zs';
可以从数组中提取值,按照对应位置对变量赋值
let [a, b, c] = [1, 2, 3]
let [x, y = 'b'] = ['a'] //x='a',y='b'
字符串扩展
| 方法 | 说明 |
|---|---|
| .startsWith('str'); | 判断字符串是否以指定的字符串开头,返回 boolean; |
| .endsWith('str); | 判断字符串是否以指定的字符串结尾,返回 boolean; |
| .padStart(2,'0'); | 参数 1 填充后的总长,参数 2 用哪个字符串填充 |
| .padEnd(1,'2'); | 参数 1 填充后的总长,参数 2 用哪个字符串填充 |
模版字符串
使用``
let arr = [{ name: 'zs', age: '1', sex: 'm' }]
for (let i = 0; i < arr.length; i++) {
str = `<tr>
<td>${arr[i].name}</td>
<td>${arr[i].age}</td>
<td>${arr[i].sex}</td>
</tr>`
}
函数扩展
ES6 允许为函数的参数设置默认值,直接写在参数定义的后面。一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域,等到初始化结束,这个作用域就会消失。这种语法行为在不设置参数默认值时是不会出现的
var x = 1
function foo(
x,
y = function () {
x = 2
}
) {
var x = 3
y()
console.log(x)
}
foo() //3
console.log(x) //1
参数默认值可以与结构赋值的默认值结合起来使用
function add({ x, y = 0 }) {
return x + y
}
const result = add({ x: 3 })
console.log(result) //3
函数 length 属性,指定默认值后将返回没有指定默认值的个数,如果默认值参数不是尾参数,那么 length 属性也不再计入后面的参数了
;(function (a) {})
.length(
// 1
function (a = 5) {}
)
.length(
// 0
function (a, b, c = 5) {}
)
.length(
// 2
function (...args) {}
)
.length(
// 0
function (a = 0, b, c) {}
)
.length(
// 0
function (a, b = 1, c) {}
).length // 1
rest 参数
function add(...argus) {
let total = 0
for (let i = 0; i < arguments.length; i++) {
total += arguments[i]
}
console.log(total)
}
add(1, 2, 3)
add(1, 2, 3, 4, 5, 6, 7)
let arr = [1, 2, 3, 4, 5]
add(...arr)
箭头函数
var add = function (x,y) {..函数体} //Es 5
var add = (x,y) => {..函数体} //Es 6
- 箭头函数内部的
this永远和箭头函数外部的this保持一致 - 箭头函数本质就是一个匿名函数,标准格式为
(参数列表) => {函数体} - 如果箭头函数左侧的形参列表只有 1 个形参,
()可以省略,x=>{console.log(x)}; - 如果箭头函数右侧函数体只有一行代码,
{}可省略,(x,y)=>console.log(x+y); - 如果箭头函数左侧只有一个形参,右侧只有一行代码,那么左右侧都可以省略括号,
x=> console.log(X); - 如果省略了右侧
{},那么默认会把右侧函数体执行结果返回出去,(x+y) =>x+y;
对象中定义方法和属性的便捷方式
const name = 'zs'
const age = 18
const data = { name, age }
console.log(data) //{ name: 'zs', age: 18 }
ES6 允许直接写入变量和函数,作为对象的属性和方法
function add(x, y) {
return x + y
}
const o = { add }
console.log(o) //{ add: [Function: add] }
ES6 允许在对象中直接写变量,属性名为变量名,属性值为变量的值
function foo(x, y) {
return { x, y } //{x:x,y:y}
}
foo(1, 2) //{x:1,y:2}
数据结构 Set
类似于数组但是成员的值都是唯一的没有重复的值,Set 内部判断两个值是否不同,使用类似于全等运算符
const set = new Set([1, 2, 3, 4, 4, 4])
[...set] // [1,2,3,4]
[...new Set(array)] //数组去重 Array.from(new Set(array))
Set.prototype.size返回set实例的成员总数 .add(val)添加某个值,返回Set结构本身 .delete(val)删除某个值,返回一个布尔值,表示删除是否成功 .has(val)返回一个布尔值,表示该值是否为Set成员 .clear()清除所有成员,没有返回值 Array.from(set)可以将Set结构转为数组
Set 结构遍历方法,遍历成员
keys()返回键名的遍历器 values()返回键值的遍历器 entries()返回键值对的遍历器 forEach()使用回调函数遍历每个成员 Set的遍历顺序就是插入顺序
let set = new Set(['red', 'green', 'blue'])
for (let item of set.keys()) {
console.log(item)
}
for (let item of set) {
console.log(item)
}
set.forEach((value, key) => console.log(key + ' : ' + value))
数据结构 Map
JavaScript 的对象本质上是键值对的集合,但是传统上只能用字符串当做键。 ES6 提供了 Map 数据结构,它类似于对象,也是键值对的集合但是各种类型的值(包括对象)都可以当做键
new Map([
[true, 7],
[{ foo: 3 }, ['abc']],
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
size属性返回 Map 结构成员总数 .set(key,value)设置键名 key 对应的键值为 value,然后返回整个 Map 结构 .get(key)读取 key 对应的键值 .has(key)返回一个布尔值,表示某个键是否在当前 Map 对象之中 .delete(key)删除某个键,返回 true .clear()清楚所有成员 Map 遍历方法,keys(),valuse(),entries(),forEach()
Symbol
Symbol 值通过 Symbol 函数生成,对象的属性名现在可以有两个类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型,凡是属性名属于 Symbol 类型就都是独一无二的,可以保证不会与其他属性名产生冲突
let s = Symbol(1)
typeof s //'Symbol'
Iterator 和 for..of 循环
任意一个对象的Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回对象的一个遍历对象
Generator 函数
const id = document.getElementById('btn')
function* hello() {
yield 1
yield 2
yield 3
return 'end'
}
const h = hello()
btn.addEventListener('click', function () {
console.log(h.next()) // { value: '1', done: false }
console.log(h.next()) // { value: '2', done: false }
console.log(h.next()) // { value: '3', done: false }
console.log(h.next()) // { value: 'end', done: true }
})
yield表达式只能在Generator函数中,如果yield表达式用在另一个表达式必须放在圆括号包裹,若yield表达式作函数参数或放在赋值表达式的右边可以不加括号
function* demo() {
console.log('Hello' + (yield)) // OK
console.log('Hello' + (yield 123)) // OK
}
function* demo2() {
foo(yield 'a', yield 'b') // OK
let input = yield // OK
}
async 函数
const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab')
const f2 = await readFile('/etc/shells')
console.log(f1.toString())
console.log(f2.toString())
}
async函数就是将Generator函数的*替换成async,将yield替换成await。Generator函数的执行必须靠执行器,而async函数自带执行器,async函数的执行,与普通函数一模一样async和await,比起星号和yield语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面表达式需要等待结果co模块约定,yield命令后面只能是Thunk函数或Promise对象,而async函数的await命令后面,可以是Promise对象和原始类型的值async函数的返回值是Promise对象,这比Generator函数的返回值是Iterator对象方便多了。可以使用then方法指定下一步操作async函数完全可以看做多个异步操作,包装成的一个Promise对象,而await命令就是内部then命令的语法糖
await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码中。或用在内部使用.catch(err=>{...})
async function main() {
try {
const val1 = await firstStep()
const val2 = await secondStep(val1)
const val3 = await thirdStep(val1, val2)
console.log('Final: ', val3)
} catch (err) {
console.error(err)
}
}
数组方法扩展
Array.prototype.forEach
替代 for 循环对数组进行循环遍历
arr.forEach(function(v,i){...})
Array.prototype.map
对数组进行遍历,同时会返回一个新数组,新数组中的每一项都是回调函数中的返回值
var list = [1, 2, 3, 4, 5]
var arr = list.map(function (v, i) {
return v * 2
}) // [2,4,6,8,10]
Array.prototype.findIndex
对数组进行遍历,会返回一个满足回调函数条件的元素的索引
var list = [1, 2, 3, 4, 5]
var index = list.findIndex(function (v, i) {
if (v == 4) return true
}) // 3
Array.prototype.filter
对数组过滤,对数组会遍历,v 就是遍历的当前项。当遍历的过程中满足函数中条件时return true会将当前遍历的这一项放到一个新数组中
var list = [1,2,3,4,5]
var arr = list.filter(function(v,i){return v%2 = = 0}) // [2,4]
Array.prototype.some
对数组进行遍历,返回一个布尔值,判断当前数组中是否有一个元素符合回调函数中的条件(特点:只要一个元素满足条件,最终返回结果就是true)
var list = [1, 2, 3, 4, 5]
var flag = list.some(function (v, i) {
if (v % 2 == 0) return true
}) // true
Array.prototype.every
对数组进行遍历,返回一个布尔值,判断当前数组中是否每一个元素都符合回调函数中的条件(特点:只要一个元素不满足条件,最终返回结果就是false)
var list = [1, 2, 3, 4, 5]
var flag = list.every(function (v, i) {
if (v % 2 == 0) return true
}) // false
