javascript的作用域详解精简版(浅谈JavaScript 中的延迟加载属性模式)
javascript的作用域详解精简版
浅谈JavaScript 中的延迟加载属性模式目录
- 一、前言
- 二、按需属性模式
- 三、凌乱的延迟加载属性模式
- 四、类的唯一自己的延迟加载属性模式
- 五、对象字面量的延迟加载属性模式
- 六、结论
传统上,开发人员在 JavaScript 类中为实例中可能需要的任何数据创建属性。对于在构造函数中随时可用的小块数据来说,这不是问题。但是,如果在实例中可用之前需要计算某些数据,您可能不想预先支付该费用。例如,考虑这个类:
class MyClass { constructor() { this.data = someExpensiveComputation(); } }
在这里,data
属性是作为执行一些昂贵计算的结果而创建的。如果您不确定是否会使用该属性,则预先执行该计算可能效率不高。幸运的是,有几种方法可以将这些操作推迟到以后。
优化执行昂贵操作的最简单方法是等到需要数据后再进行计算。例如,您可以使用带有 getter 的访问器属性来按需进行计算,如下所示:
class MyClass { get data() { return someExpensiveComputation(); } }
在这种情况下,直到有人第一次读取该data
属性时,您的昂贵计算才会发生,这是一种改进。但是,每次data
读取属性时都会执行相同的昂贵计算,这比之前的示例更糟糕,其中至少只执行了一次计算。这不是一个好的解决方案,但您可以在此基础上创建一个更好的解决方案。
只有在访问属性时才执行计算是一个好的开始。您真正需要的是在该点之后缓存信息并仅使用缓存版本。但是您将这些信息缓存在哪里以便于访问?最简单的方法是定义一个具有相同名称的属性并将其值设置为计算数据,如下所示:
class MyClass { get data() { const actualData = someExpensiveComputation(); Object.defineProperty(this, "data", { value: actualData, writable: false, configurable: false, enumerable: false }); return actualData; } }
在这里,该data
属性再次定义为类上的 getter,但这次它缓存了结果。调用Object.defineProperty()
创建一个名为的新属性data
,该属性具有固定值actualData
,并且设置为不可写、可配置和不可枚举(以匹配 getter)。之后,返回值本身。下次data
访问该属性时,它将从新创建的属性中读取而不是调用 getter:
const object = new MyClass(); // calls the getter const data1 = object.data; // reads from the data property const data2 = object.data;
实际上,所有计算仅在第一次data
读取属性时完成。对该data
属性的每次后续读取都返回缓存的版本。
这种模式的一个缺点是data
属性开始是不可枚举的原型属性,最终是不可枚举的自己的属性:
const object = new MyClass(); console.log(object.hasOwnProperty("data")); // false const data = object.data; console.log(object.hasOwnProperty("data")); // true
虽然这种区别在很多情况下并不重要,但理解这种模式很重要,因为它在传递对象时可能会导致微妙的问题。幸运的是,使用更新的模式很容易解决这个问题。
四、类的唯一自己的延迟加载属性模式如果您有一个用例,其中延迟加载的属性始终存在于实例中很重要,那么您可以使用Object.defineProperty()
在类构造函数中创建属性。它比前面的例子有点混乱,但它会确保该属性只存在于实例上。下面是一个例子:
class MyClass { constructor() { Object.defineProperty(this, "data", { get() { const actualData = someExpensiveComputation(); Object.defineProperty(this, "data", { value: actualData, writable: false, configurable: false }); return actualData; }, configurable: true, enumerable: true }); } }
在这里,构造函数data
使用Object.defineProperty()
.该属性是在实例上创建的(通过使用this
)并定义一个 getter 并指定该属性为可枚举和可配置的(典型的自己的属性)。将data
属性设置为可配置特别重要,以便您可以Object.defineProperty()
再次调用它。
然后 getter 函数进行计算并再次调用Object.defineProperty()
。该data
属性现在被重新定义为具有特定值的数据属性,并且不可写和不可配置以保护最终数据。然后,计算数据从 getter 返回。下次data
读取属性时,它将从存储的值中读取。作为奖励,该data
财产现在仅作为自己的财产存在,并且在第一次阅读之前和之后的行为都相同:
const object = new MyClass(); console.log(object.hasOwnProperty("data")); // true const data = object.data; console.log(object.hasOwnProperty("data")); // true
对于类,这很可能是您要使用的模式;另一方面,对象文字可以使用更简单的方法。
五、对象字面量的延迟加载属性模式如果您使用对象字面量而不是类,则过程要简单得多,因为在对象字面量上定义的 getter 被定义为可枚举的自身属性(而不是原型属性),就像数据属性一样。这意味着您可以对类使用凌乱的延迟加载属性模式而对于对象来说不会凌乱:
const object = { get data() { const actualData = someExpensiveComputation(); Object.defineProperty(this, "data", { value: actualData, writable: false, configurable: false, enumerable: false }); return actualData; } }; console.log(object.hasOwnProperty("data")); // true const data = object.data; console.log(object.hasOwnProperty("data")); // true
在 JavaScript 中重新定义对象属性的能力提供了一个独特的机会来缓存可能计算成本很高的信息。通过从重新定义为数据属性的访问器属性开始,您可以将计算推迟到第一次读取属性时,然后缓存结果以供以后使用。这种方法既适用于类,也适用于对象字面量,并且在对象字面量中更简单一些,因为您不必担心您的 getter 会在原型上结束。
提高性能的最佳方法之一是避免重复执行相同的工作,因此任何时候您可以缓存结果以供以后使用,都可以加快程序的运行速度。延迟加载属性模式等技术允许任何属性成为缓存层以提高性能。
以上就是浅谈JavaScript 中的延迟加载属性模式的详细内容,更多关于JS 延迟加载属性模式的资料请关注开心学习网其它相关文章!
- vue实现图片上传数据库(vue.js根据图片url进行图片下载)
- js中substring的用法、与substr的区别
- dede友情链接改为logo轮播教程(dedecms广告生成JS文件和JS调用-DEDE广告优化)
- python json转换字符串(python3 json数据格式的转换dumps/loads的使用、dict to str/str to dict、json字符串/字典)
- js扫雷小游戏源代码(原生js实现简单贪吃蛇小游戏)
- js定时器几分钟执行(利用JS定时器实现元素移动)
- vue双向数据绑定js如何实现(纯JS如何实现vue.js下的双向绑定功能)
- vue购物车怎么实现(Vue.js框架实现购物车功能)
- nodejsweb服务(Nodejs实现内网穿透服务)
- js Date对象
- js实时获取页面宽度(JavaScript获取网页的宽高及如何兼容详解)
- js函数声明和函数表达式的区别
- js特效星空(ThingJS粒子特效一键实现雨雪效果)
- JS函数前面感叹号的作用
- js和php加密(RSA实现JS前端加密与PHP后端解密功能示例)
- vue.js入门教学第15讲(Vue.js 使用AntV X6的示例步骤)
- 经度,世界时间腕表的灵魂(世界时间腕表的灵魂)
- 阿里最新财报公布 三季度营收增长3 ,将增加150亿美元回购额度 在美股价小涨(阿里最新财报公布)
- 赵薇时胖时瘦 最近变美少女 原因在这里 躺着就变瘦(赵薇时胖时瘦最近变美)
- 学会这26种姿势,你就可以和兵哥哥切磋了(你就可以和兵哥哥切磋了)
- 吴彦祖陈冠希 恩怨 ,失去曾让他流泪的女友,终遇走过18年真爱(吴彦祖陈冠希恩怨)
- 痴情男神 吴彦祖 与妻子恋爱8年,结婚10年,家庭幸福美满(痴情男神吴彦祖)
热门推荐
- 如何采集nginx的日志(Filebeat 采集 Nginx 日志的方法)
- sqlcount优化(SQL优化教程之in与range查询)
- sql两列合并成一列格式(SQL 将一列拆分成多列的三种方法)
- mysql中常用的三种存储引擎的区别(MySQL 存储过程的优缺点分析)
- sqlserver拒绝访问怎么办(SQL server服务显示远程过程调用失败的解决方法)
- docker只有localhost可用(浅谈Docker如何自定义host文件)
- jquery解析xml
- php 经典模式(php设计模式之装饰模式应用案例详解)
- css3怎么改成3d(灵活运用CSS3特性绘制简易版围棋效果)
- SQL Server 各个版本支持的功能