1

一般来说,我是 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);
4

2 回答 2

3

从大局来看,是的,你做得很好;好一个。:-) 考虑有关 SO 的其他答案中的示例以获取更多信息和观点。

一些指针,它们都不是 OOP 相关的,只是 JavaScript 相关的:

  1. JavaScript 中压倒性的约定是构造函数(your _name) 最初是有上限的,例如Name(like Dateor RegExp)。

  2. 您在表单_name.prototype.setLastName = function() { ... }中分配的各种函数是分配给具有名称的属性的匿名函数。给你的函数起正确的名字可以帮助你的工具帮助你。一些引擎足够聪明,即使你没有给你的函数命名,也能弄清楚,但其他引擎需要正确的名字。有关示例和/或Anonymouses anonymous ,请参见上面的链接。

  3. 您依赖于在所有函数分配中自动插入分号_name.prototype.setLastName = function() { ... }的恐怖:应该在}. 建议学习规则并始终明确提供分号;当引擎必须猜测时,它可能会猜错,并且当您将它们排除在外时,它会使缩小/压缩/打包变得困难。

  4. 与其到处写,不如_name.prototype.xyz = ...考虑使用范围函数并缓存_name.prototype到更简单的符号,例如:

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

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

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

更多阅读:

于 2012-06-28T23:23:35.463 回答
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 通常在初始化时只被调用一次,因此您可以将它们的代码移动到构造函数中。如果您打算使属性可变,您仍然可以使用构造函数中的验证逻辑调用 setter 函数。

typeof middleName != 'not_defined'

typeof无值变量的运算符的结果是"undefined". 您还应该在修剪之前检查一下。

您的一般代码设计中也可能存在一些缺陷。您对名字、中间名和姓氏使用相同的条件,您应该真正将它们移动到validateString可以从单个设置器(DRY 代码)调用的自己的函数中。同样,验证函数不应该给用户关于输入什么的反馈,它应该只返回false“无效”。用户交互应该由也处理您的输入的模块完成 - 而不是在数据结构模块中。

于 2012-06-28T23:20:57.890 回答