Ваш пример кода не идиоматическое Node JS.
я настоятельно рекомендую вам следовать рекомендациям лучших практик при создании новых наследуемых объектов, как:
var util=require('util');
var EventEmitter = require('events').EventEmitter;
var Account = function(){
EventEmitter.call(this); // should be first
this.balance=0; // instance var
};
util.inherits(Account,EventEmitter);
Account.prototype.deposit = function(amount){
this.balance += amount;
this.emit('balanceChanged');
};
Account.prototype.withdraw = function(amount){
this.balance -= amount;
this.emit('balanceChanged');
};
var account = new Account();
var displayBalance = function(){
console.log("Account balance : $%d", this.balance);
};
account.on('balanceChanged',displayBalance);
account.deposit(200);
account.withdraw(40);
// ... etc. ....
, при выполнении которой отображается:
Account balance : $200
Account balance : $160
Лучшие практики там так, что
- Ваш код может быть выражен таким образом, чтобы его было легко понять
- вы не сталкиваетесь с неожиданными проблемами при попытке реплицировать уже определенные функциональные возможности, возможно сложные и трудные для понимания.
Причина, по которой существует util.inherits
, заключается в том, что вам не нужно беспокоиться о том, как создается цепочка прототипов. Создав его самостоятельно, вы часто сталкиваетесь с проблемой, с которой вы столкнулись.
Кроме того, поскольку в настоящее время выполнения узла (> 6,0) также включает в себя большую часть спецификации ES6, вы можете (и действительно нужно) написать код, как:
const util = require('util');
const EventEmitter = require('events').EventEmitter;
const Account =() => {
EventEmitter.call(this);
this.balance = 0;
};
util.inherits(Account,EventEmitter);
Account.prototype.deposit = (val) => {
this.balance += val;
this.emit('balanceChanged');
};
Account.prototype.withdraw = (val) => {
this.balance -= val;
this.emit('balanceChanged');
};
Использование ключевого слова уверяет const
создаваемые вами переменные не могут быть изменены непреднамеренно или неожиданно.
И использование определения функции идиомы «жира стрелка» (() => {}
) является более емким и, следовательно, быстрее набирать, но и несет в себе дополнительное преимущество, что она сохраняет значение this
от окружающего контекста, так что вы никогда не должны написать что-то вроде:
Account.prototype.doSomething = function() {
var self = this;
doSomething(val, function(err,res){
if(err) {
throw err;
}
self.result=res;
});
};
, который, используя «жирную стрелку» построить становится:
Account.prototype.doSomething =() => {
doSomething(val, (err,res) => {
if(err) {
throw err;
}
this.result=res; // where 'this' is the instance of Account
});
};
«жирную стрелка» идиома также позволяет сделать некоторые вещи более лаконично, как:
// return the result of a single operation
const add = (a,b) => a + b;
// return a single result object
const getSum = (a,b) => {{a:a,b:b,sum:a+b}};
Другой способ создания наследуемые «классов» в ES6 является использование его строительства класса обозначения:
const EventEmitter = require('events');
class Account extends EventEmitter {
constructor() {
super();
this._balance = 0; // start instance vars with an underscore
}
get balance() { // and add a getter
return this._balance;
}
deposit(amount) {
this._balance += amount;
this.emit('balanceChanged');
}
withdraw(amount) {
this._balance -= amount;
this.emit('balanceChanged');
}
}
Следует отметить, что оба способа построения наследуемые прототипичный объектов действительно то же самое, за исключением того, что идиома нового класса добавляет синтаксический «сахар», чтобы принести декларацию в соответствие с другими языками, которые поддерживают более классическую ориентацию объекта.
Расширения ES6 к узлу предлагают много других преимуществ, заслуживающих изучения.
http://stackoverflow.com/documentation/node.js/1623/event-emitters/5254/basics#t=201608300859206033451 или вы можете использовать 'function Account (...) {...}; util.inherits (Acount, require ('events')); ' –
Я думаю * proto * в' Account.prototype.proto = events.EventEmitter.prototype; ', должен быть' __proto__': 'Account.prototype .__ proto __ = events.EventEmitter.prototype; '. Конечно, @AikonMogwai заявлял, что проще использовать * util.inherits * в узле для наследования. – dNitro