Javascript 如何编写面向对象的Node.js模型

Javascript 如何编写面向对象的Node.js模型,javascript,node.js,oop,Javascript,Node.js,Oop,我在Node.js中编写面向对象的Cat类时遇到了很多麻烦。如何编写Cat.js类并按以下方式使用它: // following 10 lines of code is in another file "app.js" that is outside // the folder "model" var Cat = require('./model/Cat.js'); var cat1 = new Cat(12, 'Tom'); cat1.setAge(100); console.log(ca

我在Node.js中编写面向对象的Cat类时遇到了很多麻烦。如何编写Cat.js类并按以下方式使用它:

// following 10 lines of code is in another file "app.js" that is outside 
// the folder "model"
var Cat = require('./model/Cat.js');

var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge()); // prints out 100 to console

var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2)); // prints out false

var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1)); // prints out True
如何修复我编写的以下Cat.js类:

 var Cat = function() {
    this.fields = {
        age: null,
        name: null
    };

    this.fill = function (newFields) {
        for(var field in this.fields) {
            if(this.fields[field] !== 'undefined') {
                this.fields[field] = newFields[field];
            }
        }
    };

    this.getAge = function() {
        return this.fields['age'];
    };

    this.getName = function() {
        return this.fields['name'];
    };

    this.setAge = function(newAge) {
        this.fields['age'] = newAge;
    };

    this.equals = function(otherCat) {
        if (this.fields['age'] === otherCat.getAge() && 
            this.fields['name'] === otherCat.getName())  {
            return true;
        } else {
            return false;
        }
    };
};

module.exports = function(newFields) {
    var instance = new Cat();
    instance.fill(newFields);
    return instance;
};

我会使用TypeScript:

class Cat{
    fields = {
        age: null,
        name: null
    };

    fill(newFields) {
        for(var field in this.fields) {
            if(this.fields[field] !== 'undefined') {
                this.fields[field] = newFields[field];
            }
        }
    }

    getAge() {
        return this.fields.age;
    }

    setAge(newAge:number) {
        this.fields.age = newAge;
    }
}

export = Cat;


TypeScript可以在NodeJ和浏览器中使用

这里的Person.js代码运行良好

  exports.person=function(age,name)
    {
        age=age;
        name=name;
        this.setAge=function(agedata)
        {
           age=agedata;
        }
        this.getAge=function()
        {
            return age;
        }
        this.setName=function(name)
        {
            name=name;
        }
        this.getName=function()
        {
            return name;
        }

};
调用对象代码:

var test=require('./route/person.js');
var person=test.person;
var data=new person(12,'murugan');
data.setAge(13);
console.log(data.getAge());
data.setName('murugan');
console.log(data.getName());

如果我设计一个像这样的物体,那么我会这样做

function Cat(age, name) {       // Accept name and age in the constructor
    this.name = name || null;
    this.age  = age  || null;
}

Cat.prototype.getAge = function() {
    return this.age;
}

Cat.prototype.setAge = function(age) {
    this.age = age;
}

Cat.prototype.getName = function() {
    return this.name;
}

Cat.prototype.setName = function(name) {
    this.name = name;
}

Cat.prototype.equals = function(otherCat) {
    return otherCat.getName() == this.getName()
        && otherCat.getAge() == this.getAge();
}

Cat.prototype.fill = function(newFields) {
    for (var field in newFields) {
        if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
            if (this[field] !== 'undefined') {
                this[field] = newFields[field];
            }
        }
    }
};

module.exports = Cat;     // Export the Cat function as it is
var Cat = require("./Cat.js");

var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge());                 // 100

var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2));             // false

var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1));       // true

var sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2));       // false

sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2));       // true
然后它可以像这样使用

function Cat(age, name) {       // Accept name and age in the constructor
    this.name = name || null;
    this.age  = age  || null;
}

Cat.prototype.getAge = function() {
    return this.age;
}

Cat.prototype.setAge = function(age) {
    this.age = age;
}

Cat.prototype.getName = function() {
    return this.name;
}

Cat.prototype.setName = function(name) {
    this.name = name;
}

Cat.prototype.equals = function(otherCat) {
    return otherCat.getName() == this.getName()
        && otherCat.getAge() == this.getAge();
}

Cat.prototype.fill = function(newFields) {
    for (var field in newFields) {
        if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
            if (this[field] !== 'undefined') {
                this[field] = newFields[field];
            }
        }
    }
};

module.exports = Cat;     // Export the Cat function as it is
var Cat = require("./Cat.js");

var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge());                 // 100

var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2));             // false

var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1));       // true

var sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2));       // false

sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2));       // true

在@thefourtheye的回答中有错误循环漏洞,我将在下面描述这些漏洞

对象建模规则

  • 创建空的新对象

  • 创建填充对象

  • 机器/代码只能设置初始对象

  • 初始对象分配后,对象中的任何更改都只能通过用户交互进行

  • 在初始对象分配之后,在没有用户意图的情况下按代码对对象进行的任何更改都会添加一些bug

问题用例:

因此,当您创建填充对象时,如果任何属性(somedate)没有任何值,则由于下面的代码,将默认值指定给它(somedate),这违反了对象建模规则

  • 错误
  • 构造函数被赋予创建新函数的双重责任 &他在创建填充对象时混合的填充对象,以及 它会犯错误
  • 这意味着你的应用程序中有一些错误代码,它将自行设置值,而用户无意中这样做

    函数Cat(age,name,somedate){//接受构造函数中的name和age
    this.name=name | | null;
    this.age=age | | null;
    this.somedate=somedate | | | new Date();//将有很多这样的用例
    }

为了解决这个问题,我使用下面的JavaScript数据模型。

因此,它允许用户仅在需要填充对象或新对象时,才有意识地创建填充对象或新对象,而不必相互干扰

类Cat{
构造函数(){
this.name=null;
this.age=null;
}
初始模型(数据){
this.name=data.name;
this.age=data.age
}
getAge(){返回this.age;}
setAge(age){this.age=age;}
getName(){this.name;}
setName(name){this.name=name;}
等于(其他类别){
返回otherCat.getName()==this.getName()
&&otherCat.getAge()==this.getAge();
}
填充(新字段){
for(新字段中的let字段){
if(this.hasOwnProperty(字段)和&newFields.hasOwnProperty(字段)){
如果(此[字段]!==“未定义”){
此[字段]=新字段[字段];
}
}
}
};
}
设cat1=新的Cat();
cat1.initModel({age:12,name:'Tom'})
cat1.设置(100);
console.log(cat1.getAge());//100
设cat2=新的Cat();
cat2.initModel({age:100,名称:'Jerry'})
console.log(cat1.equals(cat2));//假的
让sameAsCat1=新猫({年龄:100,名字:'Tom'});
sameAsCat1.initModel({age:100,名称:'Tom'})
console.log(cat1.equals(sameAsCat1));//真的
让sameAsCat2=新的Cat();
console.log(cat2.equals(sameAsCat2));//假的
sameAsCat2.fill({姓名:“Jerry”,年龄:100});

log(cat2.equals(sameAsCat2))这是否是唯一的问题,我不能说,但您想测试
typeof()!='在
fill
函数中未定义“
。因为你给它们赋值
null
值,所以无论如何都不会成功,因为你会在
typeof
上得到'object'。如果您只是将它们指定为未定义的,并通过
typeof()
进行测试,则它的行为应该与您预期的一样。您需要帮助的具体问题是什么?您可能想看看。它是可靠的,并且提供了您可能梦想的所有OO功能,除了简单自然的语法中的多重继承。@Chingy我假设您的。尝试使用
=
而不是
=
:),或者现在在ES6中使用更好的方法。我来给出相同的答案,并看到了这个-4答案,天哪。怎么了?