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

3

我的代码中有很多函数都使用了以下结构:

options = {"param1": "yes", "param2" : "no"}

在JS中,由于它是一种动态语言,我不需要“定义”这个结构。
但是当我知道该结构有一组固定字段时,为了清晰起见,将其集中声明是否是最佳实践?同样适用于在类的本地数据成员中使用。是否最好在构造函数或其他集中方式中初始化所有这些数据成员(以便更清晰)?
我知道我可以在注释中做到这一点,但来自静态语言,我想知道JavaScript风格是什么。
6个回答

2
(我希望你通常在前面加上 var 。 :-)如果没有,你就会陷入隐式全局变量的恐怖。)

除了清晰明了之外,没有真正的约定。对于来说,“清晰明了”意味着以下几点:

  1. 将所有var语句放在作用域的开头,因为它们本来就在那里

  2. 如果某些内容具有不会经常更改的重要结构,请尽早使用对象文字(如您所做)进行分配。

但是,“清晰明了”对不同的人意味着不同的事情。

对于类中的本地数据成员的使用也是一样。在构造函数或其他集中方式中初始化所有这些属性是否是最佳实践(以便清晰明了)?

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

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

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


1

通常情况下,如果您使用函数定义,您可以做更多的事情,以矩形为例。

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());

采用这种方法,一些集成开发环境支持自动完成,并且您可以操作内在对象方法,例如.toString等。如果您觉得您的需求可能会扩展,最好采用这种做法,但是关于性能基准测试还不太确定,这取决于您想要采用多高的“最佳实践”。


1

如果你将options作为参数传递给函数调用,通常的处理方式是让你的函数在可能的情况下拥有所有参数的默认值,然后在你想要指定选项的地方将一个对象字面量传递到函数中。

例如,如果myFunction有选项colorsizematerial,则分配尽可能多的默认值(例如,默认colorred,默认sizelarge,默认materialcotton)。然后当你调用myFunction()时,除非你这样调用它,否则默认值将应用:

myFunction({color:'blue', material:'suede'});

这里唯一保留的默认值将是大小。

这就是jQuery和许多其他库处理选项的方式。


1

定义类的方式有很多种。

// 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.
    }
}

如果您需要更多的面向对象编程功能

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());

0

这可能对你的情况来说有些过度,但如果你想的话,你可以创建一个构造函数,用于获取和设置特定的私有变量。这个特定的函数还会在设置之前检查设置的值是否为数字。

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

这是一个非常严格的实现,但可能是你正在寻找的。


0
我建议您创建一个单独的通用 .js 文件,并将其导入到所有页面中,集中所有默认选项。这样做的好处是它具有可重用性(您不需要每次需要时重新配置相同的内容)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接