2016-02-28 167 views
3

嘗試爲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

回答

2

您可以使用Object.create來創建對象,然後使用.apply()來應用參數。

if (!(this instanceof Stack)) { 
    var t = Object.create(Stack.prototype); 
    Stack.apply(t, arguments); 
    return t 
} 

我相信ES6允許使用的擴散操作傳遞的參數的集合與new,但是這將涵蓋傳統的瀏覽器。