不知道你为什么需要这个,但我对最佳实践的建议是:
- 不要覆盖
Array.prototype
. 这样做的原因是因为其他库可能会尝试做同样的事情,如果你将这些库包含到你的库中,就会发生冲突。
- 不需要此代码。
var a= [], r=new Array(a);
. 你只需要a = [];
......
- 确保您正在创建一个真实的课程。在您的代码中,
makeDeque
没有做您想做的事。它返回this
的是当一个函数没有被new
关键字调用时将与window
对象相同(或者undefined
如果你使用的是所谓的“严格模式”)。换句话说,你做了很多全局变量(这通常是禁忌,因为它们也可能与其他代码冲突)。
- 当您构建一个类时,最好将其添加到
prototype
您的自定义类中。这是因为这些方法只会被构建到内存中一次,并且将被所有此类对象共享。
所以我会首先重构成这样的东西:
var makeDeque = (function() { // We don't need this wrapper in this case, as we don't have static properties, but I've kept it here since we do want to encapsulate variables in my example below this one (and sometimes you do need static properties).
function makeDeque () {
if (!(this instanceof makeDeque)) { // This block allows you to call makeDeque without using the "new" keyword (we will do it for the person using makeDeque)
return new makeDeque();
}
this.r = [];
this.length = 0;
}
makeDeque.prototype.setLength = function () {
return this.length = this.r.length;
};
makeDeque.prototype.pushHead=function(v) {
this.r.unshift(v);
this.setLength();
};
makeDeque.prototype.popHead=function() {
return this.r.shift();
this.setLength();
};
makeDeque.prototype.pushTail=function(v){
this.r.push(v);
this.setLength();
};
makeDeque.prototype.popTail=function() {
return this.r.pop();
this.setLength();
};
makeDeque.prototype.isEmpty=function() {
return this.r.length === 0;
};
return makeDeque;
}());
现在您可以将其缩短如下,但我不建议这样做,因为正如 Donald Knuth 所说的那样,“过早的优化是万恶之源”。如果你试图缩短你的代码,它可能会变得不灵活。
var makeDeque = (function() {
function makeDeque () {
if (!(this instanceof makeDeque)) {
return new makeDeque();
}
this.r = [];
this.length = 0;
}
makeDeque.prototype.setLength = function () {
return this.length = this.r.length;
};
for (var i=0, methodArray = [
['pushHead', 'unshift'], ['popHead', 'shift'], ['pushTail', 'push'], ['popTail', 'pop']
]; i < methodArray.length; i++) {
makeDeque.prototype[methodArray[i][0]] = (function (i) { // We need to make a function and immediately pass in 'i' here because otherwise, the 'i' inside this function will end up being set to the value of 'i' after it ends this loop as opposed to the 'i' which varies with each loop. This is a common "gotcha" of JavaScript
return function () {
var ret = this.r[methodArray[i][1]].apply(this.r, arguments);
this.setLength();
return ret;
};
}(i));
}
makeDeque.prototype.isEmpty=function() {
return this.r.length === 0;
};
return makeDeque;
}());
如果您需要通过length
属性获取长度,而不是像 setLength() 这样在每次更新后手动设置它的方法,上述代码示例都可以通过避免使用 setLength() 方法来缩短,但您需要在 IE < 9 等较旧的浏览器中使用Object.defineProperty
which 不起作用(或不能完全起作用)。