实例化一个没有“新”的类
问题描述:
尝试为Array
创建一个包装类,它用事件侦听器增强它。下面是它的用法的例子:实例化一个没有“新”的类
new Stack(1, 2, 3).on('push', function (length) {
console.log('Length: ' + length + '.');
}).push(4, 5, 6);
这里是我的代码(fiddle):
(function(window, undefined) {
window.Stack = function(stack) {
if (!(this instanceof Stack)) {
throw new TypeError('Stack must be called with the `new` keyword.');
} else {
if (stack instanceof Array) {
this.stack = stack;
} else {
Array.prototype.push.apply(this.stack = [], Array.prototype.slice.call(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);
return this;
},
trigger: function(event, args) {
this.events[event].forEach(function(callback) {
callback.call(this.stack, args);
});
return this;
}
};
'fill pop push reverse shift sort splice unshift concat includes join slice indexOf lastIndexOf forEach every some filter find findIndex reduce'.split(' ').forEach(function(method) {
Stack.prototype.events[method] = [];
Stack.prototype[method] = function() {
return this.trigger(method, this.stack[method].apply(this.stack, this.stack.slice.call(arguments)));
};
});
}(window));
我希望能够实例Stack
不使用new
,平时,我只想做到这一点:
if (!(this instanceof Stack)) {
return new Stack(arguments);
}
但它不在这里工作,因为我本质上是通过arguments
(伪数组)作为第一个参数t ... arguments
。
我该如何做到这一点,所以我可以调用堆栈,而不使用new
?
答
您可以使用Object.create
来创建对象,然后使用.apply()
来应用参数。
if (!(this instanceof Stack)) {
var t = Object.create(Stack.prototype);
Stack.apply(t, arguments);
return t
}
我相信ES6允许使用的扩散操作传递的参数的集合与new
,但是这将涵盖传统的浏览器。