2005.12.8 Toshiro Takahashi
Memo for JavaScript掲示板
14730 XMLHttpRequestの強制ロードって?
暫定版Ajax用ライブラリjslb_ajax038.jsの強制ロード処理の
1行目の (!!sendRequest.arguments[5])?sload:false;について
(→暫定版Ajax用ライブラリ)
fooさん 2005/12/07 13:55
>"!!sendRequest.arguments[5]"というのは、具体的にはどういう判定の意味になるのでしょうか。
//強制ロードの設定
var sload = (!!sendRequest.arguments[5])?sload:false;
if(sload || method.toUpperCase() == 'GET')url += "?";
if(sload)url=url+"t="+(new Date()).getTime();
1行目の (!!sendRequest.arguments[5])?sload:false;について説明してみます。
(下記説明でいう「強制ロード」は、3行目のキャッシュ騙し処理のことです。)
この目的と機能は、
1.(目的)該当引数arguments[5]が、undefined 、null 空白など値の無い時は、
強制ロードをしない(NaNも含む)。
2.(目的)「true」や「1」の時は、強制ロードし、「false」「0」ではしない。
3.(結果としての機能)
これら以外のすべての場合、たとえばStringやObjectでは強制ロードする。
です。
このライブラリでは、1と2を実現する方法として論理否定演算子 (Logical NOT Operator) 「!」 を
使いました。これにより、該当argumentのResultを強制的にBoolean化しています。
!sendRequest.arguments[5]とすることで、trueかfalseにしてしまうわけです。
この処置によって、arguments[5]がundefinedなどになる場合でも、エラーにならずに
falseで処理されるという仕組みになっています。
「!!」と2つ重ねたのは、たとえば「true」が与えられた時に、それを「true」のまま通すためです。
(もちろん、その後の処理をfalseで通して処理するなら「!」ひとつでOKです)
そして、1と2の目的のためにこの方法を選択した結果として、3の機能が発生しているという状態です。
もちろん、この目的のためには、この方法しかないわけではなく、arguments配列も使わず、この場合
なら(sload?)xx:xxx;とするだけの方法も最近は見かけます。三項演算子も内部的には「!」と同じで
ToBooleanを呼び出すようですから、理にかなっていると思いますし、最近のブラウザでは問題が起き
ていないように見受けられますので、わたしもそのうち移行するかもしれません。
ただ、argumentsを使うこの方法は、古い多くのブラウザ戦場の中を無数のエラーを回避しつつ生き残って
きましたので、つい愛着もあって、使ってしまいます(^^;;;
ECMAScript262 3thでは
論理否定演算子の各タイプに対する動作は下記のとおりです。
入力型 結果
Undefined →false
Null →false
Boolean →結果は入力引数と等しい。(無変換)
Number →引数が +0, -0, NaN ならば結果は false; そうでなければ true
String →引数が空文字列 (長さ 0) ならば結果は false; そうでなければ true
Object →true
(論理否定演算子内ではToBoolean()が呼び出されます)
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/9_Type_Conversion.html
【型によって!と!!は何を返す?】
<div id="output"></div>
<script>
var echo = function(b){document.getElementById('output').innerHTML+=b}
function A(a) {
echo( " <b><font color='green'>"+ (a) + "</font></b> :: typeof a is <b>" + (typeof a) + "</b> / (!a) is <b>"+(!a) + "</b> / (!!a) is <b>"+(!!a)+"</b><br>");
}
A();
A(null);
A('');
A(NaN);
A(true);
A(false);
A(1);
A(0);
A(-0);
A(+0);
A("a");
A('true');
A('false');
A({});
</script>
| JavaScript++かも日記 |