2KB项目,专业的源码交易网站 帮助 收藏 每日签到

JavaScript:怎么在工具中嵌入私有成员

  • 时间:2019-05-11 18:14 编辑:2KB 来源:2KB.COM 阅读:425
  • 扫一扫,手机访问
  • 分享
摘要: 英文原文:Jav
英文原文:JavaScript: How to Embed Private Members Into an Object

比来,我开发一个项目 Angular Cloud Data Connector, 协助Angular开发者运用云数据,特殊是 AzureMobile服务, 运用WEB规范,像索引数据库(indexed DB)。我测验考试树立一种方法,使得JavaScript开发者能将私有成员嵌入到一个工具中。 

我处理这个问题的技术用到了我定名的闭包空间(closure space)。在这篇入门文章中,我要分享的是怎么在你的项目顶用它,及它对主流阅读器的功能和内存的影响。

在深化进修前,我们先说下,你为何需求用到私有成员(private members), 另有一种替换方法来模仿私有成员。

假如你想点评本文,纵情推(twitter)我: @deltakosh

1. 为什么要用私有成员(Private Members)

当你用JavaScript 创立一个工具时,可以声明值成员(value members)。 假如你计划把持对它们的读/写拜访操作,可以以下声明:

var entity = {};
 
entity._property = "hello world";
Object.defineProperty(entity, "property", {
    get: function () { return this._property; },
    set: function (value) {
        this._property = value;
    },
    enumerable: true,
    configurable: true
});

如许完成,你能完整把持读和写操作。问题在于_property 成员依然可以间接拜访和修正。

这也就是为什么我们需求愈加波动牢靠的方法,声明私有成员,它智能经过工具的办法来拜访。

2. 运用闭包空间(Closure Space)

处理办法是运用闭包空间。每当外部函数 (inner fanction) 拜访来自内部函数用处域的变量时,阅读器为你分派一段内存空间。有时很取巧,不外就我们的标题来说,这算是一个完满的处理计划。

我们在上个代码版本中添加这个特征:
var createProperty = function (obj, prop, currentValue) 
{
    Object.defineProperty(obj, prop, 
    {
            get: function () { return currentValue; },
            set: function (value) {
            currentValue = value;
                    },
                    enumerable: true,
                    configurable: true    });
                    } 
var entity = {}; 
var myVar = "hello world";createProperty(entity, "property", myVar);

示例中,createProperty 函数有一个 currentValue 变量,存在 get 和 set 办法。此变量会保管到 get 和 set 函数的闭包空间中。如今,只要这两个函数能看到和更新 currentValue 变量! Task完成!

独一需求警觉 caveat,正告,留意)的是源值 (myVar) 仍可拜访。下面给出另外一个更强健的版本(维护 myVar 变量):

var createProperty = function (obj, prop) {
    var currentValue = obj[prop];
    Object.defineProperty(obj, prop, {
        get: function () { return currentValue; },
        set: function (value) {
            currentValue = value;
        },
        enumerable: true,
        configurable: true
    });
}
 
var entity = {
    property: "hello world"
};
 
createProperty(entity, "property");

采取该函数, 即使源值都烧毁(destructed,注:意思是不克不及间接赋值)了。到此半途而废了!

3. 功能思索Performance Considerations

如今我们看看功能。

很分明,比起一个容易的变量,闭包空间,甚或(工具)属性要慢的多,且更耗费资本。这就是本文更多存眷通俗方法和闭包空间机制差别的缘由。

为证实闭包空间机制其实不比规范方法更耗费资本, 我写了下面代码做个基准测试:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<style>
    html {
        font-family: "Helvetica Neue", Helvetica;
    }
</style>
<body>
    <div id="results">Computing...</div>
    <script>
        var results = document.getElementById("results");
        var sampleSize = 1000000;
        var opCounts = 1000000;
 
        var entities = [];
 
        setTimeout(function () {
            // Creating entities
            for (var index = 0; index < sampleSize; index++) {
                entities.push({
                    property: "hello world (" + index + ")"
                });
            }
 
            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();
 
            results.innerHTML = "<strong>Results:</strong><br>Using member access: <strong>" + (end - start) + "</strong> ms";
        }, 0);
 
        setTimeout(function () {
            // Closure space =======================================
            var createProperty = function (obj, prop, currentValue) {
                Object.defineProperty(obj, prop, {
                    get: function () { return currentValue; },
                    set: function (value) {
                        currentValue = value;
                    },
                    enumerable: true,
                    configurable: true
                });
            }
            // Adding property and using closure space to save private value
            for (var index = 0; index < sampleSize; index++) {
                var entity = entities[index];
 
                var currentValue = entity.property;
                createProperty(entity, "property", currentValue);
            }
 
            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();
 
            results.innerHTML += "<br>Using closure space: <strong>" + (end - start) + "</strong> ms";
        }, 0);
 
        setTimeout(function () {
            // Using local member =======================================
            // Adding property and using local member to save private value
            for (var index = 0; index < sampleSize; index++) {
                var entity = entities[index];
 
                entity._property = entity.property;
                Object.defineProperty(entity, "property", {
                    get: function () { return this._property; },
                    set: function (value) {
                        this._property = value;
                    },
                    enumerable: true,
                    configurable: true
                });
            }
 
            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();
 
            results.innerHTML += "<br>Using local member: <strong>" + (end - start) + "</strong> ms";
        }, 0);
 
    </script>
</body>
</html>

我创立了一百万个工具,都有属性成员。要完成下面三个测试:

  • 履行 1百万次随机拜访属性。

  • 履行1百万次随机拜访闭包空间完成版本。

  • 履行1百万次随机拜访惯例get/set完成版本。

测试后果拜见下面表格和图表:

Table of results for IE11 Chrome 36 and Firefox 31Chart of results for IE11 Chrome 36 and Firefox 31

我们发明,闭包空间完成老是快于惯例完成,依据阅读器的分歧,还可以做进一步的功能优化。

Chrome 上的功能表示低于预期。也许存在 bug,因而,为确认(存在 bug),我联络了 Google 项目组,描绘发作的症状。另有,假如你计划测试在 Microsoft Edge —微软新宣布的阅读器,在windows10 中默许安装—中的功能表示,你可以点击下载 

但是,假如细心研讨,你会发明,运用闭包空间或属性比间接拜访变量成员要10倍摆布。 因而,运用要适当且慎重。

Chart comparing Direct access closure space and regular way

4. 内存占用(Memory Footprint)

我们也得验证该技术不会耗费过量内存。为测试内存占用基准状况,我写了下面代码段:

间接属性援用版本(Reference Code)

var sampleSize = 1000000;
 var entities = []; 
// Creating entities
for (var index = 0; index < sampleSize; index++) {
    entities.push({
            property: "hello world (" + index + ")"
});}

惯例方法版本(Regular Way,get/set)

var sampleSize = 1000000;
 
var entities = [];
 
// Adding property and using local member to save private value
for (var index = 0; index < sampleSize; index++) {
    var entity = {};
 
    entity._property = "hello world (" + index + ")";
    Object.defineProperty(entity, "property", {
        get: function () { return this._property; },
        set: function (value) {
            this._property = value;
        },
        enumerable: true,
        configurable: true
    });
 
    entities.push(entity);
}

闭包空间版本(Closure Space Version)

var sampleSize = 1000000;
 
var entities = [];
 
var createProperty = function (obj, prop, currentValue) {
    Object.defineProperty(obj, prop, {
        get: function () { return currentValue; },
        set: function (value) {
            currentValue = value;
        },
        enumerable: true,
        configurable: true
    });
}
 
// Adding property and using closure space to save private value
for (var index = 0; index < sampleSize; index++) {
    var entity = {};
 
    var currentValue = "hello world (" + index + ")";
    createProperty(entity, "property", currentValue);
 
    entities.push(entity);
}

以后,我(在三个主流阅读器上)运转一切的三段代码,启动(阅读器)内嵌的内存功能剖析器(本示例中运用 F12 Tools条):

embedded memory profiler example here using F12 tools

我盘算机上运转的后果以下图表:

Chart of the results I got on my computer

就闭包空间和惯例方法,只要 Chrome上,闭包空间(内存占用)表示稍好,在 IE11 和 Firefox上占用内存反而增多,可是阅读器的比较后果e—关于当代阅读器,用户极可能不会在乎这点差异。


更多 JavaSc 理论

也许你会受惊,微软供给了一批有关开源 Javascript 主题的收费进修资料, 我们正在倡议一个Task,关于创立更多 Microsoft Edge 降临 系列。 检查我的文章:

或许我们团队系列:

和一些收费Tools:Visual Studio 社区Azure 试用版跨阅读器测试Tools用于 Mac, Linux, 或许 Windows。

结论(Conclusion)

如你所见,关于创立真实的私有数据来说,闭包空间属性(机制)是一个很棒的做法。也许你得面临内存耗费小幅度增加(问题),但就我的见解,这却很公道 (这个价格可以换取相对惯例办法更高的功能增加)。

随带说一句, 假如你要本人入手尝尝,所以代码可以在 here下载。 引荐一篇不错的文章, “how-to” on Azure Mobile Services here

本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协议,假如我们的任务有进犯到您的权益,请实时联络我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部