В общем, лучше избегать проектирования структуры таким способом.
Но вы можете сделать это, связав функции events
в конструкторе, что означает создание «собственной» копииобъект событий.См. ***
комментарии в этой версии с минимальными изменениями:
// NOTE: Sticking to ES5 as the OP seems to be doing that
var MyClass = function(number) {
this.number = number || 4;
// *** Bind the functions on `this.events` to `this`
var self = this;
var events = self.events;
self.events = {};
Object.keys(events).forEach(function(key) {
if (typeof events[key] === "function") {
self.events[key] = events[key].bind(self);
}
});
};
// I've added the "name" parameter that's being passed around
// so we can be sure that the results for multiple
// instances are correct
MyClass.prototype = {
constructor: MyClass, // *** Don't break prototype.constructor
run: function(name) {
//direct access to object
console.log(name, "Direct access in object:", this.number);
//access to object with the "self" object
var self = this;
setTimeout(function() {
console.log(name, "In setTimeout callback:", self.number);
}, 1000);
//access to object with the "self" object as a parameter
this.events.test_a(name, self);
//here is the problem
this.events.test_b(name);
},
events: {
test_a: function(name, self) {
//access to object with the "self" object as a parameter
console.log(name, "In test_a:", self.number);
},
test_b: function(name) {
console.log(name, "In test_b:", this.number); // ? Not a problem anymore
}
}
};
//----
var mc1 = new MyClass(110);
var mc2 = new MyClass(220);
setTimeout(function() {
mc1.run("mc1");
}, 1000);
setTimeout(function() {
mc2.run("mc2");
}, 2000);
.as-console-wrapper {
max-height: 100% !important;
}
Примечание: смотрите эту строку, которую я добавил к объекту, который вы назначаете prototype
:
constructor: MyClass, // *** Don't break prototype.constructor
По умолчанию объект prototype
в функции имеет свойство constructor
, указывающее назад на функцию, поэтому лучше всего это сделать.