Closed Bug 866334 Opened 11 years ago Closed 7 years ago

__proto__ in VariablesView should be smarter

Categories

(DevTools :: Object Inspector, enhancement)

21 Branch
enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: bbenvie, Unassigned)

References

Details

Right now '__proto__' claims to never be writable; this is usually incorrect and is misleading. It should probably do something smarter to determine actual writability. A basic check might be `'__proto__' in obj`. A more accurate but inefficient check would involve recursing the object's prototype chain until finding the first ancestor that has an own '__proto__' property and checking the descriptor for a setter.
This applies to objects handed as raw objects in `VariablesView.prototype.populate` and in `JSTerm._prototype.fetchVarProperties`.
Actually, it might be better to solve this is in a different way. `__proto__` is now much more close to a regular property:

    js> Object.getOwnPropertyDescriptor(Object.prototype, '__proto__')
        { configurable: true,
          enumerable: false,
          get: [object Function],
          set: [object Function] }
    js> Object.prototype.hasOwnProperty('__proto__')
        true
    js> ({}).hasOwnProperty('__proto__')
        false
    js> '__proto__' in {}
        true

The only thing magical about '__proto__' is that it isn't reported when you do `Object.getOwnPropertyNames(Object.prototype)`.


The problem is that we've hijacked the '__proto__' property to indicate `[[Prototype]]` in the VariablesView. This is even more problematic for objects that actually have a '__proto__' property; instead of showing the actual '__proto__' property, it continues to use it to show the object's [[Prototype]].

    js> x = Object.defineProperty({}, '__proto__', { value: 5 })
        { __proto__: [object Object] } // incorrectly showing Object.prototype

    js> x.__proto__
        5


What we need is a way to show the [[Prototype]] and distinguish it from a regular property, since it's not a regular property; it's something that can only reliably be accessed using `Object.getPrototypeOf`.
Depends on: 866877
Picking __proto__ as the prototype label may have been an unfortunate choice on my part, but that's what every other tool is using. Using [[Prototype]] might be a better choice, albeit unfamiliar to some users.

As for distinguishing it from a regular property, I think the double brackets should suffice. We are using a similar trick for displaying an exception being thrown, using the label <exception>.
Yeah, until recently '__proto__' was perfectly acceptable, because it was a very magical property. But the way it's being standardized in ES6 makes it into basically a non-magical regular property, so it's not really sufficient to overload its use anymore.

Using '[[Prototype]]' maybe be fine, but see bug 866877 in regards to the generalized need to display non-property object information. I think in the future it may be useful to have a non-textual differentiation for these kinds of special attributes, because I think over time we may want to add more.

Another example, aside from [[Prototype]] and [[MapData]], might be [[BoundTargetFunction]] for functions resulting from `.bind`, or [[Scope]] for the scope chain of a function. While the brackets may be sufficient, it still allows for the possibility for collisions with actual regular properties. The solution that covers all edge cases requires some other distinction.
Summary: __proto__ in VariablesView should be smarter about whether it's writable → __proto__ in VariablesView should be smarter
double brackets or even a special header within the Object in the VariablesView. I suppose those are just presentation, but we should visually identify them as important.
Also note that fixing this would require working around bug 837630 until it's fixed ('__proto__' is not visible to Object.keys/Object.getOwnPropertyNames). That can be implemented like:

    function getActualOwnPropertyNames(o){
      let names = Object.getOwnPropertyNames(o);
      if (Object.getPrototypeOf(o) === null
          && {}.hasOwnProperty.call(o, '__proto__')) {
        names.push('__proto__');
      }
      return names;
    }
Component: Developer Tools → Developer Tools: Object Inspector
Severity: normal → enhancement
Won't be fixed in the VariableView. We have an issue for the ObjectInspector: https://github.com/devtools-html/devtools-core/issues/651
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.