Skip to content

Commit aa0f8c0

Browse files
committed
feat: add Object::GetPrototype and Object::SetPrototype
Fixes: #1691
1 parent af7d42e commit aa0f8c0

File tree

5 files changed

+72
-0
lines changed

5 files changed

+72
-0
lines changed

doc/object.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,28 @@ from being added to it and marking all existing properties as non-configurable.
241241
Values of present properties can still be changed as long as they are
242242
writable.
243243

244+
### GetPrototype()
245+
246+
```cpp
247+
Napi::Object Napi::Object::GetPrototype() const;
248+
```
249+
250+
The `Napi::Object::GetPrototype()` method returns the prototype of the object.
251+
252+
### SetPrototype()
253+
254+
```cpp
255+
bool Napi::Object::SetPrototype(const Napi::Object& value) const;
256+
```
257+
258+
- `[in] value`: The prototype value.
259+
260+
The `Napi::Object::SetPrototype()` method sets the prototype of the object.
261+
262+
**NOTE**: The support for `Napi::Object::SetPrototype` is only available when
263+
using `NAPI_EXPERIMENTAL` and building against Node.js headers that support this
264+
feature.
265+
244266
### operator\[\]()
245267
246268
```cpp

napi-inl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,19 @@ inline MaybeOrValue<bool> Object::Seal() const {
19661966
}
19671967
#endif // NAPI_VERSION >= 8
19681968

1969+
inline MaybeOrValue<Object> Object::GetPrototype() const {
1970+
napi_value result;
1971+
napi_status status = napi_get_prototype(_env, _value, &result);
1972+
NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Object(_env, result), Object);
1973+
}
1974+
1975+
#ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
1976+
inline MaybeOrValue<bool> Object::SetPrototype(const Object& value) const {
1977+
napi_status status = node_api_set_prototype(_env, _value, value);
1978+
NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1979+
}
1980+
#endif
1981+
19691982
////////////////////////////////////////////////////////////////////////////////
19701983
// External class
19711984
////////////////////////////////////////////////////////////////////////////////

napi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,12 @@ class Object : public TypeTaggable {
11181118
/// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
11191119
MaybeOrValue<bool> Seal() const;
11201120
#endif // NAPI_VERSION >= 8
1121+
1122+
MaybeOrValue<Object> GetPrototype() const;
1123+
1124+
#ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
1125+
MaybeOrValue<bool> SetPrototype(const Object& value) const;
1126+
#endif
11211127
};
11221128

11231129
template <typename T>

test/object/object.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,19 @@ Value InstanceOf(const CallbackInfo& info) {
343343
return Boolean::New(info.Env(), MaybeUnwrap(obj.InstanceOf(constructor)));
344344
}
345345

346+
Value GetPrototype(const CallbackInfo& info) {
347+
Object obj = info[0].UnsafeAs<Object>();
348+
return MaybeUnwrap(obj.GetPrototype());
349+
}
350+
351+
#ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
352+
Value SetPrototype(const CallbackInfo& info) {
353+
Object obj = info[0].UnsafeAs<Object>();
354+
Object prototype = info[1].UnsafeAs<Object>();
355+
return Boolean::New(info.Env(), MaybeUnwrap(obj.SetPrototype(prototype)));
356+
}
357+
#endif // NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
358+
346359
Object InitObject(Env env) {
347360
Object exports = Object::New(env);
348361

@@ -426,5 +439,10 @@ Object InitObject(Env env) {
426439
Function::New(env, SubscriptSetWithCppStyleString);
427440
exports["subscriptSetAtIndex"] = Function::New(env, SubscriptSetAtIndex);
428441

442+
exports["getPrototype"] = Function::New(env, GetPrototype);
443+
#ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
444+
exports["setPrototype"] = Function::New(env, SetPrototype);
445+
#endif // NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
446+
429447
return exports;
430448
}

test/object/object.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,17 @@ function test (binding) {
215215
c: 3
216216
});
217217
}
218+
219+
{
220+
const prototype = {};
221+
const obj = Object.create(prototype);
222+
assert.strictEqual(binding.object.getPrototype(obj), prototype);
223+
}
224+
225+
if ('setPrototype' in binding.object) {
226+
const prototype = {};
227+
const obj = Object.create(null);
228+
assert.strictEqual(binding.object.setPrototype(obj, prototype), true);
229+
assert.strictEqual(Object.getPrototypeOf(obj), prototype);
230+
}
218231
}

0 commit comments

Comments
 (0)