用于块级做用域
不存在变量提高
不可重复声明
未声明不可以使用
不可以使用window去调用前端
不可重复定义
不可对重复赋值
不存在变量提高
不容许先赋值后声明es6
规定程序源代码中定义的变量执行区域
规定了如何查找等一些列规则正则表达式
全局做用域(global,window)
局部做用域(函数做用域)
块级做用域(let。const定义的代码块区域)
动态做用域(this)数组
函数之外定义的变量
函数内部不经过var定义的变量
不经过var等定义的变量属于window下面的属性能够被删除。var则不能够,严格意义上来讲直接定义的变量不属于全局变量promise
对于可迭代的对象建立一个迭代循环app
转成数组,用法:
Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike类数组或可迭代对象
mapFn若是指定了该参数,都会执行
可选参数,执行回调函数 mapFn 时 this 对象异步
填充数组
arr.fill(value[, start[, end]])
value填充元素
start起始索引
end结束索引
let arr=[1,4,6,7]
arr.fill(99,1,9)async
建立数组
let arr=Array.of(1,43,6,8)函数
find() 方法返回数组中知足提供的测试函数的第一个元素的值,不然返回 undefined。测试
findIndex()方法返回数组中知足提供的测试函数的第一个元素的索引。不然返回-1。其实这个和 find() 是成对的,不一样的是它返回的是索引而不是值。
如何定义并实例化一个类?
es5
function Fn(type) { this.name = type } let fn = new Fn('miya') console.log(fn)
es6
class Fn { constructor(val) { this.name = val } } let fn = new Fn('miya') console.log(fn)
如何读写属性?
es6容许把属性放到函数最顶层,而不是必须放到constructor()函数中
放到最顶层前面加set或者get,由于添加上就会变成属性。
set和get的操做可让咱们灵活改变返回值,可是返回值和出口值不能相同
get+set
class Animal {
constructor (type, age) { this.type = type this._age = age } get age () { return this._age } set age (val) { this._age = val }
}
es5属性进行修改没法拦截,有条件写和设置丢作不到
es6经过get。set就能够作到,让你在读写操做上有更大的操做权,甚至能够定制化
操做方法
经过对象实例 添加方法
经过类的静态方法添加
定义时前面添加static fn(){}
使用时类调用
class Animal { constructor(type, age) { this.type = type this._age = age } get age() { return this._age } set age(val) { this._age = val } static run() { console.log('run ') } } let a = new Animal('miya', 18)
不属于对象实例上的方法,属于类的静态方法,直接从对象实例访问不到
经过类去访问
若是这个方法不依赖对象实例上的属性和方法使用类的静态方法
反之,使用对象的实例方法
对象属性值简写
key。value的简写
属性支持变量和表达式,只需用花括号抱起来便可
在obejct中能够添加异步函数(加*)
let [x,y]=[1,99] let obj={x,y,[x+y]:8,* fn (){console.log(212)}}
set
值能够是任意值
方法:添加
let s=new Set()
s.add(12).add(89)
方法:删除某一项。
let s=new Set()
s.add(12).add(89)
s.delete(10)
方法:删除全部。
let s=new Set()
s.add(12).add(89)
s.clear()
方法:判断元素是否存在
let s=new Set()
s.add(12).add(89)
s.has(12)
keys=>获取全部keys值
values=>获取全部value值
s.entries()=>获取健值对
属性:获取已经存元素的长度
let s=new Set()
s.add(12).add(89)
s.size()
map
添加修改:
let m=new Map()
m.set('a',1).set('b',2)
根据key值查找
let m=new Map()
m.set('a',1).set('b',2)
m.has('a')
let m=new Map()
m.set('a',1).set('b',2)
m.delete('a')
方法:删除全部。
let m=new Map()
m.set('a',1).set('b',2)
s.clear()
let m=new Map()
m.set('a',1).set('b',2)
keys=>获取全部keys值
values=>获取全部value值
m.entries()=>获取健值对
属性:获取已经存元素的长度
let m=new Map()
m.set('a',1).set('b',2)
m.size()
Object.assign
对象的拷贝
优缺点:
优势实现对象的浅拷贝
缺点会出现数据丢失,不能直接实现深拷贝(用递归能够实现)
浅拷贝对不是引用类型的值作数据替换;引用类型则直接替换地址
若是目标对象是undefined或者null会引起错误
原对象是undefined或者null则会返回object
let target={}
Object.assign(target,{a:1.b:2})
y修饰符(粘连)
连续匹配,用法以下:
let str = 'aaa_aa_a' let r1 = /a+/g let r2 = /a+/y console.log(r1.exec(str)) console.log(r2.exec(str)) console.log(r1.exec(str)) console.log(r2.exec(str))
u修饰符
使用方法:我是前端的${'小学生 '}
变量结构赋值:重点是在赋值,赋值的元素是要拷贝出来赋值给变量,赋值元素自己将不会收到改变
Array Destructuring
若是想忽略数组中的某一项,可使用逗号来处理
let [a,,b]=['miya','youzi','hanmeimei','xioaming']
let [a,b,c]='abc'
let [x,y,z]=new Set([1,2,4])
let user={}
[user.name,user.surname]='Ilya Kantor'.split(' ')
user //{name: "Ilya", surname: "Kantor"}
四、循环体
let obj = {
name: 'hanmeimei', addr: 'beijing' } for (let [k, v] of Object.entries(obj)) { console.log(k, v) }
let [x,y,...rest]=[1,3,5,6,8,9]
let [u,i] =[]
默认值为 undefined
object Destructuring
在这个结构赋值的过程当中,左侧的“模板”结构要与右侧的 Object 一致,可是属性的顺序无需一致。
let {name,addr}={name:'liming',addr:'beijing'}
let options={title:'Menu'}
let {width=100,height=200,title}=options
let obj1={name:'hanmeimei'}
let obj2={addr:'beijing'}
let obj3={...obj1,...obj2}
js中有不少异步操做,异步操做不是此刻完成,而是以后完成后,
描述按顺序加载不一样的脚本,采用了回调以后再回调的连锁过程,这样代码看起来就会臃肿不少
嵌套越深,代码层次就会变深,维护难度也就加增长,因此出现了promise
Promise的工做原理?
首先new Promise的时候,咱们须要关心2个内容。
status:会有一个padding状态被挂起
result:返回值此时是underfind
经过resolve和reject方法去改变状态,此时需注意。状态不可逆,一旦确认,没法改变
经过then方法去传递执行,执行then方法以后会返回一个promise对象,这样就能够完成链式操做
静态方法
使用.catch能够捕获链式操做的错误
是promise对象上的方法,不是promise静态的方法
避免每次在then上部署错误处理
不要使用throw的方式去触发,使用reject的方法去触发promise状态的改变,去捕获错误
并行操做
Promise.race 生成并返回一个新的 Promise 对象。
参数 promise 数组中的任何一个 Promise 对象若是变为 resolve 或者 reject 的话, 该函数就会返回,并使用这个 Promise 对象的值进行 resolve 或者 reject。
是promise2个静态的方法,必须使用promise的类调用执行
resove触发成功操做
reject触发失败的操做
对象上的方法
使用。catch能够捕获链式操做的错误
是promise对象上的方法,不是promise静态的方法
避免每次在then上部署错误处理
不要使用throw的方式去触发,使用reject的方法去触发promise状态的改变,去捕获错误
then方法
- 怎么去用? then是promise对象原型上的方法,只要是promis对象就能够调用此方法。 语法fn().then(onFulfilled,onReject) onFulfilled,onReject分别对应成功与失败2个方法 若是没传函数,默认会被忽略,返回一个空的promise对象 若是后面不是函数,是表达式也会被执行,返回结果, 调用.then会返回一个promise实例 - 工做原理是什么? 首先调用,then()它会返回一个promise对象。因此才能够产生链式调用 当then的参数不为函数时。返回使用return中断后续then方法
反射机制。函数执行先调用。再去查找那个方法使用。
defineProperty
静态方法 Reflect.defineProperty() 基本等同于 Object.defineProperty() 方法,惟一不一样是返回 Boolean 值。
deleteProperty
静态方法 Reflect.deleteProperty() 容许用于删除属性。它很像 delete operator ,但它是一个函数。
apply
经过指定的参数列表发起对目标(target)函数的调用
能够动态化去控制方法,
apply
原来:先肯定调用对象,后跟apply方法Math.floor.apply(null,[12.433])
如今:先绑定apply。在进行执行方法。Reflect.apply(Math.floor,null,[12.433])
使用场景
价格判断,好比超多100使用向下取整,没超过使用向上取整
old:let price = 18.9090
price = price >= 100 ? Math.floor.apply(null, [price]) : Math.ceil.apply(null, [price])
new: price = Reflect.apply(price >= 100 ? Math.floor : Math.ceil, null, [price])
construct
Reflect.construct() 方法的行为有点像 new 操做符 构造函数 , 至关于运行 new target(...args).
newTarget新建立对象的原型对象, 参考 new.target 操做符,默认值为target。
Reflect.construct容许你使用可变的参数来调用构造函数 ,这和使用new操做符搭配对象展开符调用同样。
Reflect.construct(target, argumentsList[, newTarget])
被运行的目标构造函数
类数组,目标构造函数调用时的参数。
新建立对象的原型对象, 参考 new.target 操做符,默认值为target。
虽然两种方式结果相同,但在建立对象过程当中仍一点不一样
当使用Object.create()和Function.prototype.apply()时,若是不使用new操做符调用构造函数,构造函数内部的new.target值会指向undefined。
当调用Reflect.construct()来建立对象,new.target值会自动指定到targe(或者newTarget,前提是newTarget指定了)。
get
Reflect.get()方法与从 对象 (target[propertyKey]) 中读取属性相似,但它是经过一个函数执行来操做的。
getOwnPropertyDescriptor
Reflect.getOwnPropertyDescriptor() 与 Object.getOwnPropertyDescriptor() 方法类似。若是在对象中存在,则返回给定的属性的属性描述符。不然返回 undefined。
描述符分为:数据描述符和存取描述符
value:‘数据’
writable:是否可被重写,默认false
enumerable:是否能够被遍历,默认false
configurable:是否能够被删除,默认false
getPrototypeOf
getPrototypeOf返回指定对象的原型
has
静态方法 Reflect.has() 做用与 in 操做符 相同。
Reflect.has({x: 0}, "y"); // false
Reflect.has({x: 0}, "x"); // true
isExtensible
静态方法 Reflect.isExtensible() 判断一个对象是否可扩展 (便是否可以添加新的属性)。与它 Object.isExtensible() 方法类似,但有一些不一样,
传值为一个对象,返回当前对象是否能够添加扩展属性
传入非对象会触发错误
也是判断当前传入对象是否能够扩展
传入非对象时,非对象的第一个参数会被强制转换为一个对象。返回布尔值。不会报错
ownKeys
Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
preventExtensions
Reflect.preventExtensions() 方法阻止新属性添加到对象 例如:防止未来对对象的扩展被添加到对象中)。该方法与 Object.preventExtensions()类似,但有一些不一样点。
返回值为布尔值
当传入的值不为对象的时候,会引起错误
Object.preventExtensions() 方法, 非对象的第一个参数将被强制转换为对象。
set
Reflect.set() 工做方式就像在一个对象上设置一个属性。
返回值为一个布尔值
setPrototypeOf
指定对象的原型
它能够自定义一些行为,好比查找,循环、赋值。函数执行
基础用法:new proxy(target,handler)
target要被代理的对象,能够是对象,函数,或者另外一个代理
handler一个对象。被代理的过程
处理key。value值
过滤不存在的属性
表单验证
阅后即焚
proxy中有能够建立临时代理,能够取消,一旦调用revoke。prox将失效,也就是是临时代理
用法
let obj={name:'柚子'}
let o=Proxy.revocable(obj,{})
o.revoke()
用法
let obj = {
name: 'miya', age: 190 } window.addEventListener('error', e => { console.log(e) }, true) let validator = { set(target, key, value) { if (!Reflect.has(target, key)) return '' if (key === 'age') { if (typeof value !== 'number' || Number.isNaN(value)) { throw new TypeError('Age mast be a number') } if (value <= 0) { throw new TypeError('Age must be a positive number') } } return target[key] = value } } let d = new Proxy(obj, validator) d.age = '90' console.log(d.age)
可控制迭代器的函数,能够暂停,也能够选择任什么时候候恢复
比普通函数多了一个*
函数内部使用yield来控制函数执行的暂停
Generator不可使用尖头函数,会产生错误
Generator函数能够嵌套,在yield后添加*
恢复执行函数适应next方法,此函数返回一个对象,分别是当前程序执行的状态和数据,也可传参数,参数将做为yield返回值
抽奖(批量产生)
异步数据的加载
常常玩一些小游戏,好比数数字,遇到 3 的倍数就要跳过,从 1 一直往下数
斐波那契数列
方法
Generator 对象经过next方法来获取每次遍历的结果。这个对象返回一个对象,对象中包含2个属性:
value:当前程序运行的结果
done:遍历是否结束
next方法能够接受参数。这个参数是能够传入到Generator函数中,这个参数就是做为yield的返回值
可使 Generator 遍历终止,相似for break
也可传参数,做为yield的返回值
也是能够中断函数执行
能够经过 throw 方法在 Generator 外部控制内部执行的“终断”。
若是想退出遍历 catch 以后能够配合return false, 能够起到break 的功效
yield表达式用于暂停和恢复一个生成器函数
yield表达式返回是一个underfind,可是遍历器对象的next方法能够传参数改变这个默认值。
yield后可添加*,表示后面继续是个可遍历,可迭代对象,也可嵌套Generator对象
function* fn(x=0,y=1){ while(1){yield x+y; [y,x]=[x,x+y]}}
let f=fn()
f.next()
{value: 1, done: false}
f.next()
{value: 1, done: false}
f.next()
{value: 2, done: false}
f.next()
{value: 3, done: false}
f.next()
{value: 5, done: false}
f.next()
{value: 8, done: false}
for of是为可迭代对象建立一个迭代循环。
可迭代协议容许js去自定义定制他的迭代行为,例如在for of中那些元素能够被循环等。一些内置的对象有默认迭代行为,好比array,map,另外一类则不具有(object)
自定义遍历器必须知足2个条件。
可迭代协议
迭代器协议
什么是迭代器协议?
首先是一个对象
返回一个无参函数next()
函数返回一个对象,对象包含done和value属性。
down表明当前遍历程序是否结束
value表明当前遍历数据
4.next(返回若是不是对象)会报错
为了变成可迭代对象, 一个对象必须实现 @@iterator 方法, 意思是这个对象(或者它原型链 prototype chain 上的某个对象)必须有一个名字是 Symbol.iterator 的属性
若是让一个对象是可遍历的,就要遵照可迭代协议,该协议要求对象要部署一个以 Symbol.iterator 为 key 的键值对,而 value 就是一个无参函数,这个函数返回的对象要遵照迭代器协议。
Generator是自然的具有迭代器协议。
使用Generator 配合可迭代协议就再也不须要显示的写迭代协议了(next方法和包含 done、value 属性的返回对象)。
用法
需求咱们须要遍历全部的做者名字
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' ] } }
allAuthors[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() } } } for (let item of obj) { console.log(item) }
导出
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
or:
const name='miya'
let addr=''beijing'
let list=[1,2,4]
export {name,addr,list}
export function say (content){
console.log(content);
}
export let run=(content)=>console.log(content)
or:
function say (content){
console.log(content);
}
let run=(content)=>console.log(content
export {say,run}
let data={code:0,msg:'请求成功',data:{name:'miya'}}
export {data}
export class Test{
constructor(){
this.id = 2
}}
or :
class Test{
constructor(){
this.id = 2
}}
export {Test}
导入
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
导入:
import {name,addr,list} from 'a.js'
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
导入:
import {name as cname,addr,list} from 'a.js'
export const name = 'miya'
export let addr = 'beijing'
export let list = [1, 2, 4]
导入:
import * as md from 'index.js'
判断一个元素是否存在数组中,返回值为布尔值用法以下:
let arr=[12,40,289]
arr.includes(40) //true
arr.find(key=>key===40) //40
Math.pow() 函数返回基数(base)的指数(exponent)次幂,即 baseexponent
用法以下:
Math.pow(2,5)//32
2**5//32
是promise的语法糖
使用 Promise 以后可让咱们书写异步操做更加简单,而 async 是让咱们写起 Promise 像同步操做
async 函数显式返回的不是 Promise 的话,会自动包装成 Promise 对象
await 不能够脱离 async 单独使用
获取对象的描述符
用于遍历集合,建立一个循环来迭代可迭代的对象
处理异步操做
for awite of
用于操做异步集合的操做
// function geo(time) { // return new Promise((resolv, reject) => { // setTimeout(() => { // resolv(time) // }, time) // }) // } // async function test() { // let arr = [geo(2000), geo(100), geo(3000)] // for await (const item of arr) { // console.log(new Date().getTime(), item) // } // } // test()
Promise.prototype.finally() 方法返回一个Promise,在promise执行结束时,不管结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。这为指定执行完promise后,不管结果是fulfilled仍是rejected都须要执行的代码提供了一种方式,避免一样的语句须要在then()和catch()中各写一次的状况。
数组中咱们经常使用...来合并数组
对象中合并也可使用object的rest进行2个对象的合并。他的原理是浅拷贝。不是引用。用法以下:
let obj={a:1,b:2,c:3}
let obj2={...obj,f:9090}
console.log(obj2)//{a: 1, b: 2, c: 3, f: 9090}
当对象 key-value 不肯定的时候,把必选的 key 赋值给变量,用一个变量收敛其余可选的 key 数据,用法以下:
let obj={a: 1, b: 2, c: 3, f: 9090}
let {a,b,...rest}=obj
console.log(a,b,rest)
1 2 {c: 3, f: 9090}
do Al l
正则表达式中,点(.)是一个特殊字符,表明任意的单个字符,可是有两个例外。
一、一个是四个字节的 UTF-16 字符,这个能够用u修饰符解决;
二、另外一个是行终止符(line terminator character)。/n 和/r
用法以下:
/foo.boo/s.test('foonboo')
命名捕获
后行断言
先行断言
对于一些超出范围的 Unicode,为其输出转义序列,使其成为有效 Unicode
https://developer.mozilla.org...
指定嵌套数组结构应展平的深度级别。默认为1。
let arr=[1,[2,6,[9]]]
arr.flat(1) // [1, 2, 6, Array(1)]
arr.flat(2) //[1, 2, 6, 9]
arr.flat(Infinity) //[1, 2, 6, 9]
https://developer.mozilla.org...
首先使用映射函数映射每一个元素,而后将结果展平为新数组。它与深度为1 map()的a 相同flat(),但flatMap()一般很是有用,由于将二者合并为一种方法效率更高。
let arr= [1, 0, 6, 9]
arr.flatMap(item=>[item*2]) //[2, 0, 12, 18]
https://developer.mozilla.org...
去开始空格
let str=' u '
str.trimStart() // 'u '
去除结束空格
let str=' u '
str.trimEnd() // ' u'
matchAll()
针对字符串返回正则表达式的全部匹配项。
let str = '"foo" "boo" sd "ooo"'
let collectGroup1 = (str, regExp) => {
let matches = [] for (let item of str.matchAll(regExp)) { matches.push(item[1]) } return matches } console.log(collectGroup1(str, /"([^"]*)"/g))
把键值对列表转换为一个对象,这个方法是和 Object.entries() 相对的。
let search = window.location.search.substr(1).split('&');
Object.fromEntries(search.map(k => k.split('=')))
经过 description 方法获取 Symbol 的描述
let symbol=Symbol('My name is miya')
symbol.description// My name is miya
toString() 方法返回一个表示当前函数源代码的字符串
let say=()=>console.log('hhhh')
say.toString() //()=>console.log('hhhh')
try {
console.log('Foobar')
} catch {
console.error('Bar')
}
XMind: ZEN - Trial Version