我正在尝试使用这种模式创建各种“构造函数”:
function mything() {
var a, b, c;
...
return {
publicFunc: function() {
//access private vars here
}
};
}
//usage
mything1 = mything();
mything2 = mything();
问题是,我还希望通过instanceof
测试:
assert(mything1 instanceof mything === true);
有没有办法做到这一点?使用常规构造函数将无法工作,因为原型函数无法访问私有变量。
答案 0 :(得分:4)
您需要使用稍微不同的设计模式来拥有私有变量并使其成为mything
的实例:
function mything() {
var a, b, c;
...
this.publicFunc = function() {
//access private vars here
}
};
}
//usage
var mything1 = new mything();
mything1.publicFunc();
var mything2 = new mything();
答案 1 :(得分:0)
技术上可行,但您可以更优雅地解决您的问题(解释如下):
function mything() {
var a, b, c;
function PrivateConstructor() {
this.publicFunc = function() {}
}
// this is the magic that makes it happen:
PrivateConstructor.prototype = mything.prototype;
return new PrivateConstructor();
}
mything1 = mything();
assert(mything1 instanceof mything); // passes
或者,使用EcmaScript 5功能:
function mything() {
var a, b, c;
var object = Object.create(mything.prototype);
object.publicFunc = function() {}
return object;
}
mything1 = mything();
assert(mything1 instanceof mything); // passes
如果右侧操作数是一个函数,instanceof
运算符将返回true,并且存储在该函数的prototype
属性中的对象包含在左侧的原型链中操作数。
第一个示例将mything.prototype
作为“prototype”属性重新用于另一个临时函数,该函数仅用于生成一个对象(在其原型链中具有mything.prototype
)。第二个示例通过直接从Object.create()
继承mything.prototype
来创建此类对象。
这两个对象都继承自mything.prototype
,因此将通过object instanceof mything
测试。
话虽这么说,jfriend00提出的模式具有更少的开销,并且在提供您想要的功能时更容易阅读。