{"action":"created","issue":{"url":"https://api.github.com/repos/tc39/ecma262/issues/1110","repository_url":"https://api.github.com/repos/tc39/ecma262","labels_url":"https://api.github.com/repos/tc39/ecma262/issues/1110/labels{/name}","comments_url":"https://api.github.com/repos/tc39/ecma262/issues/1110/comments","events_url":"https://api.github.com/repos/tc39/ecma262/issues/1110/events","html_url":"https://github.com/tc39/ecma262/issues/1110","id":298781634,"number":1110,"title":"The usage of the term \"key\" is ambiguous in relation to object properties","user":{"login":"ogwh","id":35018496,"avatar_url":"https://avatars3.githubusercontent.com/u/35018496?v=4","gravatar_id":"","url":"https://api.github.com/users/ogwh","html_url":"https://github.com/ogwh","followers_url":"https://api.github.com/users/ogwh/followers","following_url":"https://api.github.com/users/ogwh/following{/other_user}","gists_url":"https://api.github.com/users/ogwh/gists{/gist_id}","starred_url":"https://api.github.com/users/ogwh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ogwh/subscriptions","organizations_url":"https://api.github.com/users/ogwh/orgs","repos_url":"https://api.github.com/users/ogwh/repos","events_url":"https://api.github.com/users/ogwh/events{/privacy}","received_events_url":"https://api.github.com/users/ogwh/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-02-20T23:00:50Z","updated_at":"2018-02-21T02:46:04Z","closed_at":null,"author_association":"NONE","body":"It seems there are (at least) two definitions of the term \"key\" within the specification that are not differentiated/explicitly defined.\r\n\r\nThe most common definition is summarised as: an object property identifier of type string or symbol.\r\nFor discussion I'll call this *pid* (for property ID).\r\n\r\nThe other definition is more traditional: a string that serves to identify an object in a hash table/map.\r\nFor discussion I'll call this *hid* (for hash table ID).\r\n\r\nWhere this generates confusion relates to the common usage of an object as a key/value store. In that use case a key is a *hid*. In all other use cases a key is a *pid*. This ambiguity is propagated throughout the language itself, with some functions on Object using one definition and others using the other without remark.\r\n\r\nSome examples of Object functions that use *pid* (those that include symbol keys):\r\n\r\n- assign: Assigns all properties including symbols\r\n- create: Second param defines properties, including symbol properties\r\n- defineProperty and defineProperties: self-explanatory\r\n- seal: also seals symbol properties\r\n\r\nSome examples of Object functions that use *hid*:\r\n\r\n- keys: Only returns keys that are of type string\r\n- entries: Only returns key-value pairs where the keys are strings\r\n- values: Only returns values whose keys are strings\r\n\r\nThe above lists cover a good number of functions but they're not exhaustive.\r\n\r\nNote that the documentation for those three functions on MDN states that all enumerable properties are included, but this is not the case. It's necessary to read the spec to see that these functions only include string keys currently (which is unrealistic to expect from everyone, however desirable).\r\n\r\nFor convenience this MDN page links to all functions on Object: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object\r\n\r\nAside from the MDN documentation this has also caused confusion for the Typescript contributors (which is how I became aware of the problem):\r\n\r\nDifficulty deciding on the correct type of the return value of Object.keys: https://github.com/Microsoft/TypeScript/pull/12253#issuecomment-263132208\r\n\r\nAmbiguity causing the TS *keyof* keyword to be implemented using the *hid* definition of a key rather than the *pid* definition. Any change to which would now cause breaking changes to all Typescript programs: https://github.com/Microsoft/TypeScript/issues/20721 and https://github.com/Microsoft/TypeScript/issues/21983\r\n\r\nIn short it seems that the dual use of Object as both a hash table and as the base \"object\" type has generated (and will likely continue to generate) confusion because it's so easy to overlook.\r\n\r\nFor specifics with references to a few relevant parts of the ECMA specification itself see my comment on this issue here: https://github.com/Microsoft/TypeScript/issues/21983#issuecomment-366237751\r\n\r\nOne potential solution would be to support overloading of the indexing operator in classes, add this to Map and change the *hid* functions of Object to *pid* functions. However that would not be backwards compatible so I'm not really sure how this could be resolved? We may be stuck with it indefinitely but at least the spec can be updated to caution on the ambiguity?"},"comment":{"url":"https://api.github.com/repos/tc39/ecma262/issues/comments/367196021","html_url":"https://github.com/tc39/ecma262/issues/1110#issuecomment-367196021","issue_url":"https://api.github.com/repos/tc39/ecma262/issues/1110","id":367196021,"user":{"login":"domenic","id":617481,"avatar_url":"https://avatars0.githubusercontent.com/u/617481?v=4","gravatar_id":"","url":"https://api.github.com/users/domenic","html_url":"https://github.com/domenic","followers_url":"https://api.github.com/users/domenic/followers","following_url":"https://api.github.com/users/domenic/following{/other_user}","gists_url":"https://api.github.com/users/domenic/gists{/gist_id}","starred_url":"https://api.github.com/users/domenic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/domenic/subscriptions","organizations_url":"https://api.github.com/users/domenic/orgs","repos_url":"https://api.github.com/users/domenic/repos","events_url":"https://api.github.com/users/domenic/events{/privacy}","received_events_url":"https://api.github.com/users/domenic/received_events","type":"User","site_admin":false},"created_at":"2018-02-21T02:46:04Z","updated_at":"2018-02-21T02:46:04Z","author_association":"MEMBER","body":"While I think these distinctions might make sense for a type system, I don't think they make sense for a language specification."}}
{"actor":{"display_login":"domenic"}}