我正在编写JS面向对象的代码吗?

时间:2012-06-28 23:12:10

标签: javascript oop

我是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);

2 个答案:

答案 0 :(得分:3)

总的来说,是的,你做得很好;好一个。 :-)考虑this other answer on SO中的示例以获取更多信息和观点。

一些指针,其中没有一个与OOP相关,只与JavaScript相关:

  1. JavaScript中压倒性的惯例是构造函数(您的_name)最初被限制,例如: Name(例如DateRegExp)。

  2. _name.prototype.setLastName = function() { ... }形式分配的各种功能是分配给具有名称的属性的匿名功能。为您的函数指定正确的名称可以帮助您的工具。有些引擎足够智能,即使你没有提供你的函数名称也能解决它,但其他引擎需要适当的名称。请参阅上面的链接以获取示例,和/或Anonymouses anonymous

  3. 您依赖于所有功能分配中automatic semicolon insertion的恐怖:_name.prototype.setLastName = function() { ... }应以}后面的分号结尾。建议学习规则并始终明确提供分号;当发动机必须猜测时,它可能会猜错,并且当你把它们熄灭时会使缩小/压缩/打包变得困难。

  4. 不要在所有地方写_name.prototype.xyz = ...,而是考虑使用范围函数并将_name.prototype缓存到更简单的符号,例如:

    (function(p) {
        p.setLastName = function() {
            // ...
        };
    
        p.xyz = function() {
            // ...
        };
    })(_name.prototype);
    

    ...或使用比这更进一步的辅助函数。只是为了减少击键和脚本大小。

  5. 但是,总的来说,是的,你是在正确的轨道上。

    更多阅读:

答案 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“无效”。用户交互应该由也处理输入的模块完成 - 而不是在数据结构模块中。