with とか document.write とかって deprecated ではないよね
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ 非推奨だけど deprecated じゃないものいろいろ
with とか eval とか arguments.callee とか docuentw.write とか JavaScript では使うべきじゃないって言われてるものがいくつかありますよね
REPL 作るみたいなものだと必要ですし絶対禁止ってものではありません
私が見かけたコードでは 同じ 「文字列から JavaScript を実行する」でも 関数スコープで実行する Function コンストラクタのほうが人気な気がします
内側が複雑になると見づらくバグのもとなので これみたいな with することで便利になる限られた方法以外では 控えたほうがいいと思います
VB みたいに with のオブジェクトのプロパティは 「. から始める」ようにしておけば どこを参照してるかわかりづらいことが減ってよかったのに と思いますが . から始まると余計なところが結合されたり大変な気もするので仕方なかったのかな
ちゃんと使えば便利なので個人的には 必要に応じてアリだと思ってます
ただ strict mode では使えないので強制 strict mode になる class や module では使えません
実際に MDN でも deprecated とはなってません
推奨はされないってくらいです
callee の方は JavaScript の仕組み上 「arguments.callee()」 と書いて呼び出すと this のコンテキストが arguments になるのが良くないと聞いたことがあります
最初は Window ですが 2 回目以降は this が arguments になります
私としては 前回の引数がわかるので再帰処理的には使いみちありそうで 好きなんですけどねー
ただまあ ただの関数でなく オブジェクト指向的にメソッドとしているときなら this で本来の所属するオブジェクトが参照できないのは困るというのは理解できます
もちろんできないわけではなく arguments コンテキストで実行しなければいいだけなので
とか
とか するだけ
上側は常に window にしたいときのものなので 基本は下側でおっけいです
パフォーマンス的には上側の常に window コンテキストにしたいときも下側とかこれとかにしたほうがいいかも
毎回これ書くのが面倒なのはわからなくもないですけど これだけだと非推奨にするってほどでもないように思います
名前つければ不要かもしれませんが 関数の名前がなんであっても常に自分を指す名前って便利だと思うんですけどね
コピペだけで 使いまわせますし
なので私は再起する時には recur って名前をつけるようにしてます (recursive function:再起関数 の略)
DOM 構築後に使うとページが真っ白になってしまうので DOM 構築中の script タグ内専用みたいなものです
DOMContentLoaded や load イベント後に DOM 要素を取得して書き換えるのが一般的です
仮想 DOM 使って そういう書き換えは Framework が自動でやる とかいう世界もあるようですが いわゆる 「jQuery で十分」といわれるような小さいものだと DOM を取得して innerHTML を書き換えになります
ですが 最初に一回だけ書き換えるところであとから変更される可能性がないところは document.write でも別にいいんじゃないかと思います
例えば
あとから変わらないのに このためにわざわざ必要のない class や id つけたタグを作るのはムダに思えます
これはいわば JavaScript 的な DOM 処理じゃなくサーバ側のテンプレートエンジンで処理しておけばいいところ です
サーバサイドの処理すればいいけど ブログみたいなサーバサイド処理ができない環境だから JavaScript でやってるところは document.write でいいなじゃないかと思います
サーバサイドの代替ですよー って明示もできて Python とか PHP とか使えるようになったら置き換えれば良いところがぱっとわかりますしね
eval
eval は JavaScript に限らず言われているものでパフォーマンスもそんなよくないし ユーザの入力そのまま実行するようだと危険だし 使うところは選ばないといけないものですREPL 作るみたいなものだと必要ですし絶対禁止ってものではありません
私が見かけたコードでは 同じ 「文字列から JavaScript を実行する」でも 関数スコープで実行する Function コンストラクタのほうが人気な気がします
new Function("var a = 1;return a + 1")()
2
with
with はこの記事みたいな使い方が向いてると思います内側が複雑になると見づらくバグのもとなので これみたいな with することで便利になる限られた方法以外では 控えたほうがいいと思います
VB みたいに with のオブジェクトのプロパティは 「. から始める」ようにしておけば どこを参照してるかわかりづらいことが減ってよかったのに と思いますが . から始まると余計なところが結合されたり大変な気もするので仕方なかったのかな
callee
with と callee は strict mode だと禁止ですちゃんと使えば便利なので個人的には 必要に応じてアリだと思ってます
ただ strict mode では使えないので強制 strict mode になる class や module では使えません
実際に MDN でも deprecated とはなってません
推奨はされないってくらいです
callee の方は JavaScript の仕組み上 「arguments.callee()」 と書いて呼び出すと this のコンテキストが arguments になるのが良くないと聞いたことがあります
function countdown(n){
if(n < 0) return
console.log(this, arguments)
arguments.callee(n - 1)
}
countdown(3)
if(n < 0) return
console.log(this, arguments)
arguments.callee(n - 1)
}
countdown(3)
Window {} [3]
[3] [2]
[2] [1]
[1] [0]
[3] [2]
[2] [1]
[1] [0]
最初は Window ですが 2 回目以降は this が arguments になります
私としては 前回の引数がわかるので再帰処理的には使いみちありそうで 好きなんですけどねー
ただまあ ただの関数でなく オブジェクト指向的にメソッドとしているときなら this で本来の所属するオブジェクトが参照できないのは困るというのは理解できます
もちろんできないわけではなく arguments コンテキストで実行しなければいいだけなので
function countdown(n){
if(n < 0) return
console.log(this, arguments)
eval(arguments.callee)(n - 1)
}
countdown(3)
if(n < 0) return
console.log(this, arguments)
eval(arguments.callee)(n - 1)
}
countdown(3)
Window {} [3]
Window {} [2]
Window {} [1]
Window {} [0]
Window {} [2]
Window {} [1]
Window {} [0]
とか
const obj = {
countdown(n){
if(n < 0) return
console.log(this, arguments)
arguments.callee.call(this, n - 1)
},
mark: 1,
}
obj.countdown(3)
countdown(n){
if(n < 0) return
console.log(this, arguments)
arguments.callee.call(this, n - 1)
},
mark: 1,
}
obj.countdown(3)
Object {mark: 1} [3]
Object {mark: 1} [2]
Object {mark: 1} [1]
Object {mark: 1} [0]
Object {mark: 1} [2]
Object {mark: 1} [1]
Object {mark: 1} [0]
とか するだけ
上側は常に window にしたいときのものなので 基本は下側でおっけいです
パフォーマンス的には上側の常に window コンテキストにしたいときも下側とかこれとかにしたほうがいいかも
;(a=>a)(arguments.callee)()
毎回これ書くのが面倒なのはわからなくもないですけど これだけだと非推奨にするってほどでもないように思います
名前つければ不要かもしれませんが 関数の名前がなんであっても常に自分を指す名前って便利だと思うんですけどね
コピペだけで 使いまわせますし
なので私は再起する時には recur って名前をつけるようにしてます (recursive function:再起関数 の略)
document.write
昔のページはよく使われていましたよねDOM 構築後に使うとページが真っ白になってしまうので DOM 構築中の script タグ内専用みたいなものです
DOMContentLoaded や load イベント後に DOM 要素を取得して書き換えるのが一般的です
仮想 DOM 使って そういう書き換えは Framework が自動でやる とかいう世界もあるようですが いわゆる 「jQuery で十分」といわれるような小さいものだと DOM を取得して innerHTML を書き換えになります
ですが 最初に一回だけ書き換えるところであとから変更される可能性がないところは document.write でも別にいいんじゃないかと思います
例えば
<script>document.write(new Date().getMonth() + 1)</script>月分の◯◯◯
のような日付埋め込み系や おみくじみたいなランダムに何か出すものあとから変わらないのに このためにわざわざ必要のない class や id つけたタグを作るのはムダに思えます
これはいわば JavaScript 的な DOM 処理じゃなくサーバ側のテンプレートエンジンで処理しておけばいいところ です
サーバサイドの処理すればいいけど ブログみたいなサーバサイド処理ができない環境だから JavaScript でやってるところは document.write でいいなじゃないかと思います
サーバサイドの代替ですよー って明示もできて Python とか PHP とか使えるようになったら置き換えれば良いところがぱっとわかりますしね