gpt4 book ai didi

具有私有(private)/公共(public)方法的 Javascript 模块模式

转载 作者:行者123 更新时间:2023-11-30 08:36:17 26 4
gpt4 key购买 nike

我被要求制作一个 Javascript 模块,作为浏览器事件的计数器,并且不可能修改实际计数的事件(私有(private)方法)。

var CountingLogger = (function() {

var secret ={};
var uid = 0;
function CountingLogger(events) {
secret[this.id = uid++] = {};
// Store private stuff in the secret container
// instead of on `this`.
secret[this.id].events = events || 0;
}

CountingLogger.prototype.log = function (eventName) {
alert(secret[this.id].events[eventName]);
if (typeof secret[this.id].events[eventName] === 'undefined') {
secret[this.id].events[eventName] = 0;
}
secret[this.id].events[eventName]++;
var count = secret[this.id].events[eventName];
$('#logContents').append('<li>' + eventName + ': ' + count + '</li>');
};

return CountingLogger;
}());

在 main.js 中我定义: var logger = new CountingLogger();然后打电话 logger.log('EventName');

并且应该作为计数器“EventName”+ Counter 的回调出现,所以 Eventname:1,SecondEvent:4 ...但在日志中始终显示未定义的“WhateverEvent”。任何人都可以知道如何解决这个问题吗?问候

最佳答案

您不希望 secret 处于您所拥有的级别。作为Bergi said ,这是内存泄漏。

(注意:当我在下面说“真正私有(private)”时,请记住,如果有人使用调试器,没有是真正私有(private)的。下面的“真正私有(private)”只是让任何人都无法编写使用对象引用获取或修改私有(private)数据的代码。)

ES7 将拥有真正的私有(private)属性。在那之前,您基本上有三个选择:

  1. 真正私有(private)的数据,通过调用构造函数的闭包保存

  2. 通过属性命名约定“放手”属性

  3. 非常难以使用的属性,虽然不是私有(private)的,但很难针对这些属性编写代码

真正的私有(private)数据

如果您想要基于每个实例的真正私有(private)信息,标准方法是在构造函数中使用变量,并在构造函数中定义需要私有(private)数据的方法:

function Foo() {
var secret = Math.floor(Math.random() * 100);
this.iWillTellYouASecret = function() {
console.log("The secret is " + secret);
};
}
Foo.prototype.iDoNotKnowTheSecret = function() {
console.log("I don't know the secret");
};

是的,这意味着为每个实例创建了一个新的 iWillTellYouASecret 函数,但是当该实例从内存中删除时,它(和 secret )也会回收,并且一个体面的 JavaScript 引擎可以在这些函数对象之间重用函数的代码

“让你的手离开”属性

但大多数时候,您不需要真正的私有(private)信息,只需要“ Handlebars 拿开我”的信息。在 JavaScript 中,约定是以 _ 开头的属性。是的,这意味着可以访问实例的代码可以使用或更改该属性的值,但在大多数也具有“真正私有(private)”属性的语言(例如 Java)中,通过反射确实如此。

非常难用的属性

如果你想让试图使用你的私有(private)数据的人过得更难,你可以使用 an old blog article of mine 中的这个技巧*(当 ES6 将通过 Name 对象拥有真正的隐私时,它被写回了;从那时起,Name 变成了 Symbol 并且它是' 用于隐私了):

首先,您创建一个 Name 伪类:

var Name = function() {
var used = {};

function Name() {
var length, str;

do {
length = 5 + Math.floor(Math.random() * 10);
str = "_";
while (length--) {
str += String.fromCharCode(32 + Math.floor(95 * Math.random()));
}
}
while (used[str]);
used[str] = true;
return new String(str); // Since this is called via `new`, we have to return an object to override the default
}

return Name;
}();

然后您将此模式用于您的私有(private)实例属性:

// Nearly-private properties
var Foo = (function() {
// Create a random string as our private property key
var nifty = new Name();

// Our constructor
function Foo() {
// We can just assign here as normal
this[nifty] = 42;
}

// ***On ES5, make the property non-enumerable
// (that's the default for properties created with
// Object.defineProperty)
if (Object.defineProperty) { // Only needed for ES3-compatibility
Object.defineProperty(Foo.prototype, nifty, {
writable: true
});
}
// ***End change

// Methods shared by all Foo instances
Foo.prototype.method1 = function() {
// This method has access to `nifty`, because it
// closes over the private key
console.log("Truly private nifty info: " + this[nifty]);
};
Foo.prototype.method2 = function() {
// Also has access, for the same reason
console.log("Truly private nifty info: " + this[nifty]);
};

return Foo;
})();

var f = new Foo();
f.method1(); // Can use nifty!
f.method2(); // Can too! :-)
// Both `method1` and `method2` are *reused* by all `Foo` objects

现在,您的私有(private)属性的名称每次运行时都不同。

这仍然不是私有(private)。只是更难找到。

关于具有私有(private)/公共(public)方法的 Javascript 模块模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31140332/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com