1.变量声明let和const
通常用let和const来声明,let表示变量、const表示常量。let和const都是块级作用域。怎么理解这个块级作用域?
说白了 {}大括号内的代码块即为let 和 const的作用域。
2.基本的字符串格式化。
将表达式嵌入字符串中进行拼接。用${}来界定。
如://es5 var name = 'lux' console.log('hello' + name)
//es6 const name = 'lux' console.log(`hello ${name}`)
结果://hello lux
3.对于字符串es6当然也提供了很多厉害的方法。
说几个常用的。
1.includes:判断是否包含然后直接返回布尔值 let str = 'hahay' console.log(str.includes('y')) // true
2.repeat: 获取字符串重复n次 let s = 'he' console.log(s.repeat(3)) // 'hehehe'
3.如果你带入小数, Math.floor(num) 来处理
4.ES6为参数提供了默认值。
在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。
function action(num = 200){
console.log(num)
}
action() //200
action(300) //300
5.箭头函数
(1)[1,2,3].map( x => x + 1 )
等同于: [1,2,3].map((function(x){
return x + 1
}).bind(this))
var f = v => v;
等同于:var f = function(v) {
return v;
};
(2)如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5;
// 等同于
var f = function (){
return 5
};
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略{};
例如:var people = name => 'hello' + name //参数name就没有括号
var people = (name, age) => {
const fullName = 'h' + name
return fullName
} //如果缺少()或者{}就会报错
(3)由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
var getTempItem = id => ({ id: id, name: "Temp" });
(4)箭头函数可以与变量解构结合使用。
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
6.对象初始化简写
ES5我们对于对象都是以键值对的形式书写,是有可能出现键值对重名的。例如:
function people(name, age) {
return { name: name, age: age };
}
键值对重名,ES6可以简写如下:
function people(name, age) {
return { name, age };
}
7.ES6 同样改进了为对象字面量方法赋值的语法。ES5为对象添加方法:
const people = {
name: 'lux', getName: function() {
console.log(this.name)
}
}
ES6通过省略冒号与 function 关键字,将这个语法变得更简洁
const people = {
name: 'lux', getName (){
console.log(this.name)
}
}
8.ES6 对象提供了Object.assign()这个方法来实现浅复制。
Object.assign()可以把任意多个源对象自身可枚举的属性拷贝给目标对象,然后返回目标对象。第一参数即为目标对象。在实际项目中,我们为了不改变源对象。一般会把目标对象传为{}
const obj = Object.assign({}, objA, objB)
9.数组和对象是JS中最常用也是最重要表示形式。为了简化提取信息,ES6新增了解构,这是将一个数据结构分解为更小的部分的过程
ES5我们提取对象中的信息形式如下:
const people = { name: 'lux', age: 20 }
const name = people.name
const age = people.age
console.log(name + ' --- ' + age)
现在,ES6解构能让我们从对象或者数组里取出数据存为变量
对象: const people = { name: 'lux', age: 20 }
const { name, age } = people
console.log(`${name} --- ${age}`)
数组: const color = ['red', 'blue']
const [first, second] = color
console.log(first) //'red'
console.log(second) //'blue'
10.ES6中另外一个好玩的特性就是Spread Operator 也是三个点儿...接下来就展示一下它的用途。
(1)组装对象或者数组
数组:const color = ['red', 'yellow']
const colorful = [...color, 'green', 'pink']
console.log(colorful) //[red, yellow, green, pink]
对象: const alp = { fist: 'a', second: 'b'}
const alphabets = { ...alp, third: 'c' }
console.log(alphabets) //{ "fist": "a", "second": "b", "third": "c" }
(2)有时候我们想获取数组或者对象除了前几项或者除了某几项的其他项
number = [1,2,3,4,5]
const [first, ...rest] = number
console.log(rest) //2,3,4,5
对象: const user = { username: 'lux', gender: 'female', age: 19, address: 'peking' }
const { username, ...rest } = user
console.log(rest) //{"address": "peking", "age": 19, "gender": "female" }
(3)对于 Object 而言,还可以用于组合成新的 Object 。 当然如果有重复的属性名,右边覆盖左边
const first = { a: 1, b: 2, c: 6, }
const second = { c: 3, d: 4 }
const total = { ...first, ...second }
console.log(total) // { a: 1, b: 2, c: 3, d: 4 }
11.import导入模块、export导出模块
(1)全部导入 import people from './example'
(2)有一种特殊情况,即允许你将整个模块当作单一对象进行导入 ,该模块的所有导出都会作为对象的属性存在
如:import * as example from "./example.js"
console.log(example.name)
console.log(example.age)
console.log(example.getName())
(3)导入部分 import {name, age} from './example'
(4) 导出默认, 有且只有一个默认 export default App
(5) 部分导出 export class App extend Component {};
注意:1.当用export default people导出时,就用 import people 导入(不带大括号)
2.一个文件里,有且只能有一个export default。但可以有多个export。
3.当用export name 时,就用import { name }导入(记得带上大括号)
4.当一个文件里,既有一个export default people, 又有多个export name 或者 export age时,导入就用 import people, { name, age }
5.当一个文件里出现n多个 export 导出很多模块,导入时除了一个一个导入,也可以用import * as example
12.用同步的方式去写异步代码。
发起异步请求:fetch('/api/todos') .then(res => res.json()).then(data =>({ data })).catch(err => ({ err }));
13.生成器( generator)是能返回一个迭代器的函数。
生成器函数也是一种函数,最直观的表现就是比普通的function多了个星号*,在其函数体内可以使用yield关键字,有意思的是函数会在每个yield后暂停。
这里生活中有一个比较形象的例子。咱们到银行办理业务时候都得向大厅的机器取一张排队号。你拿到你的排队号,机器并不会自动为你再出下一张票。也就是说取票机“暂停”住了,直到下一个人再次唤起才会继续吐票。
OK。说说迭代器。当你调用一个generator时,它将返回一个迭代器对象。这个迭代器对象拥有一个叫做next的方法来帮助你重启generator函数并得到下一个值。next方法不仅返回值,它返回的对象具有两个属性:done和value。value是你获得的值,done用来表明你的generator是否已经停止提供值。继续用刚刚取票的例子,每张排队号就是这里的value,打印票的纸是否用完就这是这里的done。
// 生成器
function *createIterator() {
yield
1;
yield
2;
yield
3;
}
// 生成器能像正规函数那样被调用,但会返回一个迭代器
let iterator = createIterator();
console.log(iterator.next().value);
// 1
console.log(iterator.next().value);
// 2
console.log(iterator.next().value);
// 3
那生成器和迭代器又有什么用处呢?
围绕着生成器的许多兴奋点都与异步编程直接相关。异步调用对于我们来说是很困难的事,我们的函数并不会等待异步调用完再执行,你可能会想到用回调函数,(当然还有其他方案比如Promise比如Async/await)。
生成器可以让我们的代码进行等待。就不用嵌套的回调函数。使用generator可以确保当异步调用在我们的generator函数运行一下行代码之前完成时暂停函数的执行。
那么问题来了,咱们也不能手动一直调用next()方法,你需要一个能够调用生成器并启动迭代器的方法。就像这样子的
function run(taskDef) { //taskDef即一个生成器函数
// 创建迭代器,让它在别处可用
let task = taskDef();
// 启动任务
let result = task.next();
// 递归使用函数来保持对 next() 的调用
function step() {
// 如果还有更多要做的
if (!result.done) {
result = task.next();
step();
}
}
// 开始处理过程
step();
}