我是Javascript和面向对象编程的新手。我想知道在编写JS OOP代码时是否遵循最佳实践。
这里我创建了一个名为_name的类,并为它提供了一些属性以及一个对象this.details。然后我使用原型设计为类创建方法。
//define _name class (I use _ to easily recognize classes)
function _name () {
this.firstName = '';
this.lastName = '';
this.middleName = '';
this.details = {
eyeColor: '',
hairColor: ''
}
}
//begin _name methods
_name.prototype.getFullName = function() {
return this.firstName + ' ' + this.middleName + ' ' + this.lastName;
}
_name.prototype.setFirstName = function(firstName) {
if ($.trim(firstName).length && typeof firstName != 'not_defined') {
this.firstName = firstName;
} else {
alert('Please enter a valid first name.');
}
}
_name.prototype.setLastName = function(lastName) {
if ($.trim(lastName).length && typeof lastName != 'not_defined') {
this.lastName = lastName;
} else {
alert('Please enter a valid last name.');
}
}
_name.prototype.setMiddleName = function(middleName) {
if ($.trim(middleName).length && typeof middleName != 'not_defined') {
this.middleName = middleName;
} else {
alert('Please enter a valid middle name.');
}
}
_name.prototype.setHairColor = function(hairColor) {
this.details.hairColor = hairColor;
}
_name.prototype.setEyeColor = function(eyeColor) {
this.details.eyeColor = eyeColor;
}
//end _name methods
var personOne = new _name();
personOne.setFirstName('John');
personOne.setLastName('Doe');
personOne.setMiddleName('Barry');
personOne.setEyeColor('Brown');
personOne.setHairColor('Black');
document.write(personOne.getFullName());
document.write(personOne.details.eyeColor);
document.write(personOne.details.hairColor);
答案 0 :(得分:3)
总的来说,是的,你做得很好;好一个。 :-)考虑this other answer on SO中的示例以获取更多信息和观点。
一些指针,其中没有一个与OOP相关,只与JavaScript相关:
JavaScript中压倒性的惯例是构造函数(您的_name
)最初被限制,例如: Name
(例如Date
或RegExp
)。
以_name.prototype.setLastName = function() { ... }
形式分配的各种功能是分配给具有名称的属性的匿名功能。为您的函数指定正确的名称可以帮助您的工具。有些引擎足够智能,即使你没有提供你的函数名称也能解决它,但其他引擎需要适当的名称。请参阅上面的链接以获取示例,和/或Anonymouses anonymous。
您依赖于所有功能分配中automatic semicolon insertion的恐怖:_name.prototype.setLastName = function() { ... }
应以}
后面的分号结尾。建议学习规则并始终明确提供分号;当发动机必须猜测时,它可能会猜错,并且当你把它们熄灭时会使缩小/压缩/打包变得困难。
不要在所有地方写_name.prototype.xyz = ...
,而是考虑使用范围函数并将_name.prototype
缓存到更简单的符号,例如:
(function(p) {
p.setLastName = function() {
// ...
};
p.xyz = function() {
// ...
};
})(_name.prototype);
...或使用比这更进一步的辅助函数。只是为了减少击键和脚本大小。
但是,总的来说,是的,你是在正确的轨道上。
更多阅读:
答案 1 :(得分:0)
一些意见:
我使用_轻松识别类
标准是使用大写的名称作为构造函数。下划线用于暗示变量或属性的隐私 - 即它们是公开的,但不应使用。
var personOne = new _name();
personOne.setFirstName('John');
personOne.set...
通常你会使用构造函数的参数:
function Name (first, last, middle, eye, hair) {
this.firstName = first;
this.lastName = last;
this.middleName = middle;
this.details = {
eyeColor: eye,
hairColor: hair
}
}
var personOne = new Name('John', 'Doe', 'Barry', 'Brown', 'Black');
初始化时,通常只会调用一次setter,因此您可以将其代码移动到construtor函数中。如果您打算使属性可更改,您仍然可以使用构造函数中的验证逻辑调用setter函数。
typeof middleName!='not_defined'
无值变量的typeof
运算符的结果是"undefined"
。你也应该在修剪之前检查一下。
您的通用代码设计中也可能存在一些缺陷。您对第一个,中间名和姓氏使用相同的条件,您应该将它们移动到一个自己的validateString
函数中,该函数可以从单个setter(DRY代码)调用。同样,验证功能不应该向用户提供有关输入内容的反馈,它应该只返回false
“无效”。用户交互应该由也处理输入的模块完成 - 而不是在数据结构模块中。