慕课链接:https://coding.imooc.com/class/444.html
继续系统加固前端知识,我发现先看文档,视频辅助效率最高;Fighting
电子书网址:http://es.xiecheng.live
Babel 编译器:https://www.babeljs.cn/
为什么我要写这个笔记? 万一哪天域名失效了呢,是吧,当个文档字典来查吧
ECMAScript2015 新的声明方式:let 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 let a = 5 console .log(a)console .log(window .a)console .log(a)var a = 5 var a = 5 if (true ) { a = 6 let a } for (let i = 0 ; i < 3 ; i++) { console .log('循环内:' + i) } console .log('循环外:' + i) for (var i = 0 ; i < 3 ; i++) { (function (j ) { setTimeout (function ( ) { console .log(j) }) })(i) } for (let i = 0 ; i < 3 ; i++) { setTimeout (function ( ) { console .log(i) }) }
新的声明方式:const 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const a = 5 const obj = { name : 'xiecheng' , age : 34 , skill : { name : 'code' , year : 11 } } Object .freeze(obj)console .log(obj)obj.school = 'imooc' obj.skill.year = 12 console .log(obj)
解构赋值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 let [a, b, [c, d]] = [1 , 2 , [3 , 4 ]]console .log(a, b, c, d)let [a, b, [c]] = [1 , 2 , [3 , 4 ]]console .log(a, b, c) let [a, b, c] = [1 , 2 , [3 , 4 ]]console .log(a, b, c) let [a, b, c, d = 5 ] = [1 , 2 , [3 , 4 ], 6 ]console .log(a, b, c, d) function foo ([a, b, c] ) { console .log(a, b, c) } let arr = [1 , 2 , 3 ]foo(arr) let json = '{"a": "hello", "b": "world"}' let {a, b}= JSON .parse(json)console .log(a, b)
数组相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 arr.forEach(function (elem, index, array ) { console .log(elem, index) }) let result = arr.map(function (value ) { value += 1 return value }) console .log(arr, result)let result = arr.filter(function (value ) { return value == 2 }) console .log(arr, result)let result = arr.some(function (value ) { return value == 4 }) console .log(arr, result)let result = arr.every(function (value ) { return value == 2 }) console .log(arr, result)let sum = arr.reduce(function (prev, cur, index, array ) { return prev + cur }, 0 ) console .log(sum)for (let val of [1 , 2 , 3 ]) { console .log(val); } let imgs = Array .from(document .querySelectorAll('img' )); Array .from({ length : 5 }, function ( ) { return 1 }) let array = [1 , 2 , 3 , 4 ]array.fill(0 , 1 , 2 ) let array = [5 , 12 , 8 , 130 , 44 ];let found = array.find(function (element ) { return element > 10 ; }); console .log(found);let array = [5 , 12 , 8 , 130 , 44 ];let found = array.find(function (element ) { return element > 10 ; }); console .log(found);let arr = [1 , 2 , 3 , 4 , 5 ]console .log(arr.copyWithin(1 , 3 ))
函数相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 function foo (x, y = 'world' ) { console .log(x, y) } foo('hello' , 0 ) function foo (a, b = 1 , c ) { console .log(foo.length) } foo('a' , 'b' ) function sum (...nums ) { let num = 0 nums.forEach(function (item ) { num += item * 1 }) return num } function sum (x = 1 , y = 2 , z = 3 ) { return x + y + z } console .log(sum(...[4 ])) function foo (x = 1 , y = 2 , z = 3 ) { console .log(x, y) } console .log(foo.length)let hello = (name ) => { console .log('say hello' , name) } let person = (name ) => ({ age : 20 , addr : 'Beijing City' }) let foo = { name : 'es' , say : function ( ) { console .log(this .name) } } console .log(foo.say()) let foo = { name : 'es' , say : () => { console .log(this .name, this ) } } console .log(foo.say())
对象相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 let obj1 = { name : 'xiecheng' , age : 34 } let obj2 = { name : 'xiecheng' , age : 34 } console .log(obj1 == obj2) console .log(Object .is(obj1, obj2)) let obj2 = obj1 console .log(Object .is(obj1, obj2)) const target = { a : 1 , b : 2 } const source = { b : 4 , c : 5 } const returnedTarget = Object .assign(target, source)console .log(target) console .log(returnedTarget) for (let key in obj) { console .log(key, obj[key]) } Object .keys(obj).forEach(key => { console .log(key, obj[key]) })
Class相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 class Animal { constructor (type ) { this .type = type } walk ( ) { console .log( `I am walking` ) } } let dog = new Animal('dog' )let monkey = new Animal('monkey' )console .log(dog.hasOwnProperty('type' )) class Animal { constructor (type, age ) { this .type = type this ._age = age } get age () { return this ._age } set age (val ) { this ._age = val } } class Animal { constructor (type ) { this .type = type } walk ( ) { console .log( `I am walking` ) } static eat ( ) { console .log( `I am eating` ) } } let Dog = function ( ) { Animal.call(this , 'dog' ) this .run = function ( ) { console .log('I can run' ) } } Dog.prototype = Animal.prototype class Animal { constructor (type ) { this .type = type } walk ( ) { console .log( `I am walking` ) } static eat ( ) { console .log( `I am eating` ) } } class Dog extends Animal { constructor ( ) { super ('dog' ) } run () { console .log('I can run' ) } }
Symbol相关 数据类型 Symbol
,表示独一无二的值,可以保证不会与其他属性名产生冲突
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 let s1 = Symbol ('foo' )let s2 = Symbol ('foo' )console .log(s1)console .log(s2)console .log(s1 === s2) let s1 = Symbol .for('foo' )let s2 = Symbol .for('foo' )console .log(s1 === s2) const s1 = Symbol ('foo' )console .log(Symbol .keyFor(s1)) const s2 = Symbol .for('foo' )console .log(Symbol .keyFor(s2)) const stu1 = Symbol ('李四' )const stu2 = Symbol ('李四' )const grade = { [stu1]: { address : 'yyy' , tel : '222' }, [stu2]: { address : 'zzz' , tel : '333' }, } console .log(grade)console .log(grade[stu1])console .log(grade[stu2])const shapeType = { triangle : Symbol (), circle : Symbol () } function getArea (shape ) { let area = 0 switch (shape) { case shapeType.triangle: area = 1 break case shapeType.circle: area = 2 break } return area } console .log(getArea(shapeType.triangle))
Set相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 let s = new Set ([1 , 2 , 3 , 4 ])s.add('hello' ).add('goodbye' ) s.delete('hello' ) s.clear() s.has('hello' ) s.size let arr1 = [1 , 2 , 3 , 4 ]let arr2 = [2 , 3 , 4 , 5 , 6 ]let s = new Set ([...arr1, ...arr2])let s1 = new Set (arr1)let s2 = new Set (arr2)let result = new Set (arr1.filter(item => s2.has(item)))console .log(Array .from(result))let arr3 = new Set (arr1.filter(item => !s2.has(item)))let arr4 = new Set (arr2.filter(item => !s1.has(item)))console .log(arr3)console .log(arr4)console .log([...arr3, ...arr4])console .log(s.keys()) console .log(s.values()) console .log(s.entries()) s.forEach(item => { console .log(item) }) for (let item of s) { console .log(item) }
String相关 1 2 3 4 5 6 7 8 9 10 `string text ${expression} string text` console .log(String .fromCodePoint(0x20BB7 ))console .log(str.indexOf('mo' ))console .log(str.includes('mo' ))
Number相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const a = 0B0101 console .log(a)const b = 0O777 console .log(b)Number .isFinite(NaN ) Number .isNaN(NaN ) Number .isInteger(25.1 )
Proxy相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 let o = { name : 'xiaoming' , age : 20 } console .log(o.from || '' )let handler = { get (obj, key ) { return Reflect .has(obj, key) ? obj[key] : '' } } let p = new Proxy (o, handler)console .log(p.from)export default (obj, key, value) => { if (Reflect .has(key) && value > 20 ) { obj[key] = value } } import Validator from './Validator' let data = new Proxy (response.data, { set : Validator }) let dict = { 'hello' : '你好' , 'world' : '世界' } dict = new Proxy (dict, { get (target, prop ) { return prop in target ? target[prop] : prop } }) console .log(dict['world' ])console .log(dict['imooc' ])let arr = []arr = new Proxy (arr, { set (target, prop, val ) { if (typeof val === 'number' ) { target[prop] = val return true } else { return false } } }) arr.push(5 ) arr.push(6 ) console .log(arr[0 ], arr[1 ], arr.length)let range = { start : 1 , end : 5 } range = new Proxy (range, { has (target, prop ) { return prop >= target.start && prop <= target.end } }) console .log(2 in range)console .log(9 in range)
*Promise相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 const promise = new Promise (function (resolve, reject ) { if ( ) { resolve(value) } else { reject(error) } }) promise.then(function (value ) { console .log(value) }, function (error ) { console .error(error) }) .catch((e ) => { console .log(e.message) }) new Promise (function (resolve ) { resolve(42 ) }) Promise .reject(new Error ("出错了" )) === new Promise (function (resolve, reject ) { reject(new Error ('出错了' )) }) var p1 = Promise .resolve(1 )var p2 = Promise .resolve(2 )var p3 = Promise .resolve(3 )Promise .all([p1, p2, p3]).then(function (results ) { console .log(results) }) var p1 = Promise .resolve(1 )var p2 = Promise .resolve(2 )var p3 = Promise .resolve(3 )Promise .race([p1, p2, p3]).then(function (value ) { console .log(value) })
Generator相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 function * generatorForLoop ( ) { for (let i = 0 ; i < 5 ; i += 1 ) { yield console .log(i) } } const genForLoop = generatorForLoop()console .log(genForLoop.next()) console .log(genForLoop.next()) function * gen ( ) { let val val = yield 1 console .log( `1:${val} ` ) val = yield 2 console .log( `2:${val} ` ) val = yield 3 console .log( `3:${val} ` ) } var g = gen()console .log(g.next()) console .log(g.next()) console .log(g.next()) console .log(g.next()) function * gen ( ) { var val = 100 while (true ) { console .log( `before ${val} ` ) val = yield val console .log( `return ${val} ` ) } } var g = gen()console .log(g.next(20 ).value) console .log(g.next(30 ).value) console .log(g.return()) g.throw(new Error ('break' ))
Iterator相关 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 let authors = { allAuthors : { fiction : [ 'Agatha Christie' , 'J. K. Rowling' , 'Dr. Seuss' ], scienceFiction : [ 'Neal Stephenson' , 'Arthur Clarke' , 'Isaac Asimov' , 'Robert Heinlein' ], fantasy : [ 'J. R. R. Tolkien' , 'J. K. Rowling' , 'Terry Pratchett' ] } } authors[Symbol .iterator] = function ( ) { let allAuthors = this .allAuthors let keys = Reflect .ownKeys(allAuthors) let values = [] return { next ( ) { if (!values.length) { if (keys.length) { values = allAuthors[keys[0 ]] keys.shift() } } return { done : !values.length, value : values.shift() } } } } for (let value of authors) { console .log( `${value} ` ) } authors[Symbol .iterator] = function *( ) { let allAuthors = this .allAuthors let keys = Reflect .ownKeys(allAuthors) let values = [] while (1 ) { if (!values.length) { if (keys.length) { values = allAuthors[keys[0 ]] keys.shift() yield values.shift() } else { return false } } else { yield values.shift() } } }
Module模块 将每个js文件看作是一个模块,每个模块通过固定的方式引入,并且通过固定的方式向外暴露指定的内容
按照js模块化的设想,一个个模块按照其依赖关系组合,最终插入到主程序中
无模块化–>CommonJS规范–>AMD规范–>CMD规范–>ES6模块化
在ES6中,可以使用 import 关键字引入模块,通过 exprot 关键字导出模块,但是由于ES6目前无法在浏览器中执行,所以,只能通过babel将不被支持的import编译为当前受到广泛支持的 require
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 export const name = 'hello' export let addr = 'BeiJing City' export function say (content ) { console .log(content) } const name = 'hello' let addr = 'BeiJing City' var list = [1 , 2 , 3 ]export { name as cname, addr as caddr, list } import list, { cname, caddr } from A
ECMAScript2016(ES7) Array.prototype.includes() ES7引入的Array.prototype.includes() 方法用来判断一个数组是否包含一个指定的值
1 2 3 4 5 6 7 8 9 10 const arr = ['es6' , 'es7' , 'es8' ]console .log(arr.includes('es6' )) const arr = ['es6' , 'es7' , 'es8' ]console .log(arr.includes('es7' , 1 )) console .log(arr.includes('es7' , 2 )) const demo = [1 , NaN , 2 , 3 ]demo.indexOf(NaN ) demo.includes(NaN )
ECMAScript2017(ES8) async / await async 是让我们写起 Promise 像同步操作, 前面添加了async的函数在执行后都会自动返回一个Promise对象
在async函数中使用await,那么await这里的代码就会变成同步的了
意思就是说只有等await后面的Promise执行完成得到结果才会继续下去,await就是等待。
await 只能在 async 标记的函数内部使用,单独使用会触发 Syntax error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 async function foo ( ) { return 'imooc' } console .log(foo()) function timeout ( ) { return new Promise ((resolve, reject ) => { setTimeout (() => { reject('error' ) }, 1000 ) }) } async function foo ( ) { return await timeout() } foo().then(res => { console .log(res) }).catch(err => { console .log(err) })
Object ES8中对象扩展补充了两个静态方法,用于遍历对象:Object.values(),Object.entries()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const obj = { name : 'imooc' , web : 'www.imooc.com' , course : 'es' } console .log(Object .values(obj)) for (let [k, v] of Object .entries(grade)) { console .log(k, v) } const data = { Portland : '78/50' , Dublin : '88/52' , Lima : '58/40' } Object .defineProperty(data, 'Lima' , { enumerable : false }) Object .entries(data).map(([city, temp] ) => { console .log( `City: ${city.padEnd(16 )} Weather: ${temp} ` ) }) console .log(Object .getOwnPropertyDescriptor(data, 'Lima' ))
String 新增了两个实例函数 String.prototype.padStart 和 String.prototype.padEnd
允许将空字符串或其他字符串添加到原始字符串的开头或结尾
1 2 3 const tel = '13012345678' const newTel = tel.slice(-4 ).padStart(tel.length, '*' ) console .log(newTel)
ECMAScript2018(ES9) for await of 循环等待每个Promise对象变为resolved状态才进入下一步,更加优雅了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 function Gen (time ) { return new Promise (function (resolve, reject ) { setTimeout (function ( ) { resolve(time) }, time) }) } async function test ( ) { let arr = [Gen(2000 ), Gen(100 ), Gen(3000 )] for await (let item of arr) { console .log(Date .now(), item) } } let obj = { count : 0 , Gen (time) { return new Promise (function (resolve, reject ) { setTimeout (function ( ) { resolve({ done : false , value : time }) }, time) }) }, [Symbol .asyncIterator] () { let self = this return { next () { self.count++ if (self.count < 4 ) { return self.Gen(Math .random() * 1000 ) } else { return Promise .resolve({ done : true , value : '' }) } } } } } async function test ( ) { for await (let item of obj) { console .log(Date .now(), item) } }
RegExp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const re = new RegExp ('foo.bar' , 's' )console .log(re.test('foo\nbar' )) console .log(re.test('foo\nbar' )) console .log('2020-05-01' .match(/(\d{4})-(\d{2})-(\d{2})/ ))let test = 'hello world' console .log(test.match(/hello(?=\sworld)/ )) console .log(test.match(/(?<=world\s)hello/ ))
Rest & Spread 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const input = { a : 1 , b : 2 } const output = { ...input, c : 3 } const input = { a : 1 , b : 2 , c : 3 } let { a, ...rest } = input
Promise.prototype.finally() 指定不管最后状态如何都会执行的回调函数。Promise.prototype.finally() 方法返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let connectiondb.open() .then(conn => { connection = conn return connection.select({ name : 'Jane' }) }) .then(result => { })··· .catch(error => { }) .finally(() => { connection.close() })
ECMAScript2019(ES10) Object.fromEntries() 1 2 3 4 5 6 7 const obj = { name : 'imooc' , course : 'es' } const entries = Object .entries(obj)const fromEntries = Object .fromEntries(entries)
Array 1 2 3 4 5 6 7 8 9 const numbers = [1 , 2 , [3 , 4 , [5 , 6 ]]]console .log(numbers.flat()) console .log(numbers.flat(2 )) const numbers = [1 , 2 , 3 ]numbers.map(x => [x * 2 ]) numbers.flatMap(x => [x * 2 ])
Symbol 1 2 3 const name = Symbol ('es' )console .log(name.description) console .log(name.description === 'es' )
ECMAScript2020(ES11) Dynamic Import 1 2 3 4 5 6 7 8 9 const oBtn = document .querySelector('#btn' )oBtn.addEventListener('click' , () => { import ('./ajax' ).then(mod => { mod.default('static/a.json' , res => { console .log(res) }) }) })
Promise.allSettled() 并发任务中,无论一个任务正常或者异常,都会返回对应的的状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Promise .allSettled([ Promise .reject({ code : 500 , msg : '服务异常' }), Promise .resolve({ code : 200 , data : ['1' , '2' , '3' ] }), Promise .resolve({ code : 200 , data : ['4' , '5' , '6' ] }) ]).then(res => { console .log(res) const data = res.filter(item => item.status === 'fulfilled' ) console .log(data) }).catch(err => { console .log(err) console .log('失败' ) })
Optional chaining 1 2 3 4 5 6 7 8 9 10 11 12 const user = { address : { street : 'xx街道' , getNum ( ) { return '80号' } } } const street2 = user?.address?.streetconst num2 = user?.address?.getNum?.()console .log(street2, num2)