演算子 -『JavaScript』

table of contents

    演算子は、与えられた変数やリテラルに対して、あらかじめ用意された処理を行うための行うための記号です。演算子によって処理される変数やリテラルをオペランドと呼びます。

    算術演算子

    四則演算などのような、数学でよく取り扱う演算を行ってくれるのが算術演算子です。代数演算子とも呼びます。

    加算演算子 +

    加算演算子+は、オペランドのデータ型によって違います。オペランドの片方が文字列の場合は文字列連結演算子とみなされ、機能が変わってしまいます。


    var test01 = 100+ 100; // 200 var test02 = '100' + 100 // 100100

    インクリメント演算子 ++ デクリメント演算子 –

    インクリメント演算子++はオペランドに1を加え、デクリメント演算子--はオペランドから1を減算します。この 演算子の位置に注意します。オペランドの後に演算子がある場合(前置演算)は、変数に値を代入してから、変数をインクリメントします。オペランドの前に演算子がある場合(後置演算)は、変数に値を代入する前に、変数をインクリメントします。


    var a = 0; var b = 0; a = num++ // 1 b = ++num // 0

    小数点を含む計算

    JavaScriptでは内部的に数値を2進数で演算しているため、小数点を含む計算で値が無循環小数となり誤差が出る場合があります。小数点を含む演算をしたい場合は値を一旦整数にして、その結果を再度小数に戻す必要があります。


    console.log(0.1 * 3); // 0.30000000000000004 console.log(0.1 * 10 * 3 / 10); // 0.3

    代入演算子

    代入演算子は指定された変数に値を設定するための演算子です。算術演算子と合わさった機能を持つ複合代入演算子は、変数に対する演算の結果をその変数に再代入することができます。

    =
    変数などに値を代入する
    +=
    左辺の値に右辺の値を加算して代入
    -=
    左辺の値から右辺の値を減算して代入
    *=
    左辺の値に右辺の値を乗算して代入
    /=
    左辺の値を右辺で値を除算して代入
    %=
    左辺の値を右辺の値で除算してあまりを代入
    &=
    左辺の値を右辺の値で論理積演算して代入
    |=
    左辺の値を右辺の値で論理和演算して代入
    ^=
    左辺の値を右辺の値で排他的論理和演算して代入

    基本型と参照型のによる代入の性質の違い

    基本型の場合、値は変数に直接格納されるので、それを別の変数にコピーした上でその値を変化させても影響は与えることはありません。参照型の場合は値そのものではなく値を格納しているアドレス(場所)が格納されるので、どちらかの値を変化させると同期するような挙動を見せます。

    var x = 0;
    var y = x;
    
    x= 100; // y = 0
    
    var listX = [1,2,3,4,5];
    var listY = listX;
    
    listX[4] = 100; listY = [1,2,3,4,100];
    
    

    listXlistYはアドレスをコピーして参照による代入をしているので、同じ値を見ていることになります。listXを変更するとlistYにも影響が及びます。

    再代入できない定数のふるまい

    定数は再代入することはできませんが、変更することはできます。


    const YEAR = 2016; YEAR = 2015; // error const YEARS = [2015,2016]; YEARS = [2015,2016,2017] // error YEARS[3] = 2017 // ok

    参照型の場合は再代入はできませんが、元の配列はそのままで内容を書き換えることは可能です。

    配列の分割代入 《ES2015》

    分割代入は、配列とオブジェクトを分解して、要素とプロパティ値をひとつひとつの変数に分解するための構文です。元々の仕様では個々の要素にアクセスし変数に格納する必要がありましたが、分割代入では記述を簡潔にまとめることができます。


    // 分割代入なし // - - - - - - - - var list = [10,20,30,40,50]; var item0 = list[0]; var item1 = list[1]; var item2 = list[2]; var item3 = list[3]; var item4 = list[4]; // 分割代入 // - - - - - - - - let list = [10,20,30,40,50]; let [item0,item1,item2,item3,item4] = list;

    代入先の変数を[]で配列のように囲って列挙して記述します。...演算子を使うと、個々の変数に割り当てられなかった残りの要素をまとめて配列として切り出すことが可能です。


    let list = [10,20,30,40,50]; let [item0,item1,...other] = list; alert(other); // [30,40,50]

    分割代入を利用すると、変数の値を入れ替えることができます。


    let x = 500; let y = 1000; [x,y] = [y,x];

    オブジェクトの分割代入 《ES2015》

    配列で行った分割代入のように、オブジェクトのプロパティを変数に分解することもできます。

    オブジェクトの場合は名前で個々の変数に分解します。変数の並び順はプロパティの定義順と違っていても、分解しないプロパティがあってもokで、対応するプロパティがない場合は無視されます。無視された場合のデフォルト値を左辺で指定することができます。


    let nami = { name: 'Nami', age: 20, weapon: 'magic tact' } let {age, name, dream = 'making world map'} = nami;

    dreamにはプロパティが存在しなかったので、デフォルト値がセットされています。

    入れ子になったオブジェクトは、オブジェクトとして変数に格納することも、obj: {key}という形で値を抽出することも可能です。


    let nami = { name: 'Nami', age: 20, hair: { length: 'long', color: 'orange' } } let {hair, hair:{color}} = nami; console.log(color); // orange

    key: newKeyと記述すると元のプロパティと異なる名前の変数に値を割り当てることが可能です。


    let nami = { name: 'Nami', age: 20, weapon: 'magic tact' } let {age: namiAge, name: namiName} = nami; console.log(namiName); // Nami

    比較演算子

    左辺と右辺の値を比較してその結果を真偽値true``falseで返します。条件分岐やループ終了の処理の際に利用するのが一般的です。

    ==
    等しい場合にtrueを返す
    !=
    等しくない場合にtrueを返す
    ===
    値とデータ型が等しい場合にtrueを返す
    !==
    値かデータ型が等しくない場合にtrueを返す
    <
    右辺の方が小さい場合にtrueを返す
    >
    右辺の方が大きい場合にtrueを返す
    <=
    左辺が右辺以下の場合にtrueを返す
    >=
    左辺が右辺以上の場合にtrueを返す

    等価演算子

    等価演算子==は値が等しい場合にtrueを返しますが、オペランドのデータ型によって比較する基準が異なり、比較するデータ型が違っているとデータ型を変換して等しいと見なせないか努力するような挙動を見せます。

    文字列/数値/論理型
    文字列/論理型は数値に変換されて判定される
    オブジェクト
    基本型に変換して判定

    同値演算子

    同値演算子===はデータ型を変換せず、等しいかどうかを判定します。==ではデータ型を変換して判定してしまうので、実際の開発ではこちらの比較で処理していくことがのぞましいとされることが多いです。

    条件演算子

    条件演算子 ? :は指定された条件式の真偽に応じて、対応する値を出力したい場合に使います。if文でも同じことができますが、シンプルな処理の時など、コードを簡潔に済ませたい時に重宝します。


    var num = 9; var test = (num > 5) ? 'OK' : 'NG'

    論理演算子

    複数の条件式や論理値を結合し、その結果をtruefalseとして返します。比較演算子と組み合わせて利用して複雑な条件式を実現します。

    && (論理積演算子)
    左右の式がともにtrueならtrue (and)
    || (論理和演算子)
    左右の式のどちらかがtrueならtrue (or)
    !
    式がfalseのば場合trueを返す (not)

    falsyな値

    JavaScriptでは暗黙的にfalseとみなされている値、falsyな値があります。論理演算子のオペランドが、常に論理型のtruefalseである必要はないということです。

    • 空の文字列 ''
    • 数値の0
    • NaN
    • undefined
    • null

    ショートカット演算

    論理積/論理和演算子を利用する場合、左式だけが評価されて、右式が評価されないパターンがあります。

    &&の場合、左式がfalseと評価された段階で、条件式全体がfalseとなるので、右式は実行されません。このことから、論理演算子の先頭以外で、関数呼び出し・インクリメント・デクリメント・代入演算子などの値を操作するような式を含めない、というのが一般的な認識です。

    その他の演算子

    delete演算子

    delete演算子は、オペランドに指定した変数や配列、オブジェクトのプロパティを破棄します。削除できた場合にはtrue、できなかった場合にfalse
    返します。

    特徴としては

    • 配列の要素を削除すると、該当の要素が削除されるだけで、他の要素に影響を与えず、順番はかわらない
    • 明示的に宣言された変数を削除することはできない
    • 組み込みオブジェクトのね家には、削除できないものがある

    typeof演算子

    typeof演算子はオペランドに指定した変数やリテラルのデータ型を表す文字列を(number/string/boolean/object)として返します。配列とオブジェクトは同じobjectと返されます。。どんなobjectか知りたい場合はinstanceof演算子などを使います。

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

    複数の演算子が式にふくまれている場合、どのような順序で処理するかを決めるのが、優先順位と結合則です。

    優先順位

    JavaScriptの演算子は優先順位を持っていて、優先順位の高い順に演算が実行されます。優先順位の高い順に記述します。

    • [] ()
    • ++ -- ~ !
    • * / %
    • + -
    • << >> <<<
    • == === != !==
    • &
    • ^
    • |
    • &&
    • ||
    • ?:
    • = += -=
    • .

    この優先順位はかなり複雑なので、複雑な演算をするときは細かく()を使って区切ることで、わかりやすく演算の順序を指定することができます。


    var x = ((2 * 3) + (5 * 2)) / 2

    結合則

    結合則は、結合の方向を決めるルールです。

    左から右
    + - * / % < <= > >= == === != !== && || << >> >>> & ^ | . [] () , instanseof in
    右から左
    ++ -- = += -= *= /= %= &= ^= |= ! ~ ?: delete typeof void
    演算子 -『JavaScript』のアイキャッチ画像

    share

    related