続・ブックマークレット作法

無難に外部スクリプトを読み込むやり方に比べ保守しづらく自動更新の恩恵も受けられずオフラインで動くことぐらいしか使う側にとってこれといったメリットは無いものの作る側にとってはパズル的魅力とワンライナ的浪漫に満ちた単体動作ブックマークレットの書き方について。

方針

前回と同じだが一応再掲。

  1. 変更箇所を前方にまとめる
  2. 空白文字を使わない
  3. グローバル領域を汚染しない
手法

2. に従うと使えなくなる機能がいくつかあるので代替を考える。

var function
let with
function f() f=function() *1
for(k in o) for([k]in(o)) *2
' ' '\40'

new Date とかは単に new(Date) とすればOK。
1. と 3. は前回示した配列を用いる方法で同時に解決できる。

javascript:[0,1,2,function(){alert(this.slice(1).reverse())}].reverse()[0]()

素のオブジェクトならキーワード引数風。

javascript:({a:0,b:1,c:2,_:function(){with(this)prompt(this,[a,b,c])}})._()

もっとシンプルに with でもいい。ただし返り値に注意。

javascript:with({a:0,b:1,c:2}){prompt(this,[a,b,c])}void''

若干まわりくどいが replace を使う方法も。
ブックマークレットとかで、設定を先頭に書けるようにする - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。 - subtech

実践

失礼して http://mayokara.info/note/view/343 を添削。

javascript:"AmazonTag",{$:"{yourAffiliateId}-22",_:function(d,h,asin,r){prompt(r='<a\40href="http://www.amazon.co.jp/gp/product/'+(asin=d.getElementById("ASIN").value)+'?tag='+this.$+'"><img\40src="http://images-jp.amazon.com/images/P/'+asin+'.09.MZZZZZZZ.jpg"\40alt="'+d.title.replace(/[&<>"']/g,function(m){return'&'+h[m]+';'})+'"></a>',r)}}._(document,{"&":"amp","<":"lt",">":"gt",'"':"quot","'":"#39"})

制約は多いほうが自己満足も深い。

+

"Restrictions breed creativity." ―Mark Rosewater

*1:苦しい

*2:1.7↑限定