Trying to create a wrapper class for Array, implementing event listeners. Previously, I used a static list of Array
methods, but now I want it to be dynamic, so I'm trying to loop over Array.prototype. After searching Google for a bit, I found one on this site that said to use Object.getOwnPropertyNames, which does work... kind of. Here's my code. Debugging the properties works, but doesn't in practice.
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.Stack = factory();
}
}(this || window || {}, function() {
var Stack = function(stack) {
if (!(this instanceof Stack)) {
var self = Object.create(Stack.prototype);
Stack.apply(self, arguments);
return self;
} else {
if (stack instanceof Array) {
if (arguments.length > 1) {
Array.prototype.concat.apply(this.stack = [], arguments);
} else {
this.stack = stack;
}
} else if (Object.prototype.toString.call(stack) === '[object Object]') {
this.stack = [];
if (arguments.length > 1) {
for (var i = 0; i < arguments.length; i++) {
for (var j in arguments[i]) {
if (arguments[i].hasOwnProperty(j)) {
this.stack.push(arguments[i][j]);
}
}
}
} else {
for (var key in stack) {
if (stack.hasOwnProperty(j)) {
this.stack.push(stack[key]);
}
}
}
} else {
Array.prototype.push.apply(this.stack = [], arguments);
}
Array.prototype.push.apply(this, this.stack);
this.length = this.stack.length;
}
};
Stack.prototype = {
events: {},
on: function(event, callback) {
this.events[event].push(callback.bind(this.stack));
return this;
},
trigger: function(event, args) {
this.events[event].forEach(function(callback) {
callback(args);
});
return this;
},
off: function(event, callback) {
this.events[event].splice(this.events[event].indexOf(callback), 1);
return this;
}
};
var proto = Object.getOwnPropertyNames(Array.prototype),
method;
for (method in proto) {
method = proto[method];
if (typeof Array.prototype[method] === 'function') {
Stack.prototype.events[method] = [];
Stack.prototype[method] = function() {
return this.trigger(method, Array.prototype[method].apply(this.stack, arguments));
}
}
}
return Stack;
}));
method
, when logged, gives the name of the method, and one can then access the function itself with Array.prototype[method], but the following example does not work and used to when I was using a list.
Stack(1, 2, 3).on('push', function (length) {
console.log('Length: ' + length + '.');
}).push(4, 5, 6);
Am I not accessing the prototypical methods correctly? How would I get this to function dynamically?