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++かも日記 |