You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.2 KiB
88 lines
2.2 KiB
|
|
module.exports = ProtoList |
|
|
|
function setProto(obj, proto) { |
|
if (typeof Object.setPrototypeOf === "function") |
|
return Object.setPrototypeOf(obj, proto) |
|
else |
|
obj.__proto__ = proto |
|
} |
|
|
|
function ProtoList () { |
|
this.list = [] |
|
var root = null |
|
Object.defineProperty(this, 'root', { |
|
get: function () { return root }, |
|
set: function (r) { |
|
root = r |
|
if (this.list.length) { |
|
setProto(this.list[this.list.length - 1], r) |
|
} |
|
}, |
|
enumerable: true, |
|
configurable: true |
|
}) |
|
} |
|
|
|
ProtoList.prototype = |
|
{ get length () { return this.list.length } |
|
, get keys () { |
|
var k = [] |
|
for (var i in this.list[0]) k.push(i) |
|
return k |
|
} |
|
, get snapshot () { |
|
var o = {} |
|
this.keys.forEach(function (k) { o[k] = this.get(k) }, this) |
|
return o |
|
} |
|
, get store () { |
|
return this.list[0] |
|
} |
|
, push : function (obj) { |
|
if (typeof obj !== "object") obj = {valueOf:obj} |
|
if (this.list.length >= 1) { |
|
setProto(this.list[this.list.length - 1], obj) |
|
} |
|
setProto(obj, this.root) |
|
return this.list.push(obj) |
|
} |
|
, pop : function () { |
|
if (this.list.length >= 2) { |
|
setProto(this.list[this.list.length - 2], this.root) |
|
} |
|
return this.list.pop() |
|
} |
|
, unshift : function (obj) { |
|
setProto(obj, this.list[0] || this.root) |
|
return this.list.unshift(obj) |
|
} |
|
, shift : function () { |
|
if (this.list.length === 1) { |
|
setProto(this.list[0], this.root) |
|
} |
|
return this.list.shift() |
|
} |
|
, get : function (key) { |
|
return this.list[0][key] |
|
} |
|
, set : function (key, val, save) { |
|
if (!this.length) this.push({}) |
|
if (save && this.list[0].hasOwnProperty(key)) this.push({}) |
|
return this.list[0][key] = val |
|
} |
|
, forEach : function (fn, thisp) { |
|
for (var key in this.list[0]) fn.call(thisp, key, this.list[0][key]) |
|
} |
|
, slice : function () { |
|
return this.list.slice.apply(this.list, arguments) |
|
} |
|
, splice : function () { |
|
// handle injections |
|
var ret = this.list.splice.apply(this.list, arguments) |
|
for (var i = 0, l = this.list.length; i < l; i++) { |
|
setProto(this.list[i], this.list[i + 1] || this.root) |
|
} |
|
return ret |
|
} |
|
}
|
|
|