wmiya / study Goto Github PK
View Code? Open in Web Editor NEWjavascript
Home Page: https://juejin.im/user/593e60aaac502e006b4d0793/posts
javascript
Home Page: https://juejin.im/user/593e60aaac502e006b4d0793/posts
JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object)。
基础类型
null,undefined,string,number,Boolean,symbol
NaN属于number类型
NaN不等于自身
对象
对象(Object)是引用类型,在使用过程中会遇到浅拷贝和深拷贝的问题。
对于基础类型返回正确显示,除了null返回object
原因:早期的js使用32位系统,为了性能开绿使用低位储存变量的类型信息,其中000开头代表对象,null刚好全是000,所以错误的认为是对象
转布尔
除了null,underfind,0,-0,“”,false,NaN都都转为false。其他都是true,包括对象
判断object.proytype.toString.call()
[object string]
对象转基础类型
首先会调用valueof
其次会调用tostring的方法
最后这两者都可被自定义
四则运算
“a”+ +"b"=aNaN
加法运算
一方位字符串,另一方转为字符串
会触发类型转换
其他运算
一方位数字,另一方也转为数字
对象
每个对象都有一个__proto__的属性,他指向创建该对象的构造函数的原型,
对象可以通过 proto 来寻找不属于该对象的属性,proto 将对象连接起 来组成了原型链。
函数
每个函数都有个prototype,
除了Function.prototype.bind
原理
创建一个对象
将这对象的__proto__指向其构造函数的prototype
绑定this
返回这个对象
实现
function news() {
let obj = new Object()
let fn = [...arguments].shift()
obj.__proto__ = fn.prototype
let result = fn.apply(obj, arguments)
return typeof result === 'object' ? result : obj
}
接受2个参数(this,多个参数)
实现原理
接受2个参数(this,多个参数)
实现
Function.prototype.myCall = function (content) {
if (typeof this !== 'function') {
throw new Error('error')
}
context = context || window
content.fn = this
let agr = [...arguments].slice(1)
let result = content.fn(...agr)
delete content.fn
return result
}
也是改变this指向,接受2个参数
第一个是this。第二个是数组
实现
Function.prototype.myApplay = function (content, arr) {
if (typeof this !== 'function') {
throw new Error('error')
}
context = context || window
content.fn = this
let result;
result = arr ? content.fn(arr) : content.fn()
delete content.fn
return result
}
返回一个函数
这个函数接受参数
返回的这个函数的this是第一个传进来参数
实现
Function.prototype.myBind = function (content) {
if (typeof this !== 'function') {
throw new Error('error')
}
let self = this
let arg = [...arguments].slice(1)
return function F() {
if (this instanceof F) {
return new self(...arg, ...arguments)
}
return self.apply(content, arg.concat(...arguments))
}
}
原理是根据对象的原型琏中是不是能找到类型的prototype
实现
function instanceofs(left, right) {
let prototype = right.prototype
left = left.__proto__
while (1) {
if (left == null || left == undefined) {
return false
}
if (left == prototype) {
return true
}
left = left.__proto__
}
}
全局this
指向window
函数中的this
对象调用,则指向这个对象
独立调用,指向window
使用call,apply显示指定this
动态改变this
构造函数与原型方法上的this
指向实例化之后的对象
箭头函数中的this
调用箭头函数外层第一个普通函数的this
全局执行上下文(global)
函数执行上下文(fn,函数调用栈)
evel执行上下文
创建执行上下文
创建变量对象
变量对象
创建作用域链
确认this指向
执行执行上下文
变量赋值
函数引用
执行相关代码
在函数执行上下文A
在执行上下文A中的函数B
调用了A中的变量。闭包产生
即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)
在代码中引用了自由变量
为什么执行上下文中都已经销毁,还能调用其内部的变量?
当被返回的函数执行时,上下文会维护一个作用域链,将父函数保存在内存中,子函数就可以通过作用域链找到他,因为这个,创建了闭包
webpack
babel
eslint
webpack是一个工具,对语法做转换,需要各种loader.loader的作用就是提供一个机制,能保证所有类型的资源可以被对应的loader进行处理
npmjs.com
npm init (创建package.json)
npm install -g webpack-cli@3
npm install -g webpack@4
touch webpack.config.js
npm install http-server
webpack
output
output:{
path:path.resovle('__dirname',dist),
filename:'index.js'
}
开发摸索(development)
尽量简化
对代码不进行压缩
生产模式(production)
代码压缩
保证线上代码尽可能简化
更简洁,更干净
XMind: ZEN - Trial Version
创建
直接new
let app = new Vue({
template: '<div>{{text}}</div>',
data: {
text: 'sdsdsd'
}
})
通过render挂载
new Vue({
render: (h) => h(App)
}).$mount(root)
属性
$data
Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
$props
当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。
$el
挂载dom的根元素
$root
当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
$options
用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处:
$children
当前实例的直接子组件
$parent
父实例,如果当前实例有的话。
$slots
用来访问被插槽分发的内容
$scopedSlots
用来访问作用域插槽。
$refs
一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例。
dom节点的代理
$isserver
当前 Vue 实例是否运行于服务器。
$listeners
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
实例方法 / 数据
vm.$watch
观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。
vm.$set
用于修改数组和对象的内容
vm.$delete
删除某个属性或者元素,用于数组和对象
实例方法 / 事件
vm.$on
监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
vm.$once
监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
vm.$off
移除自定义事件监听器。果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
vm.$emit
触发当前实例上的事件。附加参数都会传给监听器回调。
实例方法 / 生命周期
vm.$mount
如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。
vm.$forceUpdate
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
vm.$nextTick
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
监听dom更新
vm.$destroy
完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器
beforeCreate
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created
实例创建之后立即被调用,观测数据和事件都已完成,
挂载还为未开始,el不可用,也得不到
beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
在服务端期间不被调用
mounted
实例被挂载后调用,el被新创建el替换
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
activated
deactivated
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
该钩子在服务器端渲染期间不被调用。
destroyed
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
errorCaptured
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
v-text
更新元素的 textContent。如果要更新部分的 textContent ,需要使用 {{ Mustache }} 插值。
=={{}}
v-html
更新元素的 innerHTML
内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译 。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。
v-show
根据表达式之真假值,切换元素的 display CSS 属性。
v-if
根据表达式的值的 truthiness 来有条件地渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 ,将提出它的内容作为条件块。
当条件变化时该指令触发过渡效果。
当和 v-if 一起使用时,v-for 的优先级比 v-if 更高
v-else
前一兄弟元素必须有 v-if 或 v-else-if。
v-for
循环必须使用特定语法 alias in expression ,为当前遍历的元素提供别名:
v-on
绑定事件监听器
v-bind
动态地绑定一个或多个特性,或一个组件 prop 到表达式。
v-model
在表单控件或者组件上创建双向绑定。细节请看下面的教程链接。
v-slot
提供具名插槽或需要接收 prop 的插槽。
v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
v-cloak
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
v-once
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
watch
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。
immediate
编写之后立即被调用
deep
如果该内容是数组或者对象的,他的子元素也将被监测
computed
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的
XMind: ZEN - Trial Version
知识图谱:https://juejin.im/post/5e09a7866fb9a016526ed0c6
let
用于块级作用域
不存在变量提升
不可重复声明
未声明不可使用
不可使用window去调用
const
不可重复定义
不可对重复赋值
不存在变量提升
不允许先赋值后声明
什么是作用域?
规定程序源代码中定义的变量执行区域
规定了如何查找等一些列规则
作用域有哪些?
全局作用域(global,window)
局部作用域(函数作用域)
块级作用域(let。const定义的代码块区域)
动态作用域(this)
全局变量?
函数以外定义的变量
函数内部不通过var定义的变量
不通过var等定义的变量属于window下面的属性可以被删除。var则不可以,严格意义上来说直接定义的变量不属于全局变量
for of
对于可迭代的对象创建一个迭代循环
Array.from
转成数组,用法:
Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike类数组或可迭代对象
mapFn如果指定了该参数,都会执行
可选参数,执行回调函数 mapFn 时 this 对象
Array.fill
填充数组
arr.fill(value[, start[, end]])
value填充元素
start起始索引
end结束索引
let arr=[1,4,6,7]
arr.fill(99,1,9)
Array.of
创建数组
let arr=Array.of(1,43,6,8)
Array.find
find() 方法返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。
Array.findIndex
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相比读写有何优点?
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
值可以是任意值
add()
方法:添加
let s=new Set()
s.add(12).add(89)
delete()
方法:删除某一项。
let s=new Set()
s.add(12).add(89)
s.delete(10)
clear
方法:删除所有。
let s=new Set()
s.add(12).add(89)
s.clear()
has
方法:判断元素是否存在
let s=new Set()
s.add(12).add(89)
s.has(12)
keys()、values()、entries()
keys=>获取所有keys值
values=>获取所有value值
s.entries()=>获取健值对
size
属性:获取已经存元素的长度
let s=new Set()
s.add(12).add(89)
s.size()
map
set()
添加修改:
let m=new Map()
m.set('a',1).set('b',2)
has()
根据key值查找
let m=new Map()
m.set('a',1).set('b',2)
m.has('a')
delete()
let m=new Map()
m.set('a',1).set('b',2)
m.delete('a')
clear
方法:删除所有。
let m=new Map()
m.set('a',1).set('b',2)
s.clear()
keys()、values()、entries()
let m=new Map()
m.set('a',1).set('b',2)
keys=>获取所有keys值
values=>获取所有value值
m.entries()=>获取健值对
size
属性:获取已经存元素的长度
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
1、可以跳过赋值元素
如果想忽略数组中的某一项,可以使用逗号来处理
let [a,,b]=['miya','youzi','hanmeimei','xioaming']
2、赋值元素可以是任意可遍历的对象
let [a,b,c]='abc'
let [x,y,z]=new Set([1,2,4])
3、左边的变量
let user={}
[user.name,user.surname]='Ilya Kantor'.split(' ')
user //{name: "Ilya", surname: "Kantor"}
4、循环体
let obj = {
name: 'hanmeimei',
addr: 'beijing'
}
for (let [k, v] of Object.entries(obj)) {
console.log(k, v)
}
5、rest函数
let [x,y,...rest]=[1,3,5,6,8,9]
6、默认值
let [u,i] =[]
默认值为 undefined
object Destructuring
1、基础用法
在这个结构赋值的过程中,左侧的“模板”结构要与右侧的 Object 一致,但是属性的顺序无需一致。
let {name,addr}={name:'liming',addr:'beijing'}
2、默认值
let options={title:'Menu'}
let {width=100,height=200,title}=options
3、rest运算符
let obj1={name:'hanmeimei'}
let obj2={addr:'beijing'}
let obj3={...obj1,...obj2}
Promise出现的背景?
js中有很多异步操作,异步操作不是此刻完成,而是之后完成后,
描述按顺序加载不同的脚本,采用了回调之后再回调的连锁过程,这样代码看起来就会臃肿很多
嵌套越深,代码层次就会变深,维护难度也就加增加,所以出现了promise
Promise的工作原理?
promise未调用.then方法前执行了什么?
首先new Promise的时候,我们需要关心2个内容。
status:会有一个padding状态被挂起
result:返回值此时是underfind
promise的状态怎么去改变?
通过resolve和reject方法去改变状态,此时需注意。状态不可逆,一旦确认,无法改变
promise结果状态改变的时候怎么传递数据?
通过then方法去传递执行,执行then方法之后会返回一个promise对象,这样就可以完成链式操作
静态方法
all
使用.catch可以捕获链式操作的错误
是promise对象上的方法,不是promise静态的方法
避免每次在then上部署错误处理
不要使用throw的方式去触发,使用reject的方法去触发promise状态的改变,去捕获错误
并行操作
Race
Promise.race 生成并返回一个新的 Promise 对象。
参数 promise 数组中的任何一个 Promise 对象如果变为 resolve 或者 reject 的话, 该函数就会返回,并使用这个 Promise 对象的值进行 resolve 或者 reject。
resolve, reject
是promise2个静态的方法,必须使用promise的类调用执行
resove触发成功操作
reject触发失败的操作
对象上的方法
catch错误处理
使用。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])
target
被运行的目标构造函数
argumentsList
类数组,目标构造函数调用时的参数。
newTarget
新创建对象的原型对象, 参考 new.target 操作符,默认值为target。
与Object.create()的区别?
虽然两种方式结果相同,但在创建对象过程中仍一点不同
当使用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。
Reflect.getOwnPropertyDescriptor(target, propertyKey)
描述符分为:数据描述符和存取描述符
value:‘数据’
writable:是否可被重写,默认false
enumerable:是否可以被遍历,默认false
configurable:是否可以被删除,默认false
getPrototypeOf
getPrototypeOf返回指定对象的原型
has
静态方法 Reflect.has() 作用与 in 操作符 相同。
Reflect.has(target, propertyKey)
Reflect.has({x: 0}, "y"); // false
Reflect.has({x: 0}, "x"); // true
isExtensible
静态方法 Reflect.isExtensible() 判断一个对象是否可扩展 (即是否能够添加新的属性)。与它 Object.isExtensible() 方法相似,但有一些不同,
Reflect.isExtensible()
传值为一个对象,返回当前对象是否可以添加扩展属性
传入非对象会触发错误
object.isExtensible()
也是判断当前传入对象是否可以扩展
传入非对象时,非对象的第一个参数会被强制转换为一个对象。返回布尔值。不会报错
ownKeys
Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
preventExtensions
Reflect.preventExtensions() 方法阻止新属性添加到对象 例如:防止将来对对象的扩展被添加到对象中)。该方法与 Object.preventExtensions()相似,但有一些不同点。
Reflect.preventExtensions(obj)
返回值为布尔值
当传入的值不为对象的时候,会引发错误
object.preventExtensions
Object.preventExtensions() 方法, 非对象的第一个参数将被强制转换为对象。
set
Reflect.set() 工作方式就像在一个对象上设置一个属性。
Reflect.set(target, propertyKey,value)
返回值为一个布尔值
setPrototypeOf
指定对象的原型
什么是proxy?
它可以自定义一些行为,比如查找,循环、赋值。函数执行
基础用法: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)
什么是Generator
可控制迭代器的函数,可以暂停,也可以选择任何时候恢复
Generator的基础用法
比普通函数多了一个*
函数内部使用yield来控制函数执行的暂停
Generator不可以使用尖头函数,会产生错误
Generator函数可以嵌套,在yield后添加*
恢复执行函数适应next方法,此函数返回一个对象,分别是当前程序执行的状态和数据,也可传参数,参数将作为yield返回值
Generator的使用场景
抽奖(批量产生)
异步数据的加载
经常玩一些小游戏,比如数数字,遇到 3 的倍数就要跳过,从 1 一直往下数
斐波那契数列
方法
next
Generator 对象通过next方法来获取每次遍历的结果。这个对象返回一个对象,对象中包含2个属性:
value:当前程序运行的结果
done:遍历是否结束
next方法可以接受参数。这个参数是可以传入到Generator函数中,这个参数就是作为yield的返回值
return
可以使 Generator 遍历终止,类似for break
也可传参数,作为yield的返回值
thorw
也是可以中断函数执行
可以通过 throw 方法在 Generator 外部控制内部执行的“终断”。
如果想退出遍历 catch 之后可以配合return false, 可以起到break 的功效
yield表达式
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 和 Iterator 的关联关系理解了吗?
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}
导出class
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 单独使用
object.keys()
object.entries()
object.values()
object.getOwnPropertyDescriptors()
获取对象的描述符
for of
用于遍历集合,创建一个循环来迭代可迭代的对象
awite
处理异步操作
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
数组中我们常用...来合并数组
对象中合并也可以使用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}
object spreat
当对象 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
正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。
1、一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;
2、另一个是行终止符(line terminator character)。/n 和/r
用法如下:
/foo.boo/s.test('foo\nboo')
命名捕获
后行断言
先行断言
JSON.stringify()
对于一些超出范围的 Unicode,为其输出转义序列,使其成为有效 Unicode
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
flat()
指定嵌套数组结构应展平的深度级别。默认为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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
flatMap()
首先使用映射函数映射每个元素,然后将结果展平为新数组。它与深度为1 map()的a 相同flat(),但flatMap()通常非常有用,因为将两者合并为一种方法效率更高。
let arr= [1, 0, 6, 9]
arr.flatMap(item=>[item*2]) //[2, 0, 12, 18]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
trimStart()
去开始空格
let str=' u '
str.trimStart() // 'u '
trimEnd()
去除结束空格
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. fromEntries()
把键值对列表转换为一个对象,这个方法是和 Object.entries() 相对的。
let search = window.location.search.substr(1).split('&');
Object.fromEntries(search.map(k => k.split('=')))
Symbol. description
通过 description 方法获取 Symbol 的描述
let symbol=Symbol('My name is miya')
symbol.description// My name is miya
function.toString()
toString() 方法返回一个表示当前函数源代码的字符串
let say=()=>console.log('hhhh')
say.toString() //()=>console.log('hhhh')
可以省略catch后边error参数
try {
console.log('Foobar')
} catch {
console.error('Bar')
}
XMind: ZEN - Trial Version
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.