みこむらめもむらむらむら

なんかHTML5とかJS勉強とかやりながらめもを綴るブログ

【JavaScript】演算子②

はーい引き続き演算子やります!

比較演算子

左辺と右辺を比較してその結果をtrue/falseとして返す
めっちゃftlやvmで利用していたので
これもある程度ならわかる、はず!

  • ==
    • 左辺と右辺の値が等しい場合はtrue
    • 例>> 5 == 5 //true
  • !=
    • 左辺と右辺の値が等しくない場合はtrue
    • 例>> 5 != 5 //false
    • 左辺が右辺より小さい場合はtrue
    • 例>> 5 < 5 //false
  • <=
    • 左辺が右辺より以下の場合はtrue
    • 例>> 5 <= 5 //true
  • >
    • 左辺が右辺より大きい場合はtrue
    • 例>> 5 > 3 //true
  • >=
    • 左辺が右辺より以上の場合はtrue
    • 例>> 5 >= 3 //true
  • ===
    • 左辺と右辺の値が等しくてデータ型も同じ場合はtrue
    • 例>> 5 === 5 //true
  • !==
    • 左辺と右辺の値等しくない場合、またはデータ型が異なる場合はfalse
    • 例>> 5 !== 5 //false
  • ?:
    • 「条件式?式1:式2」条件式がtrueの場合は式1を、falseの場合は式2を返す
    • 例>> (x == 1) ? 1:0 //

ふむ

等価演算子(==)

オペランドのデータ型によって
比較の基準が異なるので注意

左辺/右辺の型が同じ
  • 文字列/数値/論理型
    • 単純に双方が等しいかを判定
  • 配列/オブジェクト
    • 参照先が等しいかを判定
  • null/undefined
    • 双方ともnull/undefined、またはnullとundefinedの比較はすべてtrue
左辺/右辺の型が異なる
  • 文字列/数値/論理型
    • 文字列/倫理型を数値に変換したうえで判定
  • オブジェクト
    • 基本型に変換したうえで判定

要は
データ型が違う
データ型をなんとか変換して等しいとみなせないか頑張る
ってことですね

document.write(1 == true);  //true

1は真偽でいうと真なので
結果はtrue
うむ、わかりますた

またここで注意

var ary1 = [0, 1, 2];
var ary2 = [0, 1, 2];
document.writeln(ary1 == ary2);  //false

参照型の場合
変数の中には参照値(メモリ上のアドレス)が格納される
ということだったので
アドレスが一致した場合のみtrueを返す
上記の場合、実際の配列の中身は同じだけれど
あくまで参照値のary1とary2が同じでないので
falseが返ってくるわけですね、わかります

等価演算子(==)と同値演算子(===)

等価演算子オペランド
「なんとか等しいとみなせないか」とJS側で
あれこれ頑張ってくれる演算子
だがしかし、これが大きなお世話な時もある

document.writeln('3.14E2' == 314);  //true 指数表現
document.writeln('0x10' == 16);  //true 16進数表現
document.writeln('1' == 1);  //true

これは余計なお世話ですねー
そんな時に利用するのが同値演算子(===)

document.writeln('3.14E2' === 314);  //false
document.writeln('0x10' === 16);  //false
document.writeln('1' === 1);  //false

うむ!文字列型と数値型だから
すべてfalse!「'1'」も文字列扱い!
わかりやすい

ちなみに不等価演算子(!=)と非同値演算子(!==)も
同じような感じ、はあく!

条件演算子

三項演算子ともいう、とな
if命令でも同じような処理を実現できるけれど
「単に出力する値を条件に応じて振り分けたい」という場合
よりリンプルに記述できる、すっきり!
「条件式?式1:式2」こういう書き方ね

var x = 80;
document.writeln((x >= 70) ? 'やったね!' : 'もう少しがんばりましょう');  //やったね!

条件式である「x> = 70」がtrue⇒式1の「'やったね!'」が表示される
うむ、はあく!
これ便利そうだなー
忘れてif命令書きそうだなー

よーし次!

論理演算子

複数の条件式または論理値を
論理的に結合し、その結果を真偽で返す

これはめっちゃつかってたのでわかる!

  • &&(AND)
    • 左右の式がともにtrueの場合はtrue
    • 例>>100 == 100 && 1000 == 1000 //true
  • ||(OR)
    • 左右の式のどちらかがtrueの場合はtrue
    • 例>>100 == 100 || 1000 == 500 //true
  • !(NOT)
    • 式がfalseの場合はtrue
    • 例>>!(1000 == 500) //true
var x = 1;
var y = 2;
document.writeln(x == 1 && y == 1);  //false
document.writeln(x == 1 || y == 1);  //true

そりゃそうだ、うむ、ここは基本的にわかってる

ここだけ注意
論理演算子オペランド
必ずしも論理型のtrue/falseである必要はない

  • false(偽)

‐-空文字(' ')、数値の0、NaN(Not a Number)、null、underdefinedなどの値

  • true(真)
    • それ以外の値

うむ、覚えよう

論理積演算子(&&)と論理和演算子(||)

論理積/論理和演算子を利用する場合の注意!
左辺だけが評価されて右辺が評価されない
ことがある
ふむふむそうだね、あるね
具体例をチェック!

if(x == 1){document.writeln('こんにちは');}
x == 1 && document.writeln('こんにちは');

これは意味的には等価になる

1行目は変数xが1である場合に「こんにちは」と表示する
というスクリプトだがxが1でないので
それ以降の処理は実行されない

2行目は左辺がfalseな時点で
条件式全体は必ずfalseになるため
右辺は評価(実行)されない

どちらも変数x==1でないのでdocument.writeln();は
実行されない、わかります
こういう演算のことをショートカット演算とか
短絡演算という、うむ

あ、2行目みたいな記述はやめたほうがいいらしい

  • 条件分岐であることが一見してわかりにくい
  • 右辺が実行されるか曖昧になるため、思わぬバグになりやすい

からとか!ふむー

原則として
論理演算子の後方には、関数の呼び出し
インクリメント/デクリメント演算子、代入演算子など
値を実際に操作するような式を含めるべきではない
うむうむ

ビット演算子

整数値を2進数で表した場合の各桁に対して(ビット単位に)
論理計算を行う演算子のこと
なにそれおいしいの?って感じです←
読み飛ばしても構わないって書いてあるから
例は飛ばしてどんなのが使えるかだけメモ
軽く読むだけしておく
代入演算子でちょこっと調べたりしたし!

  • &
    • 左式と右式の両方にセットされているビット
  • |
    • 左式と右式のどちらかにセットされているビット
  • ^
    • 左式と右式のどちらかにセットされていて、かつ、両方にセットされていないビット
  • ~
    • ビットを反転
  • <<
    • ビットを左にシフト
    • 例>> x = 10; x >>= 1 //5
  • >>
    • ビットを右にシフト
  • >>>
    • ビットを右にシフト、かつ、左端を0で埋める

その他の演算子

今まで紹介したカテゴリに分類できない演算子

  • ,(カンマ)
    • 左右の式を続けて実行
  • delete
    • オブジェクトのプロパティや配列の要素を削除
  • instanceof
  • new
  • typeof
  • void
    • 未定義値を返す

delete演算子

オペランドに指定した変数や
配列要素、オブジェクトのプロパティを破棄する
delete演算子は削除に成功した場合trueを
失敗した場合はfalseを返す

はい、具体例!

var ary = ['赤', '青', '黄'];
document.writeln(delete ary[0]);  //true
document.writeln(ary);  //,青,黄 ①
var obj = {x:1, y:2};
document.writeln(delete obj.x);  //true
document.writeln(obj.x);  //undefined
var obj2 = {x:obj, y:2};
document.writeln(delete obj2.x);  //true
document.writeln(obj);  //[object Object] ②
var data1 = 1;
document.writeln(delete data1);  //false
document.writeln(data1);  //1 ③
data2 = 10;
document.writeln(delete data2);  //true
document.writeln(data2);  //エラー(data2は存在しない)
  • 配列要素を削除した場合、該当する要素が削除されるだけで後ろの要素が繰り上がるわけではない(インデックス番号は変わらない)①
  • プロパティを削除した場合も、プロパティそのものが削除されるだけで、プロパティが参照するオブジェクトが削除されるわけではない②
  • 明示的に宣言された変数を削除することはできない③

また、組み込みオブジェクトや
クライアントサイドJavaScript標準のオブジェクトに含まれるメンバの中には
delete演算子で削除できないプロパティもある、とか
クライアントサイドJavaScript標準のオブジェクトに関しては
後述があるようなので一旦スルー

typeof演算子

オペランドに指定した変数/リテラル
データ型を表す文字列を返す演算子
おお、なんか意味わかる

var num = 1;
document.writeln(typeof num);  //number
var str = 'こんにちは';
document.writeln(typeof str);  //string
var flag = true;
document.writeln(typeof flag);  //boolean
var ary = ['赤', '青', '黄'];
document.writeln(typeof ary);  //object
var ary2 = {x:1, y:2};
document.writeln(typeof ary2);  //object

配列やオブジェクトは
一律「object」と返される点に注意
また、ほかのデータ型でも
ラッパーオブジェクトとして宣言されている場合は
「object」とみなされる
ラッパーオブジェクトに関しては後述があるみたい

演算子の優先順位と結合則

優先順位

一つの式の中に複数の演算子が含まれる場合
優先順位の高いほうから演算する、ほう
優先度高いほうから‥

  • 配列([])、かっこ(())
  • インクリメント(++)、デクリメント(--)、減算(-)、反転(~)、否定(!)
  • 乗算(*)、除算(/)、剰余(%)
  • 加算(+)、減算(-)、文字列連結(+)
  • シフト(<<、>>、<<<)
  • 比較(<、<=、>=、>)
  • 等価(==)、不等価(!=)、同値(===)、非同値(!==)
  • AND(&)
  • OR(|)
  • 論理積(&&)
  • 論理和(||)
  • 条件(?:)
  • 代入(=)、複合代入(+=、-=など)
  • カンマ(,)

この優先順位も大事だけど
丸かっこで演算の優先順位を明示したほうがいい、そうですね間違いない

結合則

演算子を左から右、右から左の
いずれかの方向で結合するかを決めるルール
ほう‥

  • 左→右
    • 算術演算子(+、-、*、/、%)
    • 比較演算子(<、<=、>=、>、==、!=、===、!==)
    • 論理演算子(&&、||)
    • ビット演算子(<<、>>、<<<、&、^、|)
    • その他(.、[]、()、,、instanceof、in)
  • 右→左

うむ!!







演算子長かったー!次いくぜ!