javascript风格-我应该定义变量/类吗?

javascript风格-我应该定义变量/类吗?,javascript,Javascript,我的代码中的许多函数都使用此结构: options = {"param1": "yes", "param2" : "no"} 在JS中,我不必“定义”这个结构,因为它是一种动态语言 但是当我知道这个结构有一组固定的字段时,为了清晰起见,以某种集中的方式声明它是一种最佳实践吗?在类中的本地数据成员中的用法也是如此。以一个ctor或其他一些集中的方式(为了清晰起见)初始化它们是一种最佳实践吗 我知道我可以在注释中这样做,但我来自一种静态语言,我想知道javascript的风格是什么。(我希望你通常

我的代码中的许多函数都使用此结构:

options = {"param1": "yes", "param2" : "no"}
在JS中,我不必“定义”这个结构,因为它是一种动态语言

但是当我知道这个结构有一组固定的字段时,为了清晰起见,以某种集中的方式声明它是一种最佳实践吗?在类中的本地数据成员中的用法也是如此。以一个ctor或其他一些集中的方式(为了清晰起见)初始化它们是一种最佳实践吗

我知道我可以在注释中这样做,但我来自一种静态语言,我想知道javascript的风格是什么。

(我希望你通常在前面有一个
var
。-)没有它,你就成了牺牲品。)

除了清楚之外,没有什么真正的惯例。对我来说,“清晰”意味着两件事:

  • 将所有
    var
    语句放在范围的开头,因为

  • 如果某个对象的重要结构不会发生太大变化,那么尽可能早地为其分配一个对象文字(正如您所拥有的)

  • …但是“清晰”对不同的人意味着不同的事情

    在类中的本地数据成员中的用法也是如此。以一个ctor或其他一些集中的方式(为了清晰起见)初始化它们是一种最佳实践吗

    是,初始化构造函数中所有特定于实例的属性。对象可能不需要其自身副本的属性可以驻留在原型上:

    function Foo(bar) {
        this.bar = bar;
        this.baz = [];
    }
    Foo.prototype.datum = 42;
    

    在那里,通过
    new Foo(“x”)
    创建的对象将获得其自己的属性
    bar
    ,其值为
    “x”
    ,其自己的属性
    baz
    的值为
    []
    ,以及继承的属性
    datum
    的值为
    42
    。将这些初始化放在构造函数中,并放在原型旁边,有助于清晰明了。

    通常,如果使用函数定义,可以做更多的工作,以矩形为例

    function Rectangle(width, height){
        this.width = width;
        this.height = height;
    };
    
    Rectangle.prototype.width = 0;
    Rectangle.prototype.height = 0;
    Rectangle.prototype.getArea = function(){
      return this.height * this.width;
    }
    
    var rect = new Rectangle(100, 50);
    
    console.log(rect.width);
    console.log(rect.height);
    console.log(rect.getArea());
    

    通过这种方法,一些IDE支持自动完成,并且您可以操纵内在的对象方法,例如.toString等。如果您觉得您的需求可能会扩展,并且还不太确定性能基准,这是最好的做法,这取决于您希望采取的“最佳做法”的程度.

    如果要将
    选项
    作为参数传递给函数调用,典型的处理方法是尽可能使函数具有所有参数的默认值集,然后将对象文本传递给希望指定选项的函数

    例如,如果
    myFunction
    具有选项
    color
    size
    material
    ,则分配尽可能多的有意义的默认值(例如,默认
    color
    red
    ,默认
    size
    large
    ,默认
    material
    cotton
    )。然后,当您调用
    myFunction()
    时,默认值适用,除非您这样调用它:

    myFunction({color:'blue', material:'suede'});
    
    这里唯一保留的默认值是大小


    这就是jQuery和许多其他库倾向于做选择的方式。

    我建议您
    创建一个单独的generic.js
    文件,该文件将
    导入所有页面
    ,集中所有
    默认选项
    。另外,由于可重用性,它也非常棒(您不需要在需要的时候重新配置相同的东西)。

    对于您的情况来说,这可能有些过分,但是如果您需要,您可以为特定的私有变量创建一个带有getter和setter的构造函数。这个特殊的设置还会在设置前检查设置值是否为数字

    var Options = function(p1, p2){
        var _param1, _param2;
    
        this.get_param1 = function(){
            return _param1;
        };
        this.get_param2 = function(){
            return _param2;
        };
    
        this.set_param1 = function(v){
            if (typeof(v) === 'number') {
                _param1 = v;
                return _param1;
            } else {
                return false;
            }
        };
        this.set_param2 = function(v){
            if (typeof(v) === 'number') {
                _param2 = v;
                return _param2;
            } else {
                return false;
            }
        };
    
        this.set_param1(p1);
        this.set_param2(p2);
    
        return this;
    };
    
    用法如下:

    var options = new Options(1, 2);
    options._param1; // => undefined
    options.get_param1(); // => 1
    options.get_param2(); // => 2
    options.set_param1(3);
    options.get_param1(); // => 3
    options.set_param1('fail');
    options.get_param1(); // => 3
    

    这是一个非常严格的实现,但可能正是您想要的

    有一些方法可以定义类

    // serves as a constructor
    function MyClass(name, id) {
        // init members.
        // this.members are public members
        this.Name = name;
        this.Id = id;
    
        // this is a private member available only in constructor
        var something = 0;
        this.DoSomething = function () {
            // your method
            // here you also can use something here as you have access.
        }
    }
    
    MyClass.prototype = {
        // This also another way to define your methods
        "SomeMethod": function (input) {
            // Do something
            // you don't have access to private members in constructor.
        }
    }
    
    如果您想要更多OOP功能,请进一步

    function AnotherClass (input) {
        // private field
        var someNumber = 0;
        // get accessor
        this.getSomeNumber = function() {
            return someNumber;
        }
        this.setSomeNumber = function(value) {
            if (typeof value != "number" || value != value)
                throw new Error("Your value must be a number");
            someNumber = value;
        }
    }
    
    如果您想要一些静态方法,那么下面就是它们

    var MyThirdClass = (function() {
        var instanceCount = 0;
        function _Constructor() {
            this.Name = "";
            instanceCount++;
        }
        _Constructor.getInstanceCount = function() {
            return instanceCount;
        }
        return _Constructor;
    })();
    
    最后,您可以按如下方式使用它们

    var myClass = new MyClass("Foo", 1);
    myClass.Name = "Bar";
    myClass.DoSomething();
    
    var thirdClass = new MyThirdClass();
    var thirdClassAnotherInstance = new MyThirdClass();
    alert(MyThirdClass.getInstanceCount());