向这样的原型添加新函数时,您无法访问构造函数中定义的变量,因为它们超出了范围。
function Thing() {
var something = 357;
}
Thing.prototype.doSomething = function () {
// no access to something because it is out of scope
console.log(something);
};
感谢在构造函数中将函数添加到原型时的闭包,它可以访问那里定义的变量。
function Thing() {
var something = 357;
Thing.prototype.doSomething = function () {
console.log(something);
};
}
这是一种可以访问这些变量的好方法,还是有更好的模式来实现相同的目标?我有什么陷阱需要注意吗?
答案 0 :(得分:2)
您无法从原型中访问私有变量。但是,您可以访问公共变量。我发现这是一个很好的权衡:
function Thing() {
this._something = 357;
}
Thing.prototype.doSomething = function () {
console.log(this._something);
};
在属性之前放置_
的命名约定只是将其标记为私有的非正式方式,即使它实际上并非如此。
答案 1 :(得分:1)
你的设计存在一些致命缺陷:
每次调用构造函数时重新定义函数都是不可避免的特权函数,但是如果选择沿着那条路走下去,你可以直接在this
而不是原型上定义函数。
function SomeObject() {
var privateVar = 'private value';
this.somePriviledgedFunction = function () {
//Use privateVar here
};
}
现在,在WeakMap
的支持下,有一个新模式可以让您从原型上定义的函数访问私有成员。您基本上会在类声明周围使用IIFE,并且只有在该范围内可见的共享WeakMap
才能容纳所有私有成员。对象实例将用作键,以便在对象不再存在时,它们的值会被垃圾收集。
var SomeObject = (function (privates) {
function SomeObject(someValue) {
privates.set(this, {}); //initialze the privates scope
privates.get(this).privateVar = someValue;
}
Object.defineProperty(SomeObject.prototype, 'privateVar', {
get: function () {
return privates.get(this).privateVar;
}
});
return SomeObject;
})(new WeakMap());
var o1 = new SomeObject('first object');
var o2 = new SomeObject('second object');
o1.privateVar; //first object
o2.privateVar; //second object
但请注意,每个需要访问私有变量的SomeObject
原型函数都必须在同一个模块中定义(在周围的IIFE中)。另一个问题是,如果一个人不注意设计,而不是来自IIFE之外定义的任何功能,那么其他类的实例可能会偷走其他人的私人,这对我来说不是一个真正的问题。