Skip to content

Commit 56dae7f

Browse files
Added Object.hasOwn().
1 parent 2322b7d commit 56dae7f

File tree

3 files changed

+115
-12
lines changed

3 files changed

+115
-12
lines changed

src/njs_atom_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ NJS_DEF_STRING(getMonth, "getMonth", 0, 0)
286286
NJS_DEF_STRING(global, "global", 0, 0)
287287
NJS_DEF_STRING(globalThis, "globalThis", 0, 0)
288288
NJS_DEF_STRING(groups, "groups", 0, 0)
289+
NJS_DEF_STRING(hasOwn, "hasOwn", 0, 0)
289290
NJS_DEF_STRING(hasOwnProperty, "hasOwnProperty", 0, 0)
290291
NJS_DEF_STRING(hasInstance, "hasInstance", 0, 0)
291292
NJS_DEF_STRING(hypot, "hypot", 0, 0)

src/njs_object.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ static njs_int_t njs_object_define_properties(njs_vm_t *vm, njs_value_t *args,
3131
njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
3232
static njs_int_t njs_object_set_prototype(njs_vm_t *vm, njs_object_t *object,
3333
const njs_value_t *value);
34+
static njs_int_t njs_object_prototype_has_own_property(njs_vm_t *vm,
35+
njs_value_t *args, njs_uint_t nargs, njs_index_t magic,
36+
njs_value_t *retval);
3437

3538

3639
njs_object_t *
@@ -2274,8 +2277,10 @@ static const njs_object_prop_init_t njs_object_constructor_properties[] =
22742277
NJS_DECLARE_PROP_NATIVE(STRING_assign, njs_object_assign, 2, 0),
22752278

22762279
NJS_DECLARE_PROP_NATIVE(STRING_is, njs_object_is, 2, 0),
2277-
};
22782280

2281+
NJS_DECLARE_PROP_NATIVE(STRING_hasOwn,
2282+
njs_object_prototype_has_own_property, 2, 1),
2283+
};
22792284

22802285
const njs_object_init_t njs_object_constructor_init = {
22812286
njs_object_constructor_properties,
@@ -2590,27 +2595,47 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
25902595

25912596
static njs_int_t
25922597
njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args,
2593-
njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
2598+
njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
25942599
{
25952600
njs_int_t ret;
25962601
njs_value_t *value, *property, lvalue;
25972602
njs_property_query_t pq;
25982603

2599-
property = njs_lvalue_arg(&lvalue, args, nargs, 1);
2604+
if (magic == 0) {
2605+
/* hasOwnProperty. */
26002606

2601-
if (njs_slow_path(!njs_is_key(property))) {
2602-
ret = njs_value_to_key(vm, property, property);
2603-
if (njs_slow_path(ret != NJS_OK)) {
2607+
property = njs_lvalue_arg(&lvalue, args, nargs, 1 + magic);
2608+
if (njs_slow_path(!njs_is_key(property))) {
2609+
ret = njs_value_to_key(vm, property, property);
2610+
if (njs_slow_path(ret != NJS_OK)) {
2611+
return NJS_ERROR;
2612+
}
2613+
}
2614+
2615+
value = njs_argument(args, magic);
2616+
if (njs_is_null_or_undefined(value)) {
2617+
njs_type_error(vm, "cannot convert %s argument to object",
2618+
njs_type_string(value->type));
26042619
return NJS_ERROR;
26052620
}
2606-
}
26072621

2608-
value = njs_argument(args, 0);
2622+
} else {
2623+
/* hasOwn. */
26092624

2610-
if (njs_is_null_or_undefined(value)) {
2611-
njs_type_error(vm, "cannot convert %s argument to object",
2612-
njs_type_string(value->type));
2613-
return NJS_ERROR;
2625+
value = njs_lvalue_arg(&lvalue, args, nargs, magic);
2626+
if (njs_is_null_or_undefined(value)) {
2627+
njs_type_error(vm, "cannot convert %s argument to object",
2628+
njs_type_string(value->type));
2629+
return NJS_ERROR;
2630+
}
2631+
2632+
property = njs_lvalue_arg(&lvalue, args, nargs, 1 + magic);
2633+
if (njs_slow_path(!njs_is_key(property))) {
2634+
ret = njs_value_to_key(vm, property, property);
2635+
if (njs_slow_path(ret != NJS_OK)) {
2636+
return NJS_ERROR;
2637+
}
2638+
}
26142639
}
26152640

26162641
njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);

src/test/njs_unit_test.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15108,6 +15108,83 @@ static njs_unit_test_t njs_test[] =
1510815108
{ njs_str("Object.prototype.hasOwnProperty('hasOwnProperty')"),
1510915109
njs_str("true") },
1511015110

15111+
{ njs_str("var o = {a:1}; Object.hasOwn(o, 'a')"),
15112+
njs_str("true") },
15113+
15114+
{ njs_str("var o = Object.create({a:2}); Object.hasOwn(o, 'a')"),
15115+
njs_str("false") },
15116+
15117+
{ njs_str("var o = {a:1}; Object.hasOwn(o, 'b')"),
15118+
njs_str("false") },
15119+
15120+
{ njs_str("var o = Object.create(null); o.a = 1; Object.hasOwn(o, 'a')"),
15121+
njs_str("true") },
15122+
15123+
{ njs_str("var o = Object.create(null); Object.hasOwn(o, 'hasOwnProperty')"),
15124+
njs_str("false") },
15125+
15126+
{ njs_str("var o = {hasOwnProperty: 1}; Object.hasOwn(o, 'hasOwnProperty')"),
15127+
njs_str("true") },
15128+
15129+
{ njs_str("var o = {a:1}; o.hasOwnProperty = function(){return false}; "
15130+
"Object.hasOwn(o, 'a')"),
15131+
njs_str("true") },
15132+
15133+
{ njs_str("Object.hasOwn(null, 'a')"),
15134+
njs_str("TypeError: cannot convert null argument to object") },
15135+
15136+
{ njs_str("Object.hasOwn(undefined, 'a')"),
15137+
njs_str("TypeError: cannot convert undefined argument to object") },
15138+
15139+
{ njs_str("Object.hasOwn(1, 'toString')"),
15140+
njs_str("true") },
15141+
15142+
{ njs_str("Object.hasOwn('abc', '0')"),
15143+
njs_str("true") },
15144+
15145+
{ njs_str("Object.hasOwn('abc', '3')"),
15146+
njs_str("false") },
15147+
15148+
{ njs_str("Object.hasOwn('abc', 'length')"),
15149+
njs_str("true") },
15150+
15151+
{ njs_str("Object.hasOwn([1,2], '0')"),
15152+
njs_str("true") },
15153+
15154+
{ njs_str("Object.hasOwn([,2], '0')"),
15155+
njs_str("false") },
15156+
15157+
{ njs_str("Object.hasOwn([,2], '1')"),
15158+
njs_str("true") },
15159+
15160+
{ njs_str("Object.hasOwn([], 'length')"),
15161+
njs_str("true") },
15162+
15163+
{ njs_str("var s = Symbol('test'); var o = {}; o[s] = 1; Object.hasOwn(o, s)"),
15164+
njs_str("true") },
15165+
15166+
{ njs_str("var s1 = Symbol('test'); var s2 = Symbol('test'); "
15167+
"var o = {}; o[s1] = 1; Object.hasOwn(o, s2)"),
15168+
njs_str("false") },
15169+
15170+
{ njs_str("Object.hasOwn({}, Symbol.iterator)"),
15171+
njs_str("false") },
15172+
15173+
{ njs_str("Object.hasOwn()"),
15174+
njs_str("TypeError: cannot convert ") },
15175+
15176+
{ njs_str("Object.hasOwn({})"),
15177+
njs_str("false") },
15178+
15179+
{ njs_str("var o = {}; Object.hasOwn(o)"),
15180+
njs_str("false") },
15181+
15182+
{ njs_str("Object.hasOwn.length"),
15183+
njs_str("2") },
15184+
15185+
{ njs_str("Object.hasOwn.name"),
15186+
njs_str("hasOwn") },
15187+
1511115188
{ njs_str("var o = {};"
1511215189
"Object.defineProperty(o, 'a', {get:undefined, set:undefined}).a"),
1511315190
njs_str("undefined") },

0 commit comments

Comments
 (0)