以正确的方式设计课程

时间:2011-01-28 07:40:39

标签: javascript oop

我有一些关于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)?

5 个答案:

答案 0 :(得分:7)

你所拥有的是一个函数,它返回Object的istance,而不是JS类。

您需要使用DataSource.prototype结帐,如果要将其与this new >

你应该做这样的事情:

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'错误。