私有JS函数,这是怎么回事
Private JS function, What is wrong with this?
- 在构造函数中为对象编写公共函数有什么问题吗
- 在构造函数函数的原型链中添加函数有什么问题吗
- 替代方案
var obgect = function (constructorOptions) {
var privateFunction1 = function (v1) {
return 'You said: ' + v1;
};
this.willHaveAccessToPrivate = function () {
return 'This function will have access to privateFunction1(), but will I be on prototype chain?';
};
obgect.prototype.anotherPublicFunction = function () {
var s = privateFunction1('I have access to you.');
return 'Adding on prototype from within the constructor.';
};
};
obgect.prototype = new Object();
obgect.prototype.outsidePublicFunction = function () {
var s = privateFunction1('I will fail here because you are not accessible.');
return 'Standard practice';
};
var instance = new obgect({
'gurusWanted': true,
'hurtsMyHead': true,
'discouragesMe': false
});
var outside = instance.outsidePublicFunction(); // will fail here.
var anotherInside = instance.anotherPublicFunction(); // will work!
1.在对象的构造函数中为其编写公共函数有什么问题吗?
不,这是相当普遍的做法。这确实意味着每个实例都会获得每个函数的自己的副本,这可能会对内存产生一些影响,但除非你要创建数千个,否则这不一定是个问题。你只需要知道你在做。
2.在构造函数中向原型链添加函数有什么问题吗?
是 ,非常重要。它会在实例之间创建串扰,因为之前创建的实例最终将使用之后创建的实例分配给原型的函数。非常非常需要避免的事情。考虑一个简单得多的例子:
function Example(data) {
var privateData = data;
Example.prototype.doSomethingWithPrivateData = function() {
console.log(privateData);
};
}
var e1 = new Example(1);
e1.doSomethingWithPrivateData(); // "1"
var e2 = new Example(2);
e2.doSomethingWithPrivateData(); // "2"
到目前为止,一切都很好,对吧但是:
e1.doSomethingWithPrivateData(); // "2"
哎呀!e1
现在使用e2
的私有数据,因为e2
是在e1
之后创建的,并重新连接了原型。
原型上的函数不能访问以您创建它们的方式(在构造函数中)创建的"私有"函数。
3.替代方案?
这可能是一个太宽泛的问题,无法回答,但上面的规则应该可以帮助你决定如何进行。
但是,如果拥有实例的私有特性对您来说是一件重要的事情,那么您可以在获得函数重用的同时使用一种模式。我在这篇博客文章中详细介绍了这一点,但要点是:
在ES6中,我们将有"专用Name
对象",它们可以用作属性键,因此您可以将数据存储在无法访问的实例中,除非您有那个特殊的Name
对象。现在,我们在ES5中无法做到这一点,但我们可以通过使用返回半随机名称的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;
}();
下面是我们如何让(几乎)私人会员使用它:
// Nearly-private properties
// ***No `import` here (once the final form is determined, we'll probably be able to feature test for it)
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
Foo
之外的任何东西都不能轻易使用几乎私有的数据,因为属性名称不断更改。
相关文章:
- Javascript袖珍参考,第121页:这是怎么回事;猴子补丁”;方法应该有效
- 基本的HTML Javascript程序.这是怎么回事
- 每次运行此代码时,我都会得到不同的结果,这是怎么回事
- jQuery extend 函数是怎么回事
- “Bada” - 这个JavaScript片段是怎么回事
- 如何使文本字段为空?这是怎么回事
- 自定义SVG签名在CODEPEN上有效,但在本地机器上无效-这是怎么回事
- 事件侦听器不会在IE中被调用 - 这是怎么回事
- HTML 中的空脚本标签是怎么回事
- 这个JavaScript片段是怎么回事
- 调用堆栈超出,甚至没有任何递归.这是怎么回事
- 日期时间选择器不起作用.不明白怎么写JS
- 带有奇怪输出的单行 - 字符串作为“这个”是怎么回事
- 这个速记运算符是怎么回事
- 网站似乎在没有向服务器发送密码的情况下登录用户;这是怎么回事
- 将多个值分配给一个变量.这是怎么回事
- 图片库的图片预装器?这是怎么回事
- 私有JS函数,这是怎么回事
- 这段JS代码是怎么回事?
- 这个JS语法是什么意思? 'length'是怎么回事?