Understanding ECMAScript Specification: Object.prototype.hasOwnProperty and Abstract Operations
This article explains how the ECMAScript specification defines the behavior of Object.prototype.hasOwnProperty, introduces abstract operations, completion records, internal slots and methods, and shows how the spec’s pseudo‑code can be translated into concrete JavaScript examples.
The purpose of this translation is to propose translations for core terms in the ECMAScript specification for enthusiasts.
In this article we pick a simple feature from the spec to illustrate how the specification’s notation works. Let’s begin!
Preface
Even if you know JavaScript, reading its specification can be intimidating.
We start with a concrete example and then use the spec to understand it. The following code demonstrates the usage of Object.prototype.hasOwnProperty :
const o = { foo: 1 };
o.hasOwnProperty(
'foo'
); //
true
o.hasOwnProperty(
'bar'
); //
falseThe object o does not have a property named hasOwnProperty , so the prototype chain is consulted. The method is found on Object.prototype .
To describe how Object.prototype.property works, the spec uses a pseudo‑code style description:
Object.prototype.hasOwnProperty(V) When the method hasOwnProperty is called with argument V , the following steps are performed: 1. Let P be ?ToPropertyKey(V); 2. Let O be ?ToObject(this value); 3. Return ?HasOwnProperty(O, P).
The abstract operation HasOwnProperty(O, P) determines whether object O has an own property whose key is P . It returns a Boolean value wrapped in a completion record.
HasOwnProperty(O, P) Abstract operation HasOwnProperty is used to determine if an object has an own property with the given key. It takes O (the object) and P (the property key) as arguments. The algorithm proceeds as follows: 1. Assert Type(O) is Object; 2. Assert IsPropertyKey(P) is true; 3. Let desc be ?O.[[GetOwnProperty]](P); 4. If desc is undefined, return false; 5. Return true.
Language Types and Specification Types
The spec uses values such as undefined , true and false , which are language values defined by the spec.
The spec also defines its own "specification types" that do not exist in JavaScript itself, such as Records and Completion Records.
Abstract Operations
Abstract operations are functions defined by the ECMAScript spec to keep the spec concise. JavaScript engines are not required to implement them directly, and they cannot be called from ordinary JavaScript code.
Internal Slots and Internal Methods
Internal slots and internal methods are stored in the [[...]] fields of objects. For example, every JavaScript object has an internal slot [[Prototype]] and an internal method [[GetOwnProperty]] . These cannot be accessed directly from JavaScript code.
Completion Records
A Completion Record is a specification‑only type that represents the result of an abstract operation. It has three fields: [[Type]] , [[Value]] , and [[Target]] . Normal completions are wrapped in a NormalCompletion record, while abrupt completions carry a [[Type]] of throw and an exception object in [[Value]] .
The helper ReturnIfAbrupt(argument) implements the common pattern of propagating abrupt completions: if argument is an abrupt completion, return it; otherwise extract argument.[[Value]] and continue.
The shorthand ? is equivalent to ReturnIfAbrupt(...) , and ! extracts the value from a normal completion.
Assertions
Assertions in the spec state conditions that are guaranteed to hold; they are for documentation only and need not be checked by implementations.
Challenge
Abstract operations may delegate to other abstract operations. By following the explanations above you should be able to infer what each operation ultimately does, including handling of Property Descriptors.
Summary
We examined the simple method Object.prototype.hasOwnProperty , the abstract operation it relies on, the meaning of the ? and ! shorthands for error handling, and introduced language types, specification types, internal slots, and internal methods.
References
[1]
Language values: https://tc39.es/ecma262/#sec-ecmascript-language-types
[2]
Specification types: https://tc39.es/ecma262/#sec-ecmascript-specification-types
[3]
Abstract operations: https://tc39.es/ecma262/#sec-abstract-operations
[4]
Internal slots and methods: https://tc39.es/ecma262/#sec-object-internal-methods-and-internal-slots
[5]
Essential internal methods: https://tc39.es/ecma262/#table-5
[6]
Completion records: https://tc39.es/ecma262/#sec-completion-record-specification-type
[7]
Implicit completion values: https://tc39.es/ecma262/#sec-implicit-completion-values
[8]
Question‑mark shorthand: https://tc39.es/ecma262/#sec-returnifabrupt-shorthands
[9]
Original article: https://v8.dev/blog/understanding-ecmascript-part-1
Follow " ByteFE " for more front‑end content.
Click to read the original article and join us!
ByteFE
Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.