Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2a86650

Browse files
cjihrigaddaleax
authored andcommittedJul 18, 2017
n-api: add napi_has_own_property()
Refs: #13925 PR-URL: #14063 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Franziska Hinkelmann <[email protected]>
1 parent 53c52ac commit 2a86650

File tree

5 files changed

+112
-0
lines changed

5 files changed

+112
-0
lines changed
 

‎doc/api/n-api.md

+24
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,29 @@ Returns `napi_ok` if the API succeeded.
22982298
This API attempts to delete the `key` own property from `object`.
22992299
23002300
2301+
#### *napi_has_own_property*
2302+
<!-- YAML
2303+
added: REPLACEME
2304+
-->
2305+
```C
2306+
napi_status napi_has_own_property(napi_env env,
2307+
napi_value object,
2308+
napi_value key,
2309+
bool* result);
2310+
```
2311+
2312+
- `[in] env`: The environment that the N-API call is invoked under.
2313+
- `[in] object`: The object to query.
2314+
- `[in] key`: The name of the own property whose existence to check.
2315+
- `[out] result`: Whether the own property exists on the object or not.
2316+
2317+
Returns `napi_ok` if the API succeeded.
2318+
2319+
This API checks if the Object passed in has the named own property. `key` must
2320+
be a string or a Symbol, or an error will be thrown. N-API will not perform any
2321+
conversion between data types.
2322+
2323+
23012324
#### *napi_set_named_property*
23022325
<!-- YAML
23032326
added: v8.0.0
@@ -3102,6 +3125,7 @@ support it:
31023125
[`napi_get_element`]: #n_api_napi_get_element
31033126
[`napi_get_property`]: #n_api_napi_get_property
31043127
[`napi_has_property`]: #n_api_napi_has_property
3128+
[`napi_has_own_property`]: #n_api_napi_has_own_property
31053129
[`napi_set_property`]: #n_api_napi_set_property
31063130
[`napi_get_reference_value`]: #n_api_napi_get_reference_value
31073131
[`napi_is_error`]: #n_api_napi_is_error

‎src/node_api.cc

+21
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,27 @@ napi_status napi_delete_property(napi_env env,
10421042
return GET_RETURN_STATUS(env);
10431043
}
10441044

1045+
NAPI_EXTERN napi_status napi_has_own_property(napi_env env,
1046+
napi_value object,
1047+
napi_value key,
1048+
bool* result) {
1049+
NAPI_PREAMBLE(env);
1050+
CHECK_ARG(env, key);
1051+
1052+
v8::Isolate* isolate = env->isolate;
1053+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
1054+
v8::Local<v8::Object> obj;
1055+
1056+
CHECK_TO_OBJECT(env, context, obj, object);
1057+
v8::Local<v8::Value> k = v8impl::V8LocalValueFromJsValue(key);
1058+
RETURN_STATUS_IF_FALSE(env, k->IsName(), napi_name_expected);
1059+
v8::Maybe<bool> has_maybe = obj->HasOwnProperty(context, k.As<v8::Name>());
1060+
CHECK_MAYBE_NOTHING(env, has_maybe, napi_generic_failure);
1061+
*result = has_maybe.FromMaybe(false);
1062+
1063+
return GET_RETURN_STATUS(env);
1064+
}
1065+
10451066
napi_status napi_set_named_property(napi_env env,
10461067
napi_value object,
10471068
const char* utf8name,

‎src/node_api.h

+4
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ NAPI_EXTERN napi_status napi_delete_property(napi_env env,
230230
napi_value object,
231231
napi_value key,
232232
bool* result);
233+
NAPI_EXTERN napi_status napi_has_own_property(napi_env env,
234+
napi_value object,
235+
napi_value key,
236+
bool* result);
233237
NAPI_EXTERN napi_status napi_set_named_property(napi_env env,
234238
napi_value object,
235239
const char* utf8name,

‎test/addons-napi/test_object/test.js

+34
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,40 @@ assert.strictEqual(newObject.test_string, 'test string');
5050
Object.prototype.toString);
5151
}
5252

53+
{
54+
// Verify that napi_has_own_property() fails if property is not a name.
55+
[true, false, null, undefined, {}, [], 0, 1, () => {}].forEach((value) => {
56+
assert.throws(() => {
57+
test_object.HasOwn({}, value);
58+
}, /^Error: A string or symbol was expected$/);
59+
});
60+
}
61+
62+
{
63+
// Verify that napi_has_own_property() does not walk the prototype chain.
64+
const symbol1 = Symbol();
65+
const symbol2 = Symbol();
66+
67+
function MyObject() {
68+
this.foo = 42;
69+
this.bar = 43;
70+
this[symbol1] = 44;
71+
}
72+
73+
MyObject.prototype.bar = 45;
74+
MyObject.prototype.baz = 46;
75+
MyObject.prototype[symbol2] = 47;
76+
77+
const obj = new MyObject();
78+
79+
assert.strictEqual(test_object.HasOwn(obj, 'foo'), true);
80+
assert.strictEqual(test_object.HasOwn(obj, 'bar'), true);
81+
assert.strictEqual(test_object.HasOwn(obj, symbol1), true);
82+
assert.strictEqual(test_object.HasOwn(obj, 'baz'), false);
83+
assert.strictEqual(test_object.HasOwn(obj, 'toString'), false);
84+
assert.strictEqual(test_object.HasOwn(obj, symbol2), false);
85+
}
86+
5387
{
5488
// test_object.Inflate increases all properties by 1
5589
const cube = {

‎test/addons-napi/test_object/test_object.c

+29
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,34 @@ napi_value Has(napi_env env, napi_callback_info info) {
8686
return ret;
8787
}
8888

89+
napi_value HasOwn(napi_env env, napi_callback_info info) {
90+
size_t argc = 2;
91+
napi_value args[2];
92+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
93+
94+
NAPI_ASSERT(env, argc == 2, "Wrong number of arguments");
95+
96+
napi_valuetype valuetype0;
97+
NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
98+
99+
NAPI_ASSERT(env, valuetype0 == napi_object,
100+
"Wrong type of arguments. Expects an object as first argument.");
101+
102+
// napi_valuetype valuetype1;
103+
// NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
104+
//
105+
// NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
106+
// "Wrong type of arguments. Expects a string or symbol as second.");
107+
108+
bool has_property;
109+
NAPI_CALL(env, napi_has_own_property(env, args[0], args[1], &has_property));
110+
111+
napi_value ret;
112+
NAPI_CALL(env, napi_get_boolean(env, has_property, &ret));
113+
114+
return ret;
115+
}
116+
89117
napi_value Delete(napi_env env, napi_callback_info info) {
90118
size_t argc = 2;
91119
napi_value args[2];
@@ -196,6 +224,7 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
196224
DECLARE_NAPI_PROPERTY("Get", Get),
197225
DECLARE_NAPI_PROPERTY("Set", Set),
198226
DECLARE_NAPI_PROPERTY("Has", Has),
227+
DECLARE_NAPI_PROPERTY("HasOwn", HasOwn),
199228
DECLARE_NAPI_PROPERTY("Delete", Delete),
200229
DECLARE_NAPI_PROPERTY("New", New),
201230
DECLARE_NAPI_PROPERTY("Inflate", Inflate),

0 commit comments

Comments
 (0)
Please sign in to comment.