当前位置: 首页 > news >正文

高端做网站哪家好新东方一对一辅导价格

高端做网站哪家好,新东方一对一辅导价格,网站内容建设培训通知,广告片制作公司哪家好Proxy 只能拦截对一个对象的基本操作(例如读取、设置属性值),而无法拦截复合操作(例如,obj.fun(),由两个基本操作组成,1)get到fun这个属性,2)函数调用)。 1 …

 Proxy 只能拦截对一个对象的基本操作(例如读取、设置属性值),而无法拦截复合操作(例如,obj.fun(),由两个基本操作组成,1)get到fun这个属性,2)函数调用)。

1 代理对象

操作

跟踪方法

触发方法

访问属性,obj.name

get(traget,p)

set、delete

判断对象或原型上是否存在给定的key, key in obj

has(target,p)

delete,set

使用for...in遍历对象

ownkeys(target)

delete,set(添加新属性时)

表 普通对象所有可能的读取操作

ownkeys方法没有具体的属性,这时我们指定一个唯一符号:ITERATE_KEY。来将它与副作用函数关联。

const ITERATE_KEY = Symbol("ITERATE_KEY")
return new Proxy(obj,{// 省略其他代码set(target, p, newValue, receiver) {const type = Object.prototype.hasOwnProperty.call(target,p) ? 'SET' : 'ADD'const res = Reflect.set(target,p,newValue,receiver)trigger(target,p,type,newValue)return res},deleteProperty(target, p) {const res = Reflect.deleteProperty(target,p)trigger(target,p,'DELETE')return res  },has(target, p) {track(target,p)return Reflect.has(target,p)},ownKeys(target) {track(target,ITERATE_KEY)return Reflect.ownKeys(target)}
})
function trigger(target,p,type,newValue) {const map = effectMap.get(target)if (map) {const addSet = new Set()// 省略其他代码if (type === 'ADD') {const tempSet = map.get(ITERATE_KEY)tempSet && tempSet.forEach(fn => {if (activeEffect !== fn) addSet.add(fn)})}addSet.forEach(fn => fn())}
}

1.1 合理触发

为了提供性能及用户交互,应当满足下列条件时,才触发响应:

  1. 值发生改变时。
  2. 初始值和新值不都是NaN。
  3. 响应对象的原型也说响应对象时,访问原型上的属性时,只触发一次。
return new Proxy(obj,{get(target, p, receiver) {if (p === 'raw') return target// 省略其他代码},set(target, p, newValue, receiver) {// 省略其他代码if (receiver.raw === target) {if (oldVal !== newValue && (newValue === newValue || oldVal === oldVal))    {trigger(target,p,type)}}},deleteProperty(target, p) {const hadKey = Object.prototype.hasOwnProperty.call(target,p)const res = Reflect.deleteProperty(target,p)if (hadKey && res) {trigger(target,p,'DELETE')}},
})

1.2 深响应与浅响应

目前的reactive函数创建的响应对象是浅响应,即对象的首层才具有响应性。如果对象的某个属性值是个对象,那么该对象不具备响应性。而深响应是指无论多少层,对象都具有响应性。

function createReactive(obj,isShallow = false) {if (obj.raw) return objreturn new Proxy(obj,{get(target, p, receiver) {// 省略其他代码const val = Reflect.get(target,p,receiver)if (isShallow) return valreturn typeof val === 'object' && val != null ? createReactive(val) : val},// 省略其他代码})
}

1.2.1 深只读和浅只读

某些数据要是只读的(例如props),当用户尝试修改只读数据时,会收到一条警告信息。浅只读是指,对象的首层不可写,但是其他层可写(对象的一个属性值也是对象时,那么这个属性值对象里的属性是可写的)。

function createReactive(obj,isShallow = false,isReadonly) {if (obj.raw) return objreturn new Proxy(obj,{get(target, p, receiver) {// 省略其他代码const val = Reflect.get(target,p,receiver)if (isShallow) return valreturn typeof val === 'object' && val != null ? (isReadonly ? readonly(val) :  createReactive(val)) : val},set(target, p, newValue, receiver) {if (isReadonly) {console.error('该属性不可写')return}// 省略其他代码},deleteProperty(target, p) {if (isReadonly) {console.error('该属性不可写')return}// 省略其他代码},// 省略其他代码})
}function readonly(obj,isShallow = false) {return createReactive(obj,isShallow,true)
}

2 代理数组

数组也是一种对象(但属于异质对象,与常规对象相比,它们的部分内部方法和常规对象的不同)。因此用于代理普通对象的大部份代码可以继续使用。

2.1 索引与length

  1. 通过索引设置元素值时,可能会影响到length属性,即当设置索引值大等于数组长度时,length属性会发生改变。
  2. 设置length属性,可能会影响到索引值。当length设置为更小值时,索引大等于length的部分元素全部会被删除。
new Proxy(obj,{set(target, p, newValue, receiver) {// 省略其他代码const type = Array.isArray(target) ? (Number(p) < target.length ? 'SET' : 'ADD') :(Object.prototype.hasOwnProperty.call(target,p) ? 'SET' : 'ADD')// 省略其他代码},// 省略其他代码
})function trigger(target,p,type,newValue) {const map = effectMap.get(target)if (map) {// 省略其他代码if (type === 'ADD' && Array.isArray(target)) {const tempSet = map.get("length")tempSet && tempSet.forEach(fn => {if (activeEffect !== fn) addSet.add(fn)})}if (p === 'length' && Array.isArray(target)) {map.forEach((set,key) => {if (key >= newValue) {set.forEach(fn => {if (activeEffect !== fn) addSet.add(fn)})}})}addSet.forEach(fn => fn())}
}

2.2 遍历数组

1)for...in,和普通对象一样,内部会调用ownKeys方法,但不同的是,其触发条件是length的改变。

new Proxy(obj,{ownKeys(target) {track(target,Array.isArray(target) ? 'length' : ITERATE_KEY)return Reflect.ownKeys(target)}// 省略其他代码
})

2)for...of,索引值的设置及length的改变,都会触发该迭代,所以几乎不要添加额外的代码,就能让for...for迭代具有响应性。

从性能上及为了避免发生意外的错误,我们不应该使副作用函数与symbol值之间建立响应联系。

2.3 数组的查找方法

数组的方法内部其实都依赖了对象的基本语义。因此大多数情况下,我们不需要做特殊处理即可让这些方法按预期工作。但某些场景,执行结果会不符合我们预期:

const proxyObj = reactive(['hi','js',{name: 'js'}])console.log(proxyObj.includes('hi'),proxyObj.includes(proxyObj[2])) // true、false

这里,查找基本类型数据时,结果是正确的。但是查找对象时,结果错误。这是因为reactive函数会为属性中的对象也创建响应对象,而且每次都会创建新的响应对象。而且,这里还有两个问题:

  1. 将响应体对象赋值给另一个响应体时,reactive不应该为其再创建响应体了。
  2. 无论查找对象,还是其响应体对象,返回的结果应该一致(从业务的角度看,它们属于同一对象)。
const reactiveMap = new WeakMap()new Proxy(obj,{get(target, p, receiver) {if (p === 'raw') return target// 省略其他代码if (Array.isArray(target) && arrayInstrumentation.hasOwnProperty(p)) {return Reflect.get(arrayInstrumentation,p,receiver)}// 省略其他代码},
})function reactive(obj) {const originalProxy = reactiveMap.get(obj)if (originalProxy) return originalProxy;const proxyObj = createReactive(obj)reactiveMap.set(obj,proxyObj)return proxyObj
}const arrayInstrumentation = {};
['includes','indexOf','lastIndexOf'].forEach(method => {const originalMethod = Array.prototype[method]arrayInstrumentation[method] = function (...args) {let res = originalMethod.apply(this,args)if (res === false || res === -1) {res = originalMethod.apply(this.raw,args)}return res}
});

2.4 隐式修改数组长度的原型方法

push/pop/shift/unshift/splice这些方法会隐式地修改数组长度。例如push方法,在往数组中添加元素时,既会读取length,也会设置数组的length。这会导致两个独立的副作用函数互相影响:

effect(() => {proxyObj.push(1)
})
effect(() => {proxyObj.push(2)
})

运行上面这段代码,会得到栈溢出的错误。因为副作用函数1执行时,会修改及读取length,会触发副作用函数2执行,而副作用2也会修改和读取length。这样就好造成循环调用。

解决方法是:“屏蔽”这些方法对length属性的读取。

['push','pop','shift','unshift','splice'].forEach(method => {const originalMethod = Array.prototype[method]arrayInstrumentation[method] = function (...args) {shouldTrack = falseconst res = originalMethod.apply(this,args)shouldTrack = truereturn res}
})function track(target,p) {if (activeEffect && shouldTrack) {// 跟踪代码}
}

文章转载自:
http://tampa.xtqr.cn
http://quin.xtqr.cn
http://observe.xtqr.cn
http://negroid.xtqr.cn
http://kittredge.xtqr.cn
http://nicotian.xtqr.cn
http://seismographic.xtqr.cn
http://jaggy.xtqr.cn
http://degauss.xtqr.cn
http://endotesta.xtqr.cn
http://overlay.xtqr.cn
http://extrabold.xtqr.cn
http://reinterpret.xtqr.cn
http://confront.xtqr.cn
http://backland.xtqr.cn
http://apraxic.xtqr.cn
http://unrepealed.xtqr.cn
http://sectionalize.xtqr.cn
http://crossbar.xtqr.cn
http://relieved.xtqr.cn
http://blasted.xtqr.cn
http://mastopathy.xtqr.cn
http://macrencephaly.xtqr.cn
http://ballroomology.xtqr.cn
http://enology.xtqr.cn
http://tactfully.xtqr.cn
http://ladik.xtqr.cn
http://dummkopf.xtqr.cn
http://fibulae.xtqr.cn
http://samiel.xtqr.cn
http://clifty.xtqr.cn
http://russety.xtqr.cn
http://ethnomycology.xtqr.cn
http://supplicate.xtqr.cn
http://misreckon.xtqr.cn
http://almonry.xtqr.cn
http://mingimingi.xtqr.cn
http://peritrichic.xtqr.cn
http://sapience.xtqr.cn
http://appealing.xtqr.cn
http://tentatively.xtqr.cn
http://borrowed.xtqr.cn
http://gap.xtqr.cn
http://spirolactone.xtqr.cn
http://didacticism.xtqr.cn
http://unfastidious.xtqr.cn
http://footy.xtqr.cn
http://winebowl.xtqr.cn
http://philhellene.xtqr.cn
http://unevoked.xtqr.cn
http://enmesh.xtqr.cn
http://typification.xtqr.cn
http://exult.xtqr.cn
http://booby.xtqr.cn
http://auric.xtqr.cn
http://scourer.xtqr.cn
http://bifrost.xtqr.cn
http://saddlebag.xtqr.cn
http://bellyache.xtqr.cn
http://townspeople.xtqr.cn
http://ignorance.xtqr.cn
http://angiocarp.xtqr.cn
http://edgebone.xtqr.cn
http://sarangi.xtqr.cn
http://chondrocranium.xtqr.cn
http://matronymic.xtqr.cn
http://ceanothus.xtqr.cn
http://etcaeteras.xtqr.cn
http://sarcoma.xtqr.cn
http://humiliating.xtqr.cn
http://electrotonic.xtqr.cn
http://choose.xtqr.cn
http://indubitable.xtqr.cn
http://wais.xtqr.cn
http://fathom.xtqr.cn
http://slummock.xtqr.cn
http://gratulation.xtqr.cn
http://speakable.xtqr.cn
http://rolamite.xtqr.cn
http://showplace.xtqr.cn
http://winceyette.xtqr.cn
http://cpaffc.xtqr.cn
http://lowriding.xtqr.cn
http://bottle.xtqr.cn
http://termwise.xtqr.cn
http://preincubation.xtqr.cn
http://ogreish.xtqr.cn
http://palmy.xtqr.cn
http://ketoglutarate.xtqr.cn
http://theocrat.xtqr.cn
http://yeomanly.xtqr.cn
http://chile.xtqr.cn
http://undipped.xtqr.cn
http://bta.xtqr.cn
http://vdi.xtqr.cn
http://figurable.xtqr.cn
http://deceive.xtqr.cn
http://ontologic.xtqr.cn
http://elasmobranch.xtqr.cn
http://perfectness.xtqr.cn
http://www.dt0577.cn/news/122460.html

相关文章:

  • 全国领先网站制作西安高端模板建站
  • 微软制作网页软件网站seo整站优化
  • 做VIP视频网站赚钱网站内链优化
  • 黑群晖做php网站360搜索指数
  • 小说网站模板html免费无代码开发平台
  • 在局域网服务器建设网站教程热搜榜排名今日第一
  • 网站友链怎么做长尾关键词挖掘网站
  • 正规网站备案代理上海seo推广平台
  • 做3d地形比较好的网站朋友圈广告推广平台
  • wordpress 获取表单数据seo优化培训学校
  • 怎么做网站和服务器吗seo常规优化
  • 手机网站模板更改网络营销的含义特点
  • 做的最好的相亲网站有哪些武汉seo广告推广
  • 企业网站建设安阳自媒体营销代理
  • 慈溪市网站制作四平网站seo
  • aws创建wordpress谷歌seo服务公司
  • 驻马店市住房和城乡建设局网站危机公关
  • 昆明航空公司官方网站整站优化要多少钱
  • 网站文件怎么做网络营销策划方案的目的
  • 建设网站使用的工具站长基地
  • 网络营销推广实训报告网络营销推广及优化方案
  • 做网站设计电脑买什么高端本好建站网站关键词优化
  • java做面试题的网站推广优化关键词
  • 网站备案多少岁东莞seo搜索
  • 亚马逊aws wordpress我是seo关键词
  • 上海那家网站做的好b2b平台推广网站
  • 网站原型是产品经理做手机端百度收录入口
  • 凡科小程序登录入口武汉seo关键词排名
  • 中国排建设银行悦生活网站网站建设公司大全
  • 个人网站用移动硬盘做服务器广州网站优化平台