NJS_DEF_STRING(global, "global", 0, 0)
NJS_DEF_STRING(globalThis, "globalThis", 0, 0)
NJS_DEF_STRING(groups, "groups", 0, 0)
+NJS_DEF_STRING(hasOwn, "hasOwn", 0, 0)
NJS_DEF_STRING(hasOwnProperty, "hasOwnProperty", 0, 0)
NJS_DEF_STRING(hasInstance, "hasInstance", 0, 0)
NJS_DEF_STRING(hypot, "hypot", 0, 0)
njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
static njs_int_t njs_object_set_prototype(njs_vm_t *vm, njs_object_t *object,
const njs_value_t *value);
+static njs_int_t njs_object_prototype_has_own_property(njs_vm_t *vm,
+ njs_value_t *args, njs_uint_t nargs, njs_index_t magic,
+ njs_value_t *retval);
njs_object_t *
NJS_DECLARE_PROP_NATIVE(STRING_assign, njs_object_assign, 2, 0),
NJS_DECLARE_PROP_NATIVE(STRING_is, njs_object_is, 2, 0),
-};
+ NJS_DECLARE_PROP_NATIVE(STRING_hasOwn,
+ njs_object_prototype_has_own_property, 2, 1),
+};
const njs_object_init_t njs_object_constructor_init = {
njs_object_constructor_properties,
static njs_int_t
njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args,
- njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
+ njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
{
njs_int_t ret;
njs_value_t *value, *property, lvalue;
njs_property_query_t pq;
- property = njs_lvalue_arg(&lvalue, args, nargs, 1);
+ if (magic == 0) {
+ /* hasOwnProperty. */
- if (njs_slow_path(!njs_is_key(property))) {
- ret = njs_value_to_key(vm, property, property);
- if (njs_slow_path(ret != NJS_OK)) {
+ property = njs_lvalue_arg(&lvalue, args, nargs, 1 + magic);
+ if (njs_slow_path(!njs_is_key(property))) {
+ ret = njs_value_to_key(vm, property, property);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+ }
+
+ value = njs_argument(args, magic);
+ if (njs_is_null_or_undefined(value)) {
+ njs_type_error(vm, "cannot convert %s argument to object",
+ njs_type_string(value->type));
return NJS_ERROR;
}
- }
- value = njs_argument(args, 0);
+ } else {
+ /* hasOwn. */
- if (njs_is_null_or_undefined(value)) {
- njs_type_error(vm, "cannot convert %s argument to object",
- njs_type_string(value->type));
- return NJS_ERROR;
+ value = njs_lvalue_arg(&lvalue, args, nargs, magic);
+ if (njs_is_null_or_undefined(value)) {
+ njs_type_error(vm, "cannot convert %s argument to object",
+ njs_type_string(value->type));
+ return NJS_ERROR;
+ }
+
+ property = njs_lvalue_arg(&lvalue, args, nargs, 1 + magic);
+ if (njs_slow_path(!njs_is_key(property))) {
+ ret = njs_value_to_key(vm, property, property);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+ }
}
njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
{ njs_str("Object.prototype.hasOwnProperty('hasOwnProperty')"),
njs_str("true") },
+ { njs_str("var o = {a:1}; Object.hasOwn(o, 'a')"),
+ njs_str("true") },
+
+ { njs_str("var o = Object.create({a:2}); Object.hasOwn(o, 'a')"),
+ njs_str("false") },
+
+ { njs_str("var o = {a:1}; Object.hasOwn(o, 'b')"),
+ njs_str("false") },
+
+ { njs_str("var o = Object.create(null); o.a = 1; Object.hasOwn(o, 'a')"),
+ njs_str("true") },
+
+ { njs_str("var o = Object.create(null); Object.hasOwn(o, 'hasOwnProperty')"),
+ njs_str("false") },
+
+ { njs_str("var o = {hasOwnProperty: 1}; Object.hasOwn(o, 'hasOwnProperty')"),
+ njs_str("true") },
+
+ { njs_str("var o = {a:1}; o.hasOwnProperty = function(){return false}; "
+ "Object.hasOwn(o, 'a')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn(null, 'a')"),
+ njs_str("TypeError: cannot convert null argument to object") },
+
+ { njs_str("Object.hasOwn(undefined, 'a')"),
+ njs_str("TypeError: cannot convert undefined argument to object") },
+
+ { njs_str("Object.hasOwn(1, 'toString')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn('abc', '0')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn('abc', '3')"),
+ njs_str("false") },
+
+ { njs_str("Object.hasOwn('abc', 'length')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn([1,2], '0')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn([,2], '0')"),
+ njs_str("false") },
+
+ { njs_str("Object.hasOwn([,2], '1')"),
+ njs_str("true") },
+
+ { njs_str("Object.hasOwn([], 'length')"),
+ njs_str("true") },
+
+ { njs_str("var s = Symbol('test'); var o = {}; o[s] = 1; Object.hasOwn(o, s)"),
+ njs_str("true") },
+
+ { njs_str("var s1 = Symbol('test'); var s2 = Symbol('test'); "
+ "var o = {}; o[s1] = 1; Object.hasOwn(o, s2)"),
+ njs_str("false") },
+
+ { njs_str("Object.hasOwn({}, Symbol.iterator)"),
+ njs_str("false") },
+
+ { njs_str("Object.hasOwn()"),
+ njs_str("TypeError: cannot convert ") },
+
+ { njs_str("Object.hasOwn({})"),
+ njs_str("false") },
+
+ { njs_str("var o = {}; Object.hasOwn(o)"),
+ njs_str("false") },
+
+ { njs_str("Object.hasOwn.length"),
+ njs_str("2") },
+
+ { njs_str("Object.hasOwn.name"),
+ njs_str("hasOwn") },
+
{ njs_str("var o = {};"
"Object.defineProperty(o, 'a', {get:undefined, set:undefined}).a"),
njs_str("undefined") },