本文共 22810 字,大约阅读时间需要 76 分钟。
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
应用场景:以后声明变量使用 let 就对了
代码示例:let
//變量申明,不允許重複申明 let a = "a", d = { }; let a = "this is a"; console.log(a) //块作用域 let b, c; { let boy = "月月" } console.log(boy) //变量提升不存在 try () { console.log(school) let school = "长沙民政"; } //可访问外层let变量 { let collage = "长沙民政" function fn() { console.log(collage) } fn() }
代码示例:let案例:点击div块改变对应div块的颜色
letExample 点击改变颜色
const 关键字用来声明常量,const 声明有以下特点
注意: 对象属性修改和数组元素变化不会出发 const 错误
应用场景:声明对象类型使用 const,非对象类型声明选择 let代码示例:const
// const 声明变量 必须要赋初始值 const a; //默认常量使用大写(规范) const DIR = 4 //常量值不可修改 const TOP = 1 TOP = 3 console.log(TOP) //const 声明的数组、对象的值可改变 // 虽然数组、对象的值改变了,但是其常量所指向的地址没有发生改变
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称
为解构赋值。代码示例:
//解构赋值 const arr = ["the shy", "ning", "rookie", "baolan"]; let [S, Y, Z, F] = arr; console.log(S); console.log(Y); console.log(Z); console.log(F); // 对象结构 const Rookie = { name:"宋义进", age:23, middle:function(){ console.log("IG middle"); } } let { name,age,middle} = Rookie; console.log(name) console.log(age) console.log(middle) // let {middle} = Rookie // console.log(middle)
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
代码示例:
// `` 反引号 let str = `is string` console.log(str) console.log(typeof str) // 内容中可以出现换行 let stringSingle = "
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这
样的书写更加简洁。代码示例:
let name = "name"; let change = function(){ console.log("change") } const obj ={ name, change, noChange:function(){ console.log("no change") } } console.log(obj)
ES6 允许使用「箭头」(=>)定义函数。
箭头函数的注意点:
代码示例:
let f = function() { } let t = (a, b) => { return a + b } console.log(t(1, 2)) // 箭头函数的特点 // 1 this是静态的,this始终指向函数声明时所在作用域下的this function getName() { console.log(this.name) } let getName1 = () => { console.log(this.name) } // 改变window下的这个name的值 window.name = '月月鸟' getName() getName1() const obj1 = { name: '黄月月' } // 使用call函数改变当前this的值 getName.call(obj1) getName1.call(obj1) // 不能使用箭头函数保存agruments实参 let fn = () => { console.log(arguments); } // fn() // 箭头函数的省略 let fn1 = (n) => { return n * n } // 当形参只有一个点时候可以省略括号 let fn2 = n => { return n * n } // 只有一条语句可省略大括号和return let fn3 = n => n * n console.log(fn1(3)) console.log(fn2(3)) console.log(fn3(3))
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
代码示例:
// ES5 function data(){ console.log(arguments) } data('黄','月','月'); // ES6 rest参数 // rest 参数必须放在最后 function data1(...args){ console.log(args) } data1('黄','月','月');
扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
代码示例:
// ... 扩展运算符可以将数组转换为逗号分隔的参数序列 const IG = ['the shy','ning','rookie','jackerlove','baolan'] function LPL(){ console.log(arguments) } LPL(IG) LPL(...IG) // 数组合并 const a = ['1','2','3'] const b = ['4','5','6'] // 对于ES5 console.log(a.concat(b)) // 对于ES6 扩展运算符来说直接在中间加上一个逗号即可 console.log([...a,...b]); // 数组克隆 const SZH = ['E','G','M'] const SYC = [...SZH] console.log(SYC) // 伪数组转真数组 const divs = document.querySelectorAll("div") const divArr = [...divs] console.log(divArr)
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点
代码示例:
// 创建Symbol let s = Symbol() console.log(s) console.log(typeof s) let s2 = Symbol('s2') console.log(s2) let s3 = Symbol('s2') console.log(s2 == s3) let s4 = Symbol.for('s4') console.log(s4) // 不可进行运算 let res = s4 + 100
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
代码示例:
const IG = ['the shy', 'ning', 'rookie', 'jackerlove', 'baolan'] // 使用 for of 进行遍历 for (item of IG) { console.log(item) } // of 得到值 in得到索引 for (item in IG) { console.log(item) } // 迭代 往后指 得到value和done的值 let iterator = IG[Symbol.iterator](); console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next())
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
生成器注意点:
*
的位置没有限制代码示例:
function* gen() { console.log("hello world") } let res = gen() console.log(res) res.next() // yield 作为代码分隔符 function* gen1() { console.log('1') yield 'this is one' console.log('2') yield 'this is two' console.log('3') yield 'this is three' } // 不会执行 let res1 = gen1() res1.next() res1.next() res1.next() // 生成器参数 function* gen2(arg) { console.log(arg) let B = yield 111; console.log(B) yield 222; yield 333; } let res2 = gen2("AA") console.log(res2.next()) // next 方法可传实参 console.log(res2.next("BBB")) console.log(res2.next())
生成器实例:代码示例:解决异步问题,这里使用定时器模拟异步数据
// 异步编程处理 IO Ajax SQL // 案例 1秒后输出111 2秒后输出222 等等 // 延时器回调嵌套 套娃模式 // setTimeout(() => { // console.log("111") // setTimeout(() => { // console.log("222") // setTimeout(() => { // console.log("333") // }, 3000) // }, 2000) // }, 1000) // function one(){ setTimeout(() => { console.log("111"); res.next(); }, 1000) } function two(){ setTimeout(() => { console.log("222"); res.next(); }, 2000) } function three(){ setTimeout(() => { console.log("333"); res.next(); }, 3000) } // 使用生成器 function * gen (){ yield one(); yield two(); yield three(); } let res = gen(); res.next();
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,
用来封装异步操作并可以获取其成功或失败的结果。Promise对象的创建和then方法,代码示例:
// 实例化 Promise 对象 const p = new Promise(function(resolve, reject) { setTimeout(() => { // 成功 // let data = 'user'; // resolve(data) // 失败 let data = 'defult' reject(data) }, 1000) }) // p.then(function(value) { console.log(value) }, function(reason) { console.log(reason) })
使用Promise对象读取文件模拟异步请求处理,代码示例:(用到nodsjs的fs模块):
const fs = require('fs')//读取文件// fs.readFile('./君子有所为.md', (err, data) => { // if (err) throw err;// console.log(data.toString())// })// 使用Promise 进行封装const p = new Promise(function(resolve, reject) { fs.readFile('./../君子有所为.md', (err, data) => { if (err) reject(err); if (data) resolve(data.toString()) })})p.then(function(value) { console.log(value)}, function(reason) { console.log(reason)})
使用Promise对象封装Ajax请求,代码示例:
// 创建对象 const xhr = new XMLHttpRequest() // 初始化 xhr.open('GET', "http://api.apiopen.top/getJoke") // 发送请求 xhr.send() // 绑定事件,处理结果 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300) { console.log(xhr.response) } else { console.error(xhr.status) } } }
then方法详解,代码示例:
const p = new Promise(function(resolve, reject) { setTimeout(() => { let data = 'defult' resolve(data) }, 1000) }) // then 方法返回结果是Promise 返回状态由回调函数执行结果决定 const res = p.then(value => { console.log(value) // 返回字符串 Promise对象的PromiseValue为返回值 // return '1111' // 返回Promise对象 return new Promise((resolve, reject) => { resolve('ok'); }) }, reason => { console.log(reason) }) console.log(res) // then 支持链式回调 .then(()=>{}).then(()=>{})......
使用Promise读取多个文件操作,代码示例(nodejs):
const fs = require('fs');// fs.readFile('./君子有所为.md', (err, data1) => { // fs.readFile('./我见众生皆草木.md', (err, data2) => { // fs.readFile('./唯见青山不见君.md', (err, data3) => { // console.log(data1 + data2 + data3)// })// })// })// 使用Promiseconst p = new Promise((resolve, reject) => { fs.readFile('./君子有所为.md', (err, data) => { resolve(data.toString()) // 使用toString转字符串,或者使用 +'' 进行字符串拼接 })})// p.then((value, reason) => { // console.log(value)// })p.then((value, reason) => { return new Promise((resolve, reject) => { fs.readFile('./我见众生皆草木.md', (err, data) => { resolve(value + data) }) })}).then((value, reason) => { return new Promise((resolve, reject) => { fs.readFile('./唯见青山不见君.md', (err, data) => { let res = value + data resolve(res) console.log(res) }) })})
catch方法,代码示例:
const p = new Promise((resolve, reject) => { setTimeout(() => { reject("err") }, 1000) }) // p.then((value, reason) => { // console.log(reason) // }) p.catch(reason => { console.log(reason) })
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历
集合的属性和方法:
集合的声明和方法操作,代码示例:
// set 的声明 let set = new Set(); console.log(set) console.log(typeof set) // Set 存储会进行去重 let set2 = new Set(['a', 's', 'd', 'a', 's']) console.log(set2) // 元素的个数 console.log(set2.size); // 添加元素 set2.add('f') // 删除元素 set2.delete('a') // 判断是否存在 set2.has('s') // 清空 //set2.clear() // 遍历 for(let val of set2){ console.log(val) }
集合实践,数组去重、交集、并集、差集,代码示例:
// 1 数组去重 let arr = [1, 2, 2, 3, 3, 4, 4, 2, 1, 1] // let res = new Set(arr) // 这是还是Set集合 // res = [...res] // 转为Array数组 // console.log(res) // 求交集 let arr2 = [1, 2, 3, 4, 23, 2] let res = [...new Set(arr)].filter(item => { let res2 = new Set(arr2) if (res2.has(item)) { return true } else { return false } }) console.log(res) let res2 = [...new Set(arr)].filter(item => new Set(arr2).has(item) ) console.log(res2) // 求并集 let union = [...new Set([...arr, ...arr2])] console.log(union) // 求差集 let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)) ) console.log(diff)
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。
Map 的属性和方法:
map集合的声明和操作,代码示例:
// 声明 let map = new Map() //元素的添加 map.set('name', 'yueyue') map.set('age', 18) map.set('change', function change() { console.log('change function') }) let key = { school: '民院' }; map.set(key, ['长沙市雨花区']) console.log(map) // 个数 console.log(map.size) // 删除 map.delete('age') // 获取 根据键获取 console.log(map.get('name')) console.log(map.get(key)) // 清空 // map.clear() // 遍历 for (let v of map) { console.log(v) }
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
ES5和ES6创建class类的区别,代码示例:
// ES5 // 通过构造函数 function Person(name, age) { this.name = name; this.age = age; } // 添加方法 Person.prototype.myself = function() { console.log('i am person') } // 实例化 let p = new Person('yueyue', 20) console.log(p) p.myself() // ES6 通过class类 class PersonOne { // 构造方法 constructor(name, age) { this.name = name; this.age = age; } myself() { console.log('i am person') } } let p1 = new PersonOne('yueyue', 20) console.log(p1) p1.myself()
// ES5 function Person(name, age) { this.name = name; this.age = age; } Person.prototype.myself = function() { console.log('i am person') } // 继承 function APerson(name, age, size) { // 继承父类 Person.call(this, name, age) this.size = size } // 设置子类构造函数的原型 APerson.prototype = new Person; APerson.prototype.constructor = APerson; // 添加子类方法 APerson.prototype.play = function() { console.log('play') } let p = new APerson('yue', 18, 100) console.log(p) p.myself() p.play() //ES6 class Phone { constructor(name, size) { this.name = name; this.size = size; } call() { console.log('i can call') } } // 继承父类 class huawei extends Phone { constructor(name, size, price) { // 子类调父类的构造方法 super(name, size); // 子类独有的参数构造 this.price = price; } play() { console.log('i can play') } // 方法重写 call(){ console.log('i can huawei call') } } const magic2 = new huawei('magic2', '4.7 inch', 2999) console.log(magic2) magic2.call() magic2.play()
Number.EPSILON 是 JavaScript 表示的最小精度;
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;// JS 小数计算 console.log(0.1 + 0.2 === 0.3) // 数值拓展 function equal(a, b) { if (Math.abs(a - b) < Number.EPSILON) { return true; } else { return false; } } console.log(equal(0.1 + 0.2, 0.3))
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;
// 二进制 八进制 十六进制 let b = 0b111; let o = 0o111; let x = 0xff; console.log(b) console.log(o) console.log(x)
Number.isFinite() 用来检查一个数值是否为有限的;
Number.isNaN() 用来检查一个值是否为 NaN;// 是否为有限数 console.log(Number.isFinite(100)) console.log(Number.isFinite(100 / 0)) // isNaN console.log(Number.isNaN(123))
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;
// 字符串转整数 console.log(Number.parseInt("123456asdf")) console.log(Number.parseFloat("123.456asdf"))
用于去除一个数的小数部分,返回整数部分;
// 将数字的小数去掉 console.log(Math.trunc(123.587))
Number.isInteger() 用来判断一个数值是否为整数;
// 判断是否为整数 console.log(Number.isInteger(2)) console.log(Number.isInteger(2.32))
概述:ES6 新增了一些 Object 对象的方法:
代码示例:
//Object.is 判断两个值是否相等 console.log(Object.is(120, 1)) console.log(Object.is(NaN, NaN)) console.log(NaN == NaN) //Object.assign 对象合并 const a = { name: 'yue', age: '18', size: 10 } const b = { name: 'huang', age: '22', color: 'blue' } // 出现重名进行覆盖 console.log(Object.assign(a, b)) // 设置原型对象 const school = { name: '民院' } const city = { xiaoqu: ['长沙', '广州'] } Object.setPrototypeOf(school, city) console.log(Object.getPrototypeOf(school)) console.log(school)
概述:模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;
模块化的优势有以下几点:
模块功能主要由两个命令构成:export 和 import;
js 暴露
// 分别暴露// me.jsexport let school = '民院'export function say() { console.log('i am 民院')}// 统一暴露// me2.jslet school = '民院'function say() { console.log('i am 民院')}export { school, say}// 默认暴露// me3.jsexport default { meThree: 'this is a', sayThree: function() { console.log('this is say function') }}
导入js模块代码示例:
概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值; 判断数组中是否包含某元素,语法:arr.includes(元素值);概述:
在 ES7 中引入指数运算符**
,用来实现幂运算,功能与 Math.pow 结果相同;幂运算的简化写法,例如:2的10次方:2**10; 代码示例:
//include let arr = [1, 2, 3, 4, 5]; console.log(arr.includes(2)) // 幂运算 console.log(10 ** 2) console.log(Math.pow(10, 2))
async 和 await 两种语法结合可以让异步代码像同步代码一样
代码示例:
async function fn() { // 返回的不是Promise对象,那么这个函数返回的就是一个成功的Promise // return 'this is function' // return null 也就是undefined // return; // 抛出错误,则返回结果为一个失败的Promise // throw new Error('404') // 返回结果为一个Promise 对象 return new Promise((resolve, reject) => { resolve('success') }) } const f = fn() f.then((value, reason) => { console.log(value) })
代码示例:
const p = new Promise((resolve, reject) => { resolve('success') }) async function fn() { let res = await p; console.log(res) } fn() const p1 = new Promise((resolve, reject) => { reject('err') }) async function fn1() { try { let res1 = await p1; console.log(res1) } catch (e) { console.log(e) } } fn()
代码示例:使用nodejs读取文件进行模拟
const fs = require('fs')function read1() { return new Promise((resolve, reject) => { fs.readFile('./君子有所为.md', (err, data) => { if (err) reject(err) resolve(data) }) })}function read2() { return new Promise((resolve, reject) => { fs.readFile('./唯见青山不见君.md', (err, data) => { if (err) reject(err) resolve(data) }) })}function read3() { return new Promise((resolve, reject) => { fs.readFile('./我见众生皆草木.md', (err, data) => { if (err) reject(err) resolve(data) }) })}// asyncasync function read() { let r1 = await read1(); let r2 = await read2() let r3 = await read3() console.log(r1 + r2 + r3)}read()
该方法返回指定对象所有自身属性的描述对象
代码示例:
const school = { name: '民院', cities: ['长沙', '广州', '深圳', ], } // 获取所有键与值 console.log(Object.keys(school)) console.log(Object.values(school)) console.log(Object.entries(school)) const map = new Map(Object.entries(school)) console.log(map.get('name')) console.log(Object.getOwnPropertyDescriptors(school))
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符代码示例:
function self({ name, age, ...user }) { console.log(name) console.log(age) console.log(user) } self({ name: 'yueyue', age: 18, hieght: '170cm', weight: '62kg' }) const person = { name: 'huang', age: '18', color: 'huang' } console.log({ ...person })
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
代码示例:
let str = 'baidu' const reg = /(.*)<\/a>/ const res = reg.exec(str) console.log(res) let str1 = 'baidu' const reg1 = /(?.*)<\/a>/ const res1 = reg1.exec(str1) console.log(res1) console.log(res1.groups.url) console.log(res1.groups.text)
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
let str = '123456是是是555啊啊啊'; // 正向断言 const reg = /\d+(?=啊)/ const res = reg.exec(str) console.log(res) // 反向断言 const reg1 = /(?<=是)\d+/ const res1 = reg.exec(str) console.log(res1)
正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行
终止符出现代码示例:
let str = `` // 使用正则进行匹配 const reg = /
(.*?)<\/p>/gs // gs 进行全局匹配 let res1; // 使用data进行保存 let data = [] while (res1 = reg1.exec(str)) {
//console.log(res1) data.push({ title: res1[1], time: res1[2] }) } console.log(data)把键值对列表转换为一个对象。
代码示例:
// 二维数组 const res = Object.fromEntries([ ['name', 'yueyue'], ['age', 18] ]) console.log(res) // map 对象 const m = new Map(); m.set('name', 'huang') const res1 = Object.fromEntries(m) console.log(res1)
清除空字符串
代码示例:
let str = ' this is str ' console.log(str) // 清除空字符串 console.log(str.trimStart()) console.log(str.trimEnd())
flat 方法会按照一个指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回
flatMap方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与map连着深度值为1的flat几乎相同,但flatMap通常在合并成一种方法的效率稍微高些。
代码示例:
// flat 多维数组转低维数组 let arr = [1, 2, 3, [4, 5, [1, 55, [4]]]] // 参数 表示 降几个维度 console.log(arr.flat(2)) let arr1 = [4, 5, 2] const res = arr1.flatMap((item) => [item * 58]) console.log(res)
description 是一个只读属性,它会返回 Symbol 对象的可选描述的字符串。
代码示例:
let s = Symbol('this is symbol') console.log(s.description)
代码示例:
let str = `` let reg = /
(.*?)<\/p>/sg // const result = reg.exec(str) // 进行全局匹配 const result = str.matchAll(reg) console.log(result) for (let v of result) {
console.log(v) }私有属性采用 # 进行定义,和Java一样,私有属性在类的外部是获取不到的。
代码示例:
class Person { // 共有属性 name; // 私有属性 #age; // 构造方法 constructor(name, age) { this.name = name; this.#age = age; } sayAge() { console.log(this.#age) } } const gril = new Person('qing', 18) console.log(gril) console.log(gril.name) // 私有属性无法访问 undefined console.log(gril.age) // 只有在类里面才可以获取到这个私有属性 gril.sayAge()
该Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用它。
代码示例:
const p1 = new Promise(( resolve, reject ) => { setTimeout(() => { resolve('data1') }, 1000) }); const p2 = new Promise(( resolve, reject ) => { setTimeout(() => { //resolve('data2') reject('err') }, 1000) }); // 返回一个成功的Promise对象 const result = Promise.allSettled([p1, p2]); console.log(result) // 有一个Promise对象失败 则返回的是一个失败的Promise const result1 = Promise.all([p1, p2]) console.log(result1)
// 始终指向全局 console.log(globalThis)
转载地址:http://hkqzi.baihongyu.com/