我有一些关于JavaScript的问题,我需要确定。为了帮助我,我正在编写一个简单的类定义:
var dataSource = function (src, extension) {
return {
exists: function () {
// function to check if the source exists (src *should* be an object
// and extension should be a string in the format ".property.property.theSource".
// this function will return true if src.property.property.theSource exists)
},
get: function () {
// function will return the source (ex: return src.property.property.theSource)
}
}
}();
问题:
1)在我目前对JavaScript的理解中,调用dataSource()将创建一个新对象,其中包含其自身副本的exists()和get()方法。我是对的吗?
2)有没有办法写这个,这样如果我创建了1,000,000个dataSource对象,我只需要拥有每个函数的一个副本?
3)我是否应该关注(2)?
答案 0 :(得分:7)
你所拥有的是一个函数,它返回Object的istance,而不是JS类。
您需要使用DataSource.prototype
结帐,如果要将其与this
你应该做这样的事情:
function DataSource(src, extension){
//Make sure this behaves correctly if someone forgets to use new
if (! this instanceof DataSource)
return new DataSource(src,extension);
//store the constructor arguments
//so you can use them in the shared methods below
this._src=src;
this._extension=extension;
}
DataSource.prototype.exists=function(){
//use this._src and this._extension here
//This method will be available to all
//objects constructed by new DataSource(...)
};
DataSource.prototype.get=function(){
//use this._src and this._extension here
//This method will be available to all
//objects constructed by new DataSource(...)
};
var instance = new DataSource('a source','an extension');
修改 您提到过您更喜欢'私有'变量
构造闭包是模拟私有属性的唯一可移植方式,但是根据我的经验,为它们添加_
前缀,并且组织内部的约定不依赖于{{1}在大多数情况下,前缀变量就足够了
答案 1 :(得分:5)
Prototype是你想要使用的。它将被存储一次并与对象的所有实例相关联。
答案 2 :(得分:0)
您可以像这样创建该类,以轻松制作多个副本。
编辑 - 添加了构造函数参数。
function DataSource(src, extension) {
this.src = src,
this.extension = extension,
this.exists = function() {
// function to check if the source exists (src *should* be an object
// and extension should be a string in the format ".property.property.theSource".
// this function will return true if src.property.property.theSource exists)
},
this.get = function() {
// function will return the source (ex: return src.property.property.theSource)
}
}
dataSource1 = new DataSource();
dataSource2 = new DataSource();
答案 3 :(得分:0)
您已在返回值中插入了类变量。因此,当您实例化许多对象时,将创建许多实例。
根据您的要求,如果您将类变量与返回类型分开并仅声明一次(对于所有),那么对于每个实例,这些属性都可用。这意味着那些变量(定义为ExampleClass.prototype = function(){})将作为c / c ++中的静态变量
答案 4 :(得分:0)
更新了ES6类语法(这是编写@ tobyodavies答案的另一种方式):
class DataSource {
constructor(src, extension) {
this._src = src;
this._extension = extension;
}
exists() {
}
get() {
}
};
var instance = new DataSource('a source','an extension');
没有必要检查是否使用new实例调用了类,因为ES6类不可能这样做。它将返回Class constructor DataSource cannot be invoked without 'new'
错误。