我的代码中的许多函数都使用这种结构:
options = {"param1": "yes", "param2" : "no"}
在JS中,我不必“定义”这种结构,因为它是一种动态语言。
但是当我知道结构有一组固定的字段时,为了清晰起见,以集中的方式声明它是最佳做法吗?对于类中的本地数据成员的使用也是如此。以ctor或其他集中方式(为了清晰)初始化所有这些是最佳做法吗?
我知道我可以在评论中这样做但是来自静态语言我想知道什么是javascript风格。
答案 0 :(得分:2)
(我希望你通常在前面有一个var
。:-)如果没有一个,你就会成为The Horror Of Implicit Globals的牺牲品。)
除了明确之外,没有真正的惯例。对于 me ,“明确”意味着一些事情:
将所有var
语句放在范围的开头,因为that's where they really are anyway。
如果某些内容具有不会发生太大变化的重要结构,请尽早为其指定一个对象文字(如您所愿)。
......但“明确”对不同的人来说意味着不同的事情。
同样适用于类中的本地数据成员。以ctor或其他集中方式(为了清晰)初始化所有这些是最佳做法吗?
是,初始化构造函数中所有特定于实例的属性。对象可能不需要自己的副本的属性可以驻留在原型上:
function Foo(bar) {
this.bar = bar;
this.baz = [];
}
Foo.prototype.datum = 42;
在那里,通过new Foo("x")
创建的对象将获得其拥有的属性bar
,其值为"x"
,它是拥有的属性baz
的值为[]
,继承的属性datum
的值为42
。将这些初始化放在构造函数和原型旁边有助于明确。
答案 1 :(得分: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());
使用这种方法,某些IDE支持自动完成,您可以操作内部对象方法,例如.toString等。如果您认为您的需求可能会扩展,那么最佳做法是这样做,而不是太确定性能基准测试,这取决于如何你想要采取“最佳实践”。
答案 2 :(得分:1)
如果您将options
作为参数传递给函数调用,处理此问题的典型方法是使您的函数尽可能为所有参数设置一组默认值,然后传递一个对象文字到你想要指定选项的函数中。
例如,如果myFunction
包含选项color
,size
和material
,请指定尽可能多的默认值(例如,默认color
为{ {1}},默认red
为size
,默认large
为material
)。然后当你拨打cotton
默认值时,除非你这样称呼它:
myFunction()
此处保留的唯一默认值为size。
这就是jQuery和许多其他库倾向于做选择的方式。
答案 3 :(得分: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.
}
}
此外,如果您想要更多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());
答案 4 :(得分:0)
我会recommend
你create a separate generic .js
文件imported in all pages
,集中所有default options
。它也很棒,因为reusability
(你不需要在你需要的时候重新配置相同的东西)。
答案 5 :(得分:0)
对于您的情况,这可能有点过分,但如果您需要,可以使用针对特定私有变量的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
这是一个非常严格的实现,但可能正是您正在寻找的。