在尝试从已经初始化的伪javascript类中修改“this”对象时遇到了很多麻烦

向下滚动到该post的底部可以看到解决方法。

这可能更容易,只是在源代码中解释与评论。 现在的问题是我不知道如何伪类一起工作来执行我正在尝试做的任务(在下面的代码中解释)。

代码被分解成3个文件:lead.js,router.js和db.js.

有相当数量的代码行,但大部分是评论。

[lead.js] var bcrypt = require('bcrypt'), validators = require('../lib/validators'), utility = require('../lib/utility'), document = {}; var Lead = module.exports = function (db) { // Save a reference to the database. this.db = db; // Reference initial document. // This is totally wrong, not sure how to 'send' a variable to the constructor of a class // when I cannot add another param. Due to how I'm importing the db model, I won't know what // the document is until I fill out the form. I've also tried 'document' instead of 'Lead.document'. this.document = Lead.document; // Setup the document if it exists. // This also doesn't work. // Basically I want to be able to set up a document variable outside of this module (line #100), // Then pass it to this module after filling it up with values from a form. // Then based on what's been filled in, it would fix up (trim, convert to lower case) // some of the values automatically and default a few values that I'm not always going to pass. if (!document) { var salt = bcrypt.genSaltSync(10), hash = bcrypt.hashSync(utility.generatePassword(), salt); // Default values. if (!document.meta.createdAt) { this.document.meta.createdAt = Date.now(); } if (!document.login.password) { this.document.login.password = hash; } if (!document.login.role) { this.document.login.role = 'User'; } // Normalize a few values. this.document.login.email = document.login.email.toLowerCase().trim(); this.document.contact.name.first = document.contact.name.first.trim(); this.document.contact.name.last = document.contact.name.last.trim(); this.document.contact.address.street = document.contact.address.street.trim(); this.document.contact.address.city = document.contact.address.city.trim(); this.document.contact.address.state = document.contact.address.state.trim(); this.document.contact.address.zip = document.contact.address.zip.trim(); this.document.contact.phone.home = document.contact.phone.home.trim(); } // So in regards to the above code, the end result I'm looking for is... // I want to append some properties to the this.document reference when the document is empty (when I'm updating it, I won't set the document), // and on new documents it will append a few default values/normalize all the fields. }; Lead.prototype.validate = function(fn) { var errors = []; // Some validation rules I cut out to make this shorter. if (errors.length) return fn(errors); fn(); }; Lead.prototype.save = function(fn) { this.db.collection('leads', function(err, collection) { if (err) { fn(new Error({message: err})); } collection.insert(this.document, function(err, result) { return fn(err, result); }); }); }; --- [route.js file] var db = require('../models/db'); app.post('/register', function(req, res) { var data = req.body.lead || {}; // Fill the document. var document = { meta: { host: req.headers.host, referer: req.headers.referer, createdIPAddress: req.connection.remoteAddress }, login: { email: data.email }, contact: { name: { first: data.first, last: data.last }, address: { street: data.street, city: data.city, state: data.state, zip: data.zip }, phone: { home: data.phone } } }; // Write the document. db.lead.document = document; db.lead.validate(function(err) { if (err) { req.session.error = err; return res.redirect('back'); } db.lead.save(function(err) { res.redirect('/register/success'); }); }); }); --- [db.js] var mongodb = require('mongodb'), server = new mongodb.Server('localhost', 27017), connection = new mongodb.Db('test', server); connection.open(function(err, db) {}); module.exports = { lead: new (require('./lead'))(connection) }; 

当我运行这个,我的validation器总是报告密码是空的,这是有道理的。 我最初将文档发送到类与一个空密码(密码是随机生成的,而不是一个表单字段) – 问题是我不知道如何处理if(!document)…代码块实际设置这个.document正确。

我希望在评论和代码之间可以了解我正在尝试做什么。 我一直坚持这一点。

编辑

我改变了它的stream程来得到一个解决scheme。

在db.js中,我导出了连接,而不是直接实例化引导(以及未来的模型)。

在router.js文件中,我需要db和lead文件,然后在Lead的构造函数中传递db连接和文档。 防爆。

 var lead = new Lead(db, document); 

在lead.js文件中,就像做这个文档= document一样简单(和db相同)。 当我提交新的潜在客户时,我不会从router.js发送的值被附加到文档(创builddate,随机密码等),一切都很好。

这是一个体面的处理方式,还是有更好的方法来重构呢?

您需要阅读Javascript中的面向对象编程 。

您在代码顶部附近定义的匿名函数构造函数,因此对于您希望目前未初始化的document属性,只需键入如下内容:

 this.document = null; 

然后一段时间,当你使用这个构造函数创build一个新的对象时,就像这样:

 var myLead = new Lead(dbConnection); 

您将拥有myLead.document属性。

不过,你的代码还有许多其他的错误。 你为什么假设在你的库中有一个全局documentvariables,当它被定义为{}时,它的相关数据是可见的? 在你的构造函数末尾的if语句中的代码应该在document属性被设置在下面的其他文件中时运行,并且只应该期望this.document存在。

这是完全错误的方法,即使使这个代码工作,如你所愿。 在这个例子中你有单身主angular。 通过请求/注册URL你想设置“文档”字段到这个单身人士。 (重要)但请求asynchronous工作。 绝对不能保证你保存的文件,只是validation。 因为新的请求可能会覆盖导致对象。 您需要在请求范围内执行此逻辑。 一个请求的范围。 不是一个人。

您最初设置var document = {}{}不是虚假的。 更好的办法是设置一个起始值document = null ,然后在分配任何你需要的属性之前检查!document set document = {}