JavaScriptは良くも悪くも記述の自由度が高い言語ですよね。
そんなJavaScriptには現場で使われるちょっとした小技や必須のテクニック、競技や問題向けの小技や荒技が存在する物と思います。
もしよければこんなのを現場では使ってる、コードゴルフでこれが有効ではないかというようなコードを共有しませんか?
必要なもので有名なのはprototypeやこれらですよね。
lang
1//即時関数 2(function (){ 3 // 4}()); 5 6//クロージャ 7//……めちゃくちゃなコードですね 8function a(_N){ 9 var n=_N; 10 return { 11 add : 12 function (_n){ 13 return n+_n; 14 } 15 } 16} 17var NN=a(10); 18NN.add(5);
競技や問題向けですと型変換は多用されますかね。
lang
1//暗黙の型変換 文字から数値 2var s="100"; 3s-0;//number型 4 5//暗黙の型変換 数値から文字 6var n=250; 7n+"";//string型 8n+[];//string型 9 10//暗黙の型変換 数字を使わず数値を作る 11var v=+!v;//1 12z|z;//0
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
ベストアンサー
暗黙の型変換の1つに、+s
というのがあって、これで数値にできます。あと、即時関数は、カッコを使わずに!function(){...}()
とすれば1文字削れます。
XSSなどでたまに出現しますが、/foobar/.source
とすることで、引用符なしで文字列を作れます。
いちばん強烈な技としては、[]['constructor']['constructor']('コード文字列')
とすればFunctionコンストラクタを経由してコード実行ができるので、あとは文字列を記号にすることで任意のコードを記号だけで書き下せます。
投稿2015/05/29 05:02
総合スコア145062
0
これはよく使うので回答してみます。
条件分岐を&&
や||
で書く。
lang
1//fが暗黙の型変換でtrueになるとき関数を実行 2f && f(); 3//if(f) f();と同じ 4 5//fが暗黙の型変換でfalseになるときどこかで定義してあるDEFAULT_FUNCTIONを代入 6f || (f = DEFAULT_FUNCTION); 7//if(!f) f = DEFAULT_FUNCTION;と同じ 8 9//objがfalseのとき{}を代入 10obj = obj || {}; 11//obj = obj ? obj : {}; と同じ 12
型変換でtrue
,false
を短く書く
lang
1!0;//true; 2!1;//false; 3
追記
オブジェクトの存在判定など。
lang
1 2//AudioContextの存在判定(なければfalseになり、あればそのオブジェクトが代入される) 3window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext; 4//これとおなじ 5if(window.AudioContext) window.AudioContext = window.AudioContext; 6else if(window.webkitAudioContext)window.AudioContext = window.webkitAudioContext; 7else if(window.mozAudioContext)window.AudioContext = window.mozAudioContext; 8else window.AudioContext = false; 9 10//addEventListener なければattachEventを[on]で使えるようにする 11var on = ['addEventListener ', 'attachEvent']; 12var i = -1; 13window[on[++i]] || window[on[++i]; 14on = on[i]; 15
投稿2015/06/02 11:29
編集2015/06/02 13:28総合スコア12
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
class を定義したり、それを extend するというときは、
coffeescript で書いて、 coffee -p -b で javacript に変換してしまうことがあります。
lang
1# See http://leko.jp/archives/407 2class Parent 3 constructor: (@name) -> 4 5 move: (meters) -> 6 console.log @name + " moved #{meters}m." 7 8class Child extends Parent 9 move: -> 10 console.log "slithering..." 11 super 5 12 13child = new Child("kato") 14child.move()
$ coffee 1.coffee slithering... kato moved 5m.
$ coffee -p -b 1.coffee > 2.js $ node 2.js slithering...
$ cat 2.js var Child, Parent, child, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; Parent = (function() { function Parent(name) { this.name = name; } Parent.prototype.move = function(meters) { return console.log(this.name + (" moved " + meters + "m.")); }; return Parent; })(); Child = (function(superClass) { extend(Child, superClass); function Child() { return Child.__super__.constructor.apply(this, arguments); } Child.prototype.move = function() { console.log("slithering..."); return Child.__super__.move.call(this, 5); }; return Child; })(Parent); child = new Child("kato"); child.move();
投稿2015/06/06 08:24
編集2015/06/06 08:26総合スコア22322
0
みなさん使ってるとは思いますが・・・・。
jQueryで、アニメーションか、CSSのチェンジだけかを判定させる時、
当てるCSSを一度オブジェクトに格納して当てたりしてます。
lang
1var addCSS = {width: int, height: int, top: float, left: float}; 2var animationFlg = true; 3 4if (animationFlg) { 5 tagetDOM.animate(addCSS, time, ease, callBack); 6} else { 7 tagetDOM.css(addCSS); 8} 9
また、メソッドもテキストで格納したりとか
lang
1var runMethod; 2var addPosition = 'bottom'; 3 4if (addPosition = 'bottom') { 5 runMethod = 'append'; 6} else { 7 runMethod = 'prepend'; 8} 9 10tagetDOM[runMethod](addDOM);
小技というより、条件分岐でなるたけ一元管理できるように、ですね。
投稿2015/06/04 04:05
総合スコア9528
0
あまり規模が小さくないがasync/awaitをgenerator/yield再現するのためのco
lang
1function co(gfn) { 2 return function () { 3 var gen = gfn.apply(this, arguments) 4 return new Promise(function (res, rej) { 5 function resume(v) { 6 var r = gen.next(v) 7 Promise.resolve(r.value).then(r.done ? res : resume).catch(rej) 8 } 9 resume() 10 }) 11 } 12}
//例
lang
1function wait(ms) { 2 return new Promise(function (res) { 3 setTimeout(res, ms) 4 }) 5} 6 7var test = co(function* () { 8 console.log('T') 9 yield wait(1000) 10 console.log('E') 11 yield wait(1000) 12 console.log('S') 13 yield wait(1000) 14 console.log('T') 15}) 16 17 18console.log('--start--') 19test().then(function () { 20 console.log('--done--') 21})
またHTMLも含むのであれば任意の文字列をテキストファイルとしてダウンロードするためのこれ
lang
1var blob = new Blob(['テキスト']) 2var link = document.createElement('a') 3link.href = URL.createObjectURL(blob) 4link.download = 'ファイルネーム.txt' 5link.click()
投稿2015/05/29 09:36
編集2015/05/29 09:45総合スコア100
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/05/29 10:01
2015/05/30 19:52
2015/05/31 06:41
2015/05/31 10:04
0
有名なのだとビット演算で小数の整数化とかですかね?
lang
1var f = 12.34; 2var i = f | 0; // ==> 12
あまり推奨されないかもしれませんが、たまにビルドインオブジェクトのprototype拡張をすることがあります。
lang
1!!String.prototype.hoge 2|| Object.defineProperty(String.prototype, "hoge", { 3 value: function(){ 4 return this; 5 } 6});
後はメソッドの統一とかですか。
lang
1Element.prototype.matches = Element.prototype.matches || 2 Element.prototype.matchesSelector || 3 Element.prototype.webkitMatchesSelector || 4 Element.prototype.mozMatchesSelector || 5 Element.prototype.msMatchesSelector || 6 Element.prototype.oMatchesSelector;
小技というと違うような気もしますが…。
投稿2015/05/29 02:49
総合スコア870
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/05/29 05:17