Javascript 如何正确地将JS代码组织到更传统的类结构中?

Javascript 如何正确地将JS代码组织到更传统的类结构中?,javascript,class,constructor,Javascript,Class,Constructor,我正在努力处理我的JS代码结构,这在我的单元测试尝试中变得越来越明显。我已经习惯了类的结构,但是在JS世界里我有点迷失了,那里没有任何类。我正在寻找一种在传统的类/构造函数体系结构中组织代码的方法。以下是我所拥有的: function ddGridSelector(primaryId, templateDefault, gridObj) { //set the variables this.primaryId = primaryId, this.defaultTempla

我正在努力处理我的JS代码结构,这在我的单元测试尝试中变得越来越明显。我已经习惯了类的结构,但是在JS世界里我有点迷失了,那里没有任何类。我正在寻找一种在传统的类/构造函数体系结构中组织代码的方法。以下是我所拥有的:

function ddGridSelector(primaryId, templateDefault, gridObj) {
    //set the variables
    this.primaryId = primaryId,
    this.defaultTemplate = templateDefault,
    this.gridObj = gridObj,
    this.gridObj.searchVal = '',

    this.init = ddgs_init
}

function ddgs_init(ddgs_obj) {
    ddgs_setDefaultTemplate(ddgs_obj);
    ddgs_initGrid(ddgs_obj);
    ddgs_initKendoWindow(ddgs_obj);
    ddgs_initKendoButton(ddgs_obj);
    ddgs_initResetButton(ddgs_obj);
    ddgs_addGridEventListener(ddgs_obj);
}

function ddgs_setDefaultTemplate(ddgs_obj) {
    //doing stuff
}

function ddgs_initGrid(ddgs_obj) {
    //more stuff
}
把这些叫做

var ddGridSelector_new = new ddGridSelector('PrimaryIdentifier', templateDefault, gridObj);

ddGridSelector_new.init(ddGridSelector_new);
将我的对象传递给构造函数中指定的函数似乎真的是多余的,所以我确信我在这里遗漏了一些明显的东西。我真的希望能在这件事上得到一些指导。我想我即将走上一条好的道路

但是我有点迷失在JS的世界里,那里没有任何类

但是。。。有

class ddGridSelector {
    constructor(primaryId, templateDefault, gridObj) {
        //set the variables
        this.primaryId = primaryId,
        this.defaultTemplate = templateDefault,
        this.gridObj = gridObj,
        this.gridObj.searchVal = '',
     }

     init() {
        this.setDefaultTemplate();
        this.initGrid();
        this.initKendoWindow();
        this.initKendoButton();
        this.initResetButton();
        this.addGridEventListener();
    }

    setDefaultTemplate() {
        //doing stuff
    }

    initGrid() {
        //more stuff
    }
}
但是我有点迷失在JS的世界里,那里没有任何类

但是。。。有

class ddGridSelector {
    constructor(primaryId, templateDefault, gridObj) {
        //set the variables
        this.primaryId = primaryId,
        this.defaultTemplate = templateDefault,
        this.gridObj = gridObj,
        this.gridObj.searchVal = '',
     }

     init() {
        this.setDefaultTemplate();
        this.initGrid();
        this.initKendoWindow();
        this.initKendoButton();
        this.initResetButton();
        this.addGridEventListener();
    }

    setDefaultTemplate() {
        //doing stuff
    }

    initGrid() {
        //more stuff
    }
}

当我想要避免新特性时,我倾向于喜欢这种类式布局的结构。它为您提供了一个私有作用域,您可以在其中根据需要对函数和共享变量进行作用域划分,并允许您在原型上分离“构造函数”和公共方法

var MyType = (function () {
    function MyType() {
        //My Constructor
    }

    MyType.prototype = {
        constructor: MyType,
        publicMethod: privateMethod
    };

    function privateMethod() {
        ...
    }

    return MyType;
}());
外部作用域立即运行并保持全局命名空间干净。我们用原型实例方法扩充私有函数,定义所需的任何“私有”方法,并在设置后返回私有类型。这使您可以实例化一个类似于普通的类并调用任何方法

var example = new MyType();
example.publicMethod();

当我想要避免新特性时,我倾向于喜欢这种类式布局的结构。它为您提供了一个私有作用域,您可以在其中根据需要对函数和共享变量进行作用域划分,并允许您在原型上分离“构造函数”和公共方法

var MyType = (function () {
    function MyType() {
        //My Constructor
    }

    MyType.prototype = {
        constructor: MyType,
        publicMethod: privateMethod
    };

    function privateMethod() {
        ...
    }

    return MyType;
}());
外部作用域立即运行并保持全局命名空间干净。我们用原型实例方法扩充私有函数,定义所需的任何“私有”方法,并在设置后返回私有类型。这使您可以实例化一个类似于普通的类并调用任何方法

var example = new MyType();
example.publicMethod();
ES5路 您可以这样做“函数类”,这是非常自我解释的:

函数用户(名称){
//因此,这个名字在这里是“私有的”,因为它是
//不放在“this.name”下
this.sayHi=函数(){
警报(名称);
};
}
let user=新用户(“John”);
user.sayHi();//约翰
还有原型类模式:

函数用户(姓名、生日){
这个。_name=name;
}
User.prototype.sayHi=函数(){
警报(此名称);
};
let user=新用户(“John”);
user.sayHi();//约翰

ES6+方式 在ES6中,您可以以更像传统编程语言的方式声明类:

类用户{
建造师(姓名){
this.name=名称;
}
(){
警报(此名称);
}
}
let user=新用户(“John”);
user.sayHi();//约翰
但是,如果您的目标平台是IE(所有版本)、Opera Mini和Android浏览器(4.4.x,)(),或者旧iOS设备上的Cordova(<10、UIWebView等),则您需要一个类似transplier的或将其编译为与web兼容的代码

Node.js应该支持4.8.4(!)及以上版本的类,令人惊讶的是()。

ES5-Way 您可以这样做“函数类”,这是非常自我解释的:

函数用户(名称){
//因此,这个名字在这里是“私有的”,因为它是
//不放在“this.name”下
this.sayHi=函数(){
警报(名称);
};
}
let user=新用户(“John”);
user.sayHi();//约翰
还有原型类模式:

函数用户(姓名、生日){
这个。_name=name;
}
User.prototype.sayHi=函数(){
警报(此名称);
};
let user=新用户(“John”);
user.sayHi();//约翰

ES6+方式 在ES6中,您可以以更像传统编程语言的方式声明类:

类用户{
建造师(姓名){
this.name=名称;
}
(){
警报(此名称);
}
}
let user=新用户(“John”);
user.sayHi();//约翰
但是,如果您的目标平台是IE(所有版本)、Opera Mini和Android浏览器(4.4.x,)(),或者旧iOS设备上的Cordova(<10、UIWebView等),则您需要一个类似transplier的或将其编译为与web兼容的代码


Node.js应该支持4.8.4(!)及以上版本的类,令人惊讶的是()。

。只是要确保不要在不适合的地方应用它,但是你已经有了一个传统的构造函数。也许你想了解一下以前的。。只需确保不要在不适合的地方应用它,但您已经有了传统的构造函数。也许您想了解以前的。类私有函数会大大增加内存使用。我不建议这样做,因为这会对内存使用产生负面影响。我以前从未听说过。你的意思是在原型中定义并引用它们,还是在原型中使用匿名函数?是的,请阅读本文,我认为这不适用于此代码。我没有实现对象存储,只是一个新实例的原型。它适用于
privateMethod
,它对公共范围隐藏,并存储类元素的闭包。类私有函数会大大增加内存使用。我不建议这样做,因为这会对内存使用产生负面影响。我以前从未听说过。你的意思是在原型中定义并引用它们,还是在原型中使用匿名函数?是的,请阅读本文,我认为这不适用于此代码。我没有实现对象存储,只是一个新实例的原型。它适用于
privateMethod
,它对公共范围隐藏,并存储类元素的闭包。如今,您不需要transpiler来处理类:我选择这个答案是因为提供的源代码帮助我理解了您推理背后的逻辑。这一点和我提出的任何问题都很容易被推荐人回答