Closed Bug 982099 Opened 7 years ago Closed 3 years ago

PlacesTransaction.jsm: Subclass arrays and be nice at the same time


(Toolkit :: Places, defect, P1)




Tracking Status
firefox56 --- fixed


(Reporter: mano, Assigned: mak)



(Whiteboard: [fxsearch])


(1 file)

In the new PlacesTransaction.jsm I'm "subclassing" the native js-array in order to implement the TransactionsHistory object: adding methods, getters etc. No matter how I used all those ES5/6 techniques for doing so, the result wasn't very readable (it looked more like meta-programming, and that, of course, applies to the Proxies trick as well). At last, I decided not to be nice so the code could be, and used the old __proto__ hack:

let TransactionsHistory = [];
TransactionsHistory.__proto__ = {
  __proto__: Array.prototype,

I recall there's some upcoming ES6 API for making this task less painful (maybe it was an alternative to Object.defineProperties that takes a JS object and clones it. I'm not sure).

So I'm filing this bug for replacing the __proto__ there when/if a better way is available.
How about doing:

function TransactionsHistory() {}

TransactionsHistory.prototype = Object.create(Array.prototype);

TransactionsHistory.prototype.myFunction = function () {
  // ...
This doesn't work because you must use the native array constructor, and you cannot just call it on another object.

I think Object.assign (bug 937855) is the API I was thinking of.
and the problem with the assignment isn't with functions but with getters. Object.definePropert[y|ies] is one ugly API for day-to-day use. Moreover, I tend to prefer having my implementation "contained" in their object literals. I know it doesn't matter (they end being set the same way on the same object) and I know it's very JS-ish to do myObj.aFunc = ... myObj.b = ..., but I honestly don't like it. However, if defining getters worked that way, I'd do that here.
Bug 838540 is about the "proper" solution, but it doesn't seem like anything is happening over there.
I found a little more information about subclassing arrays that might be useful:
The sandbox trick is clever, isn't it? (that is, in the context of privileged code we could use Componets.utils.Sandbox for adopting the iframe trick suggested there)
The iframe trick is clever but seems very hacky to me, not sure we would want to do that. BTW, bug 948227 has landed recently that warns about the perf impact of using __proto__.
Priority: -- → P3
Assignee: nobody → mak77
Priority: P3 → P1
Whiteboard: [fxsearch]
Comment on attachment 8882767 [details]
Bug 982099 - Properly extend Array in PlacesTransaction.jsm.

Attachment #8882767 - Flags: review?(standard8) → review+
Pushed by
Properly extend Array in PlacesTransaction.jsm. r=standard8
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
You need to log in before you can comment on or make changes to this bug.