[Project_owners] Defining new array methods (SeaMonkey vsFirefox).

Peter B. Shalimoff vshalim at home.ru
Fri Jun 23 14:49:48 EDT 2006


Philip Chee wrote:
> I tried your workaround:
> But I'm still getting these errors. Help?

That for-in loop must be placed _after_ you're done adding your own
functions to Array.prototype. Anyway, that workaround is not really good,
because it brings (a little) overhead. Instead of looping through properties
of Array.prototype, it's better to define substr() method once - in
Object.prototype:

Object.prototype.substr = function(){return "...";};

Now every object will have substr() method, and there's no overhead for
looping. I rewrote my code as shown above, but I was too mad to think at the
time I found that mess.

As to why this happens, I suggest to read the ECMAScript spec, sections
"8.6.1 Property Attributes" and "8.6.2.2 [[Put]] (P, V)". In brief:
user-defined properties (e.g. your inArray prop) don't have DontEnum
attribute, so they are enumerated in a for-in loop. Default properties of
built-in JS objects do have DontEnum attribute set, so they are skipped by a
for-in loop.

Line numbers in my TODO comment are given for Mozilla 1.7.12 and FF 1.5.0.1.
Here's piece of navigator.js:

// Pref listener constants
const gButtonPrefListener =
{
  domain: "browser.toolbars.showbutton",
  init: function()
  {
    var array = pref.getChildList(this.domain, {}); // line 79
    for (var i in array)
      this.updateButton(array[i]); // line 81
    this.updateSeparator();
  },
  observe: function(subject, topic, prefName)
  {
    // verify that we're changing a button pref
    if (topic != "nsPref:changed")
      return;

    this.updateButton(prefName);
    this.updateSeparator();
  },
  updateButton: function(prefName)
  {
    var buttonName = prefName.substr(this.domain.length+1); // line 95
    var buttonId = buttonName + "-button";

In line 79 we have an Array instance returned from getChildList(). Then we
enter for-in loop, and, since inArray property don't have DontEnum
attribute, it gets enumerated. So we call updateButton() passing it a
reference to the inArray function instead of a string. And since functions
don't have substr() method, there's an exception thrown.

--
0xdeadbeef



More information about the Project_owners mailing list