diff --git a/html/perlito5.js b/html/perlito5.js
index 8f7833a06..8a56d98b3 100644
--- a/html/perlito5.js
+++ b/html/perlito5.js
@@ -13981,8 +13981,15 @@ return (p5call(p5pkg["Perlito5::AST::Apply"]["v__"], "emit_javascript2_set_list"
};
if ( p5bool(p5call(v_arg, "isa", ['Perlito5::AST::Call'], 0)) ) {
if ( (p5str(p5call(v_arg, "method", [], 0)) == 'postcircumfix:<{ }>') ) {
- (function () { throw(p5context([('(' + p5str(p5call(p5call(v_arg, "invocant", [], 0), "emit_javascript2", [], 0)) + ')._hash_.hasOwnProperty(' + p5str(p5call(p5call(p5pkg["Perlito5::AST::Lookup"], "autoquote", p5list_to_a((v_arg || (v_arg = new p5HashRef({})))._hash_.p5hget('arguments')), 0), "emit_javascript2", [v_level], 0)) + ')')], p5want)) })()
- }
+ (function () { throw(p5context([('(' + p5str(p5call(p5call(v_arg, "invocant", [], 0), "emit_javascript2", [], 0)) + ')._hash_.hasOwnProperty(' + p5str(p5call(p5call(p5pkg["Perlito5::AST::Lookup"], "autoquote", p5list_to_a((v_arg || (v_arg = new p5HashRef({})))._hash_.p5hget('arguments')), 0), "emit_javascript2", [v_level], 0)) + ')')], p5want)) })();
+ };
+ };
+ if ( (p5bool(p5call(v_arg, "isa", ['Perlito5::AST::Var'], 0)) && (p5str(p5call(v_arg, "sigil", [], 0)) == '&')) ) {
+ var v_name;
+ v_name = ((v_arg || (v_arg = new p5HashRef({})))._hash_.p5hget('name'));
+ var v_namespace;
+ v_namespace = (p5or((v_arg || (v_arg = new p5HashRef({})))._hash_.p5hget('namespace'), function () { return p5make_package("Perlito5")["v_PKG_NAME"] }));
+ (function () { throw(p5context([('p5pkg[' + p5str(p5pkg["Perlito5::Javascript2"].escape_string([v_namespace], 0)) + '].hasOwnProperty(' + p5str(p5pkg["Perlito5::Javascript2"].escape_string([v_name], 0)) + ')')], p5want)) })()
}
}
catch(err) {
diff --git a/perlito5.pl b/perlito5.pl
index 637a3c6d1..b934b9219 100644
--- a/perlito5.pl
+++ b/perlito5.pl
@@ -9884,6 +9884,11 @@ package Perlito5::AST::Apply;
if (($arg->method() eq 'postcircumfix:<{ }>')) {
return ('(' . $arg->invocant()->emit_javascript2() . ')._hash_.hasOwnProperty(' . Perlito5::AST::Lookup->autoquote($arg->{'arguments'})->emit_javascript2($level) . ')')
}
+ };
+ if (($arg->isa('Perlito5::AST::Var') && ($arg->sigil() eq '&'))) {
+ my $name = $arg->{'name'};
+ my $namespace = ($arg->{'namespace'} || $Perlito5::PKG_NAME);
+ return ('p5pkg[' . Perlito5::Javascript2::escape_string($namespace) . '].hasOwnProperty(' . Perlito5::Javascript2::escape_string($name) . ')')
}
});
sub Perlito5::AST::Apply::emit_javascript2 {
diff --git a/src5/lib/Perlito5/Javascript2/Emitter.pm b/src5/lib/Perlito5/Javascript2/Emitter.pm
index eb7b0681d..cb143a0cd 100644
--- a/src5/lib/Perlito5/Javascript2/Emitter.pm
+++ b/src5/lib/Perlito5/Javascript2/Emitter.pm
@@ -2365,6 +2365,15 @@ package Perlito5::AST::Apply;
return '(' . $arg->invocant->emit_javascript2() . ')._hash_.hasOwnProperty(' . Perlito5::AST::Lookup->autoquote($arg->{arguments})->emit_javascript2($level) . ')';
}
}
+ if ( $arg->isa('Perlito5::AST::Var')
+ && $arg->sigil eq '&'
+ )
+ {
+ # TODO exist() + 'my sub'
+ my $name = $arg->{name};
+ my $namespace = $arg->{namespace} || $Perlito5::PKG_NAME;
+ return 'p5pkg[' . Perlito5::Javascript2::escape_string($namespace) . '].hasOwnProperty(' . Perlito5::Javascript2::escape_string($name) . ')';
+ }
},
);
diff --git a/t5/01-perlito/180-namespace.t b/t5/01-perlito/180-namespace.t
index ed7523495..0e29b5f03 100755
--- a/t5/01-perlito/180-namespace.t
+++ b/t5/01-perlito/180-namespace.t
@@ -4,7 +4,7 @@ use feature 'say';
package Main;
-say '1..6';
+say '1..8';
sub subr { $_[0] + $_[1] };
@@ -53,3 +53,13 @@ say "ok 5";
print "not " unless Mod2::subr4() == 456;
say "ok 6";
+# exists
+
+sub xyz ($$);
+print "not " unless exists &xyz;
+say "ok 7 # exists";
+
+print "not " if exists &abc;
+say "ok 8 # not exists";
+
+