今さらながら == と === の挙動の違いをチェック
そもそもコレなんて呼ぶ
PHP、javaScriptで、いつも使っているけど、何て言うのか
覚えていますか?
ネット上とかで毎回見ているけど、意外とスルーしていたりします。
正解は
うーん、会話で使うには長いんですよね。普段は、「イコール1コ抜けてるよ」 とか言っていますね。 (ごめんなさい、そんな状況あんまりなかった)
で、名前のとおり、=== の方が厳しく型をチェックしてくれます。
でも、実際にどんな動きをしているか理解しているのか、と言われたら微妙だということに
気づきました。
挙動チェック
上がjavaScript、下がPHPのコードです。
var str = "1"; var num = 1; console.log( str == num ); // true console.log( str === num ); // false
<?php $str = '1'; $num = 1; var_dump( $str == $num ); // true var_dump( $str === $num ); // false
== は文字列を数値に変換してから比較を行います。 === は型変換を行うことなく評価を行うので、
javaScript、PHPともにfalseが返ってきていますね。この挙動を見ただけでも === を使うことの
意味が実感できると思います。
次に、Boolean(boolean)型を見てみましょう。
オペランドの片方がBooleanならば、その論理オペランドはtrueならば1に、そしてfalseならば0に変換さます。
=== ならば、もちろん厳密にチェックしてくれるのでfalseが返って来ます。
console.log( true == 1 ); // true console.log( true === 1 ); // false console.log( false == 0 ); // true console.log( false === 0 ); // false
<?php var_dump( 1 == true ); // true var_dump( 1 === true ); // false var_dump( 0 == false ); // true var_dump( 0 === false ); // false
javaScriptとPHPの違い
javaScriptの方は、最後の2行に注目していただければわかると思います。
console.log( undefined == null ); // true console.log( undefined === null ); // false console.log( undefined == "" ); // false console.log( undefined === "" ); // false console.log( null == "" ); // false console.log( null === "" ); // false
<?php var_dump( null == '' ); // true var_dump( null === '' ); // false
PHPの方はnullが == で比較した場合、trueになっているんですね。この挙動は最新のPHP7で確認しても
変わっていませんでした。
それでも、 === で比較すれば、ちゃんとfalseが返って来てくれます。
大事なことは、なんでもかんでも === を使わずに == と === を使った場合とで、どういう挙動になるか
考えてプログラムを書くことです。
javaScriptのthis
thisイコール「自分自身」からの脱却
- 以下のコードはGoogle ChromeとFireFoxでしかテストしていません
- コードにはjQueryを使用しています
先にコードとコンソール(開発者ツール)での結果を出します。
<div id="test_zone"> <button id="test_button">テストボタン</button> </div>
$(function() { "use strict"; console.log("1 : " + this); // Testオブジェクト var Test = function(score) { console.log("2 : " + this); this.score = score; } // メソッドはプロトタイプ宣言で Test.prototype = { buttonOn : function() { console.log("3 : " + this); console.log("test : " + this.score); $("#test_zone").on({ "click": function() { console.log("4 : " + this); } }, "#test_button"); } }; // -- main -- var test = new Test(55); test.buttonOn(); });
結果 1 : [object HTMLDocument] 2 : [object Object] 3 :[object Object] test : 55 4 : [object HTMLButtonElement] // ボタンをクリック後
番号順に説明していきましょう。
1はグローバルなので、オブジェクトはHTMLDocument
、つまりwindow
を指しています。
2はTestオブジェクト(Testクラス)内なので、Testオブジェクト自体を指しています。
3はbuttonOnメソッド内。結果がobject Object
でわかりづらいので、Testオブジェクトの
プロパティであるscore
をthisで呼びしています。score
がthisで呼びせている、ということ
は、つまり、thisにはTestオブジェクトが入っていることを意味しますね。
問題は4です。4でのthisは、HTMLButtonElement
を指しています。DOMのボタン
を示しているのです。
なぜか。それは、javaScriptでは関数自体が独立したオブジェクトであり、thisは関数を
定義したオブジェクトに属するものではないからです。(この説明は誤解を招くかもしれませんね。自分でも
ちょっと自信ないです)
で、結局thisがなんなのかと言うと、その関数やメソッドを呼び出したオブジェクトが入っているというイメージが良い
かもしれません。
4では、jQueryのonメソッドのclickメソッドを呼び出したbuttonElementがthisに
入っていたわけです。
上記の場合の解決策
上記の場合で、onメソッド内でTestオブジェクトを参照したい、という場合があります。そのような場合は、
一旦、別変数のなかにthisを格納することで解決できます。下記ではself
という変数
のなかにthis
を格納しています。
buttonOn : function() { console.log("3 : " + this); console.log("test : " + this.score); var self = this; $("#test_zone").on({ "click": function() { console.log("4 : " + this); console.log("5 : " + self); console.log("test : " + self.score); } }, "#test_button"); }
5 : [object Object] test : 55
Testオブジェクトのscore
をself
で呼び出せているので
5のobject Object
の正体がTestオブジェクトであることがわかります。
成功ですね。
参考
apply
とcall
を使うとthis
を自由自在に操ることができる
らしいです。詳しくは以下を参照してください。
CSS3で光沢を表現する
ナビゲーションをつくる
今回は以下のナビゲーションにlinear-gradientを施す形で光沢を表現します。
コードは以下の通り。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>DEMO</title> <link rel="stylesheet" href="style.css"> </head> <body> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Works</a></li> <li><a href="#">Links</a></li> </ul> </nav> </body> </html>
body { margin: 0; padding: 0; } nav { background-color: #ddd; } nav ul { overflow: hidden; list-style: none; } nav li { float: left; width: 100px; border-right: #fff 1px solid; font-weight: 700; } nav li:first-child { border-left: #fff 1px solid; } nav a { display: block; text-decoration: none; text-align: center; background-color: #f36; padding: 10px 0; color: #fff; } nav a:hover { opacity: 0.7; }
見てわかる人もいるかもしれませんが、前回の記事のコードをちょっと加工しただけです。
ナビゲーションに光沢を施してみる
CSSに以下の記述を追加します。
nav a { display: block; text-decoration: none; text-align: center; background-color: #f36; padding: 10px 0; color: #fff; /* ここから先を追記 */ background: -webkit-linear-gradient( top, #ffced7 0%, #f74657 49%, #f10013 51%, #fe2951 100% ); background: -ms-linear-gradient( top, #ffced7 0%, #f74657 49%, #f10013 51%, #fe2951 100% ); background: linear-gradient( to bottom, #ffced7 0%, #f74657 49%, #f10013 51%, #fe2951 100% ); /* ここまで追記 */ }
以下はGoogle chromeでの表示結果です。
ベンダープレフィックスをつけているので、FireFoxとIE10以上でも表示されます。その
他のブラウザでは確認していません。
linear-gradientはIE9以下ではサポートされていません。F12ボタン(Windowsの場合)を
押して開発者ツールでブラウザのバージョンを下げれば、そのことがわかります。
linear-gradientの注意点
上記コードでlinear-gradientを施した際、ベンダープレフィックスつきの書式と、ついていない書式で違う部分が
あります。(それ以外は同じということなのでコピペが有効)
top
とto bottom
の部分ですね。今回のグラデーションの場合、上から下へのグラデーションと
なっているわけですが、linear-gradientでは、プレフィックスつきの場合は起点の名前を、そうでない
(ベンダープレフィックスではない)場合は、to ××
で方向を指定します。
上記のナビは光沢にするため%なんかを使っていますが、基本形は下記のような感じになります。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>DEMO</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="grad_box"></div> </body> </html>
body { margin: 0; padding: 0; } #grad_box { width: 200px; height: 200px; background: #ddd; background: -webkit-linear-gradient(top, #ffced7, #fe2951); background: -ms-linear-gradient(top, #ffced7, #fe2951); background: linear-gradient(to bottom, #ffced7, #fe2951); }
現在ではフラットデザインが主流となっているので使用場面が限られますが、それでも覚えておいて損はないはずです。