__proto__ in VariablesView should be smarter

RESOLVED WONTFIX

Status

()

Firefox
Developer Tools: Object Inspector
--
enhancement
RESOLVED WONTFIX
5 years ago
2 days ago

People

(Reporter: benvie, Unassigned)

Tracking

21 Branch
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

5 years ago
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.
(Reporter)

Comment 1

5 years ago
This applies to objects handed as raw objects in `VariablesView.prototype.populate` and in `JSTerm._prototype.fetchVarProperties`.
(Reporter)

Comment 2

5 years ago
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`.
(Reporter)

Updated

5 years ago
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>.
(Reporter)

Comment 4

5 years ago
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.
(Reporter)

Updated

5 years ago
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.
(Reporter)

Comment 6

5 years ago
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;
    }
(Reporter)

Updated

4 years ago
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
Last Resolved: 2 days ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.