JavaScriptでは予約語やkeywordを識別子(変数名)に使える状況が多々あります(過言)。どういう事でしょうか?
予約語
識別子として使用不可なものは break
,case
,catch
,class
,const
,continue
,debugger
,default
,delete
,do
,else
,export
,extends
,false
,finally
,for
,function
,if
,import
,in
,instanceof
,new
,null
,return
,super
,switch
,this
,throw
,true
,try
,typeof
,var
,void
,while
,with
。
それに加え厳格("use strict")な場所で使用不可になるものは let
、static
、yield
。
let
はlet
やconst
で宣言する時とclass定義内でも予約語。
static
はclass定義内でも予約語。
yield
はGenerator関数本体でも予約語。
//let
function _(){var let=0}
function _(){let let=0}//error
function _(){const let=0}//error
function _(){"use strict";var let=0}//error
class _{constructor(){var let=0}}//error
//yield
function _(){var yield=0}
function*_(){var yield=0}//error
function _(){"use strict";var yield=0}//error
//static
var static=0;
function _(){"use strict";var static=0}//error
class _{constructor(){var static=0}}//error
await
は非同期関数内やmodule内で予約語。
function _(){var await=0}
async function _(){var await=0}//error
<script type=module>
var await=0//error
</script>
特別な識別子
arguments
、as
、async
、eval
、fom
、get
、of
、set
はkeywordでなくても、ある文脈で特別な意味を持つ
実践編
of祭り
let of=[of=>of=>of];
for(of of of)of(of)(of);
for([]of[]);
for([]of[,]);//error
async祭り
let async=async function async(async=async=>async){return++async}
object
//化石Browserでは動作しかねる
let a={let:0,var:0,const:0,function:0,return:0,
do:0,for:0,while:0,break:0,continue:0,
with:0,if:0,else:0,try:0,catch:0,finally:0,
switch:0,case:0,default:0,
class:0,extends:0,debugger:0,super:0,
new:0,delete:0,in:0,instanceof:0,void:a=>a,
throw:0,export:0,import:0,true:0,false:0,this:0,null:0
};
a.void(0);
a.let++;a.if++;a.this++;
何が優先されるかな?
with祭り
with({if:a=>console.log(a)})if(1);
with({do:a=>console.log(a),while:a=>console.log(a)}){do(0);while(0)}
with({typeof:a=>typeof(a)})console.log(typeof(0)=="string");
with({void:a=>b=a,b:1})void(0),console.log(b);
(function*(a){with({yield:a=>console.log(a)})yield(a)})(0);
(async function(a){with({await:a=>console.log(a)})await(a)})(0);