Mat*_*gan 27 javascript closures commonjs node.js
我想创建模块来构建我的NodeJS应用程序,但我有点迷失,而且我还没有找到任何关于这个主题的完全确定的东西(有几个小时的搜索).
假设我想创建一个"用户"模块,我可以使用以下内容在我的代码中创建新用户:
var newUser = new User();
Run Code Online (Sandbox Code Playgroud)
理想情况下,我需要使用以下代码之类的代码顶部的模块:
var User = require('../lib/user');
Run Code Online (Sandbox Code Playgroud)
这非常有效.问题是,我应该如何构建用户模块?以下是最好的方法吗?
module.exports = function User() {
var authorized = false;
var username = undefined;
var password = undefined;
var statistics = undefined;
this.authorized = function() {
return authorized;
}
this.username = function() {
return username;
}
this.statistics = function() {
return statistics;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在为各种模块变量编写getter和setter,允许我隐藏我不想从其他代码中意外访问的内容.但是,我之前这样做过:
function User() {
this.authStatus = false;
this.email;
this.displayName;
this.inSession;
}
User.prototype.isAuthenticated = function() {
return(this.authStatus && this.email && this.displayName)
}
User.prototype.isInSession = function() {
return(this.inSession && this.isAuthenticated());
}
exports.User = User;
Run Code Online (Sandbox Code Playgroud)
这也有效,但有一点需要注意; 我还没有找到一种从闭包内访问用户属性的方法.如果我的理解是正确的,那么第二个实现,我不能.这意味着如果我需要将一个函数关闭到db库作为回调来编辑用户的属性,我不能.这看起来像:
User.prototype.login = function() {
db.doDbStuff('get user data query', function(_error, _result) {
this.username = _result[0].name; //this code will not work
});
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,代码不起作用,因为"this"关键字在闭包范围内,而不是User.即使代码放在User函数中:
function User() {
this.login = function() { //you know
Run Code Online (Sandbox Code Playgroud)
它不会起作用.
我想我的问题是,这个问题的最佳解决方案是什么?这是我在第一个代码块中提出的方法吗?这似乎相当麻烦和混乱,容易发生变量冲突.我很害怕.
提前致谢!
tim*_*ley 26
我通常采用第二种方法,将函数附加到原型.
你所拥有的变量"无法在闭包中使用"的问题与原型无关.无论你如何构建它,你都会遇到同样的问题.
它与javascript的混乱动态有关this:http:
//robotlolita.me/2011/10/09/understanding-javascript-oop.html#sec-2-1
基本上,你需要做一些事情:
User.prototype.login = function() {
var self = this // bind this to self so you have a reference to what `this` was
db.doDbStuff('get user data query', function(_error, _result) {
self.username = _result[0].name; // self refers to the original `this`, so this works.
});
}
Run Code Online (Sandbox Code Playgroud)
您还可以选择使用function.bind:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
在绑定函数中,值this将是您提供给的任何值.bind(value):
User.prototype.login = function() {
db.doDbStuff('get user data query', (function(_error, _result) {
this.username = _result[0].name; // bind fixes the original `this`, so this also works.
}).bind(this));
}
Run Code Online (Sandbox Code Playgroud)
无论你是使用function.bind还是self = this某种个人品味问题,但是前几天我们在freenode#nodejs做了一些基准测试,发现bind()比它慢了20倍var self = this.
至于你关于如何构建模块的原始问题,有很多例子可以在github上学习.只需找到您喜欢的模块并检查它们的结构.我注意到许多人似乎更喜欢工厂而不是直接暴露构造函数(例如require('module').create()).你的来电.
Mal*_*k13 12
作为一种不同的方法,我是以下模式的粉丝.
module.exports = function User(data) {
//this properly private stuff.
var privateVar;
var username = data.username;
var pass = data.pass; //etc
function privateFunc() {
}
return {
login: function(cb) {
db.doStuff(username, pass, cb);
}
};
};
| 归档时间: |
|
| 查看次数: |
35736 次 |
| 最近记录: |