学习ES6笔记──工作中常用到的ES6语法

一、let和const
function test() {if(true) {console.log(a)//TDZ,俗称临时死区,用来描述变量不提升的现象let a = 1}}test() // a is not definedfunction test() {if(true) {let a = 1}console.log(a)}test() // a is not defined
function test() {if(true) {let a = 1console.log(a)}}test() // 1
const type = {a: 1}type.a = 2 //没有直接修改type的值,而是修改type.a的属性值,这是允许的。console.log(type) // {a: 2}
for(var i = 0; i < 5; i++) {setTimeout(() => {console.log(i) //5, 5, 5, 5, 5}, 0)}console.log(i) //5 i跳出循环体污染外部函数//将var改成let之后for(let i = 0; i < 5; i++) {setTimeout(() => {console.log(i) // 0,1,2,3,4}, 0)}console.log(i)//i is not defined i无法污染外部函数
var mySymbol=Symbol();console.log(typeof mySymbol) //"symbol"
二、字符串
// 以前的多行字符串我们这么写:console.log("hello world 1\n\hello cala");// "hello world// hello cala"//有了模板字符串之后console.log(`hello worldstring text line 2`);// "hello world// hello cala"
var name="cala";var age=22;console.log(`hello,I'am ${name},my age is ${age}`)//hello,I'am cala,my age is 22
let t = 'abcdefg'if(t.includes('cde')) {console.log(2)}//true
let t = 'abcdefg'if(t.startsWith('ab')) {console.log(2)}//true
let t = 'abcdefg'if(t.endsWith('fg')) {console.log(2)}//true
三、函数
在ES5中,我们给函数传参数,然后在函数体内设置默认值,如下面这种方式。
function a(num, callback) {num = num || 6callback = callback || function (data) {console.log('ES5: ', data)}callback(num * num)}a() //ES5: 36,不传参输出默认值//你还可以这样使用callbacka(10, function(data) {console.log(data * 10) // 1000, 传参输出新数值})
function a(num = 6, callback = function (data) {console.log('ES6: ', data)}) {callback(num * num)}a() //ES6: 36, 不传参输出默认值a(10, function(data) {console.log(data * 10) // 1000,传参输出新数值})
四、箭头函数(=>)
const arr = [5, 10]const s = arr.reduce((sum, item) => sum + item)console.log(s) // 15
普通函数:
1、函数作为全局函数被调用时,this指向全局对象
2、函数作为对象中的方法被调用时,this指向该对象
3、函数作为构造函数的时候,this指向构造函数new出来的新对象
4、还可以通过call,apply,bind改变this的指向
箭头函数:
1、箭头函数没有this,函数内部的this来自于父级最近的非箭头函数,并且不能改变this的指向。
2、箭头函数没有super
3、箭头函数没有arguments
4、箭头函数没有new.target绑定。
5、不能使用new
6、没有原型
7、不支持重复的命名参数。
const s = a => aconsole.log(s(2)) // 2
//ES5普通函数function Man(){this.age=22;return function(){this.age+1;}}var cala=new Man();console.log(cala())//undefined//ES6箭头函数function Man(){this.age=22;return () => this.age+1;}var cala=new Man();console.log(cala())//23
//没有argumentsvar foo=(a,b)=>{return arguments[0]*arguments[1]}console.log(foo(3,5))//arguments is not defined//没有原型var Obj = () => {};console.log(Obj.prototype);// undefined//不能使用new 关键字var Obj = () => {"hello world"};var o = new Obj();// TypeError: Obj is not a constructor
const arr = [10, 50, 30, 40, 20]const s = arr.sort((a, b) => a - b)console.log(s) // [10,20,30,40,50]
2、尾调用是函数最后一条语句
3、尾调用结果作为函数返回
在ES5时代,我们不推荐使用递归,因为递归会影响性能。
但是有了尾调用优化之后,递归函数的性能有了提升。
//新型尾优化写法"use strict";function a(n, p = 1) {if(n <= 1) {return 1 * p}let s = n * preturn a(n - 1, s)}//求 1 x 2 x 3的阶乘let sum = a(3)console.log(sum) // 6
五、ES6对象新增方法
var o1 = { a: 1 };var o2 = { b: 2 };var o3 = { c: 3 };var obj = Object.assign(o1, o2, o3);console.log(obj); // { a: 1, b: 2, c: 3 }console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。
var o1 = { a: 1, b: 1, c: 1 };var o2 = { b: 2, c: 2 };var o3 = { c: 3 };var obj = Object.assign({}, o1, o2, o3);console.log(obj); // { a: 1, b: 2, c: 3 }
六、Map和Set
Array的indexOf方法比Set的has方法效率低下
let set = new Set()// Set转化为数组let arr = Array.from(set)let arr = [...set]// 实例属性(继承自Set)set.constructor === Setset.size// 操作方法set.add(1) // 添加一个值set.delete(1) //删除一个值set.has(1) //判断是否有这个值(Array中的indexOf)set.clear() //清除所有值// 获取用于遍历的成员方法(Set的遍历顺序就是插入顺序)set.keys() // 返回键名的遍历器set.values() // 返回键值得遍历器set.entries() // 返回键值对的遍历器set.forEach() // 循环遍历每个值(和Array的方法一致)for (let key of set.keys()){}for (let val of set.values()){}for (let entry of set.entries()){}// 使用数组方法来处理set值set = new Set(arr)set = new Set([...set].map((x) => x = x * 2))set = new Set([...set].filter((x) => x > 2))
let map = new Map()// 实例属性(继承自Map)map.constructor === Mapmap.size// 操作方法map.set(1,2)map.get(1)map.delete(1)map.has(1)map.clear()// 遍历方法map.keys()map.values()map.entries()map.forEach()// Map和数组的转换map = new Map([['key','val'],[2,1]]) // 要求双成员数组let arr = [...map]// 值得注意的是Map的键是跟内存绑定的map.set([1], 's')map.get([1])let arr = [1]let arr1 = [1]map.set(arr, 's')map.get(arr)map.set(arr1, 's')map.get(arr1)
七、迭代器(Iterator)
//数组const arr = ['a', 'b', 'c'];for(let v of arr.entries()) {console.log(v)}// [0, 'a'] [1, 'b'] [2, 'c']//Setconst arr = new Set(['a', 'b', 'c']);for(let v of arr.entries()) {console.log(v)}// ['a', 'a'] ['b', 'b'] ['c', 'c']//Mapconst arr = new Map();arr.set('a', 'a');arr.set('b', 'b');for(let v of arr.entries()) {console.log(v)}// ['a', 'a'] ['b', 'b']
//数组const arr = ['a', 'b', 'c'];for(let v of arr.values()) {console.log(v)}//'a' 'b' 'c'//Setconst arr = new Set(['a', 'b', 'c']);for(let v of arr.values()) {console.log(v)}// 'a' 'b' 'c'//Mapconst arr = new Map();arr.set('a', 'a');arr.set('b', 'b');for(let v of arr.values()) {console.log(v)}// 'a' 'b'
//数组const arr = ['a', 'b', 'c'];for(let v of arr.keys()) {console.log(v)}// 0 1 2//Setconst arr = new Set(['a', 'b', 'c']);for(let v of arr.keys()) {console.log(v)}// 'a' 'b' 'c'//Mapconst arr = new Map();arr.set('a', 'a');arr.set('b', 'b');for(let v of arr.keys()) {console.log(v)}// 'a' 'b'
const obj = {a: 1,b: 2,*[Symbol.iterator]() {for(let i in obj) {yield [i, obj[i]]}}}for(let [key, value] of obj) {console.log(key, value)}// 'a' 1, 'b' 2
const str = 'abc';for(let v of str) {console.log(v)}// 'a' 'b' 'c'
ES6给数组添加了几个新方法:find()、findIndex()、fill()、copyWithin()
const arr = [1, "2", 3, 3, "2"]console.log(arr.find(n => typeof n === "number")) // 1
const arr = [1, "2", 3, 3, "2"]console.log(arr.findIndex(n => typeof n === "number")) // 0
arr.fill(value, start, end)
arr.copyWithin(target, start, end)const arr = [1, 2, 3, 4, 5]console.log(arr.copyWithin(3)) // [1,2,3,1,2] 从下标为3的元素开始,复制数组,所以4, 5被替换成1, 2const arr1 = [1, 2, 3, 4, 5]console.log(arr1.copyWithin(3, 1)) // [1,2,3,2,3] 从下标为3的元素开始,复制数组,指定复制的第一个元素下标为1,所以4, 5被替换成2, 3const arr2 = [1, 2, 3, 4, 5]console.log(arr2.copyWithin(3, 1, 2)) // [1,2,3,2,5] 从下标为3的元素开始,复制数组,指定复制的第一个元素下标为1,结束位置为2,所以4被替换成2
评论
