如何在 JavaScript 对象中嵌入私有成员.docx_第1页
如何在 JavaScript 对象中嵌入私有成员.docx_第2页
如何在 JavaScript 对象中嵌入私有成员.docx_第3页
如何在 JavaScript 对象中嵌入私有成员.docx_第4页
如何在 JavaScript 对象中嵌入私有成员.docx_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

最近,我开发一个项目Angular Cloud Data Connector, 帮助Angular开发者使用云数据,特别是Azure移动服务, 使用WEB标准,像索引数据库(indexed DB)。我尝试建立一种方式,使得JavaScript开发者能将私有成员嵌入到一个对象中。我解决这个问题的技术用到了我命名的闭包空间(closure space)。在这篇入门文章中,我要分享的是如何在你的项目中用它,及它对主流浏览器的性能和内存的影响。在深入学习前,咱们先说下,你为什么需要用到私有成员(private members), 还有一种替代方式来模拟私有成员。1. 为何要用私有成员(Private Members)当你用JavaScript 创建一个对象时,可以声明值成员(value members)。 如果你打算控制对它们的读/写访问操作,可以如下声明:varentity=;entity._property=helloworld;Object.defineProperty(entity,property,get:function()returnthis._property;,set:function(value)this._property=value;,enumerable:true,configurable:true);这样实现,你能完全控制读和写操作。问题在于_property 成员仍然可以直接访问和修改。这也就是为何我们需要更加稳定可靠的方式,声明私有成员,它智能通过对象的方法来访问。2. 使用闭包空间(Closure Space)解决方法是使用闭包空间。每当内部函数 (inner fanction) 访问来自外部函数作用域的变量时,浏览器为你分配一段内存空间。有时很取巧,不过就我们的题目来讲,这算是一个完美的解决方案。我们在上个代码版本中添加这个特性:varcreateProperty=function(obj,prop,currentValue)Object.defineProperty(obj,prop,get:function()returncurrentValue;,set:function(value)currentValue=value;,enumerable:true,configurable:true);varentity=;varmyVar=helloworld;createProperty(entity,property,myVar);示例中,createProperty 函数有一个 currentValue 变量,存在 get 和 set 方法。此变量会保存到 get 和 set 函数的闭包空间中。现在,只有这两个函数能看到和更新currentValue 变量! 任务完成!唯一需要警惕 caveat,警告,注意)的是源值 (myVar) 仍可访问。下面给出另一个更健壮的版本(保护 myVar 变量):varcreateProperty=function(obj,prop)varcurrentValue=objprop;Object.defineProperty(obj,prop,get:function()returncurrentValue;,set:function(value)currentValue=value;,enumerable:true,configurable:true);varentity=property:helloworld;createProperty(entity,property);采用该函数, 即便源值都销毁(destructed,注:意思是不能直接赋值)了。到此大功告成了!3.性能考虑Performance Considerations现在咱们看看性能。很明显,比起一个简单的变量,闭包空间,甚或(对象)属性要慢的多,且更消耗资源。这就是本文更多关注普通方式和闭包空间机制差异的原因。为证明闭包空间机制并不比标准方式更消耗资源,我写了下面代码做个基准测试:htmlfont-family:HelveticaNeue,Helvetica;Computing.varresults=document.getElementById(results);varsampleSize=1000000;varopCounts=1000000;varentities=;setTimeout(function()/Creatingentitiesfor(varindex=0;indexsampleSize;index+)entities.push(property:helloworld(+index+);/Randomreadsvarstart=newDate().getTime();for(index=0;indexopCounts;index+)varposition=Math.floor(Math.random()*entities.length);vartemp=perty;varend=newDate().getTime();results.innerHTML=Results:Usingmemberaccess:+(end-start)+ms;,0);setTimeout(function()/Closurespace=varcreateProperty=function(obj,prop,currentValue)Object.defineProperty(obj,prop,get:function()returncurrentValue;,set:function(value)currentValue=value;,enumerable:true,configurable:true);/Addingpropertyandusingclosurespacetosaveprivatevaluefor(varindex=0;indexsampleSize;index+)varentity=entitiesindex;varcurrentValue=perty;createProperty(entity,property,currentValue);/Randomreadsvarstart=newDate().getTime();for(index=0;indexopCounts;index+)varposition=Math.floor(Math.random()*entities.length);vartemp=perty;varend=newDate().getTime();results.innerHTML+=Usingclosurespace:+(end-start)+ms;,0);setTimeout(function()/Usinglocalmember=/Addingpropertyandusinglocalmembertosaveprivatevaluefor(varindex=0;indexsampleSize;index+)varentity=entitiesindex;entity._property=perty;Object.defineProperty(entity,property,get:function()returnthis._property;,set:function(value)this._property=value;,enumerable:true,configurable:true);/Randomreadsvarstart=newDate().getTime();for(index=0;indexopCounts;index+)varposition=Math.floor(Math.random()*entities.length);vartemp=perty;varend=newDate().getTime();results.innerHTML+=Usinglocalmember:+(end-start)+ms;,0);我创建了一百万个对象,都有属性成员。要完成下面三个测试: 执行 1百万次随机访问属性。 执行1百万次随机访问闭包空间实现版本。 执行1百万次随机访问常规get/set实现版本。测试结果参见下面表格和图表:我们发现,闭包空间实现总是快于常规实现,根据浏览器的不同,还可以做进一步的性能优化。Chrome 上的性能表现低于预期。或许存在 bug,因此,为确认(存在 bug),我联系了 Google 项目组,描述发生的症状。还有,如果你打算测试在Microsoft Edge微软新发布的浏览器,在windows10 中默认安装中的性能表现,你可以点击下载。然而,如果仔细研究,你会发现,使用闭包空间或属性比直接访问变量成员要10倍左右。因此,使用要恰当且谨慎。4.内存占用(Memory Footprint)我们也得验证该技术不会消耗过多内存。为测试内存占用基准情况,我写了下面代码段:直接属性引用版本(Reference Code)varsampleSize=1000000;varentities=;/Creatingentitiesfor(varindex=0;indexsampleSize;index+)entities.push(property:helloworld(+index+);常规方式版本(Regular Way,get/set)varsampleSize=1000000;varentities=;/Addingpropertyandusinglocalmembertosaveprivatevaluefor(varindex=0;indexsampleSize;index+)varentity=;entity._property=helloworld(+index+);Object.defineProperty(entity,property,get:function()returnthis._property;,set:function(value)this._property=value;,enumerable:true,configurable:true);entities.push(entity);闭包空间版本(Closure Space Version)varsampleSize=1000000;varentities=;varcreateProperty=function(obj,prop,currentValue)Object.defineProperty(obj,prop,get:function()returncurrentValue;,set:function(value)currentValue=value;,enumerable:true,configurable:true);/Addingpropertyandusingclosurespacetosaveprivatevaluefor(varindex=0;indexsampleSize;index+)varentity=;varcurrentValue=helloworld(+index+);createProperty(entity,property,currentValue);entities.push(entity);之后,我(在三个主流浏览器上)运行所有的三段代码,启动(浏览器)内嵌的内存性能分析器(本示例中使用 F12 工具条):我计算机上运行的结果如下图表:就闭包空间和常规方式,只有 Chrome上,闭包空间(内存占用)表现稍好,在 IE11 和 Firefox上占用内存反而增多,但是浏览器的比较结果e对于现代浏览器,用户很可能不会在意这点差别。更多 JavaScript 实践或许你会吃惊,微软提供了一批有关开源 Javascript 主题的免费学习材料,我们正在发起一个任务,关于创建更多Microsoft Edge 来临系列。 查看我的文章: 基于HTML5 和 Babylon.JS开发 WebGL 3D

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论