方法①:lengthを使用する
a=[1,2,3]; console.log(a.length>3);
方法②:inを使用する
a=[1,2,3]; console.log(3 in a);
- Arrayオブジェクトの場合、in演算子によってインデックスが存在するかを検査できる。
a=[1,2,3]; console.log(a.length>3);
a=[1,2,3]; console.log(3 in a);
.length
で数える(×)// 半角英数字の場合 const sample1 = "12345abcde"; console.log(sample1.length); // 10 (〇) // 全角英数字の場合 const sample2 = "12345ABCDE"; console.log(sample2.length); // 10 (〇) // 絵文字の場合 const sample3 = "😀🤣😅😍😲😨😩😱🤬👽"; console.log(sample3.length); // 20 (×)
// 半角英数字の場合 const sample1 = "12345abcde"; console.log(Array.from(sample1).length); // 10 (〇) // 全角英数字の場合 const sample2 = "12345ABCDE"; console.log(Array.from(sample2).length); // 10 (〇) // 絵文字の場合 const sample3 = "😀🤣😅😍😲😨😩😱🤬👽"; console.log(Array.from(sample3).length); // 10 (〇)
// 半角英数字の場合 const sample1 = "12345abcde"; const buf = [...sample1]; console.log(buf .length); // 10 (〇) // 全角英数字の場合 const sample2 = "12345ABCDE" const buf = [...sample2]; console.log(buf .length); // 10 (〇) // 絵文字の場合 const sample3 = "😀🤣😅😍😲😨😩😱🤬👽" const buf = [...sample3]; console.log(buf .length); // 10 (〇)
桁数(文字数)が合わない数字等の桁あわせを実施する処理
slice
を使用する// 3桁で合わせる場合 a=1; a=('00'+a).slice(-3); console.log(a); // '001'
padStart
を使用する(ES2017)a=1; a=(''+a).padStart(3,0); console.log(a); // '001'
JavaScript
がその分のメモリをすぐに回収するとは限りません。
JavaScript
の構文は静的スコープ(構文スコープ:lexicsl scope)const x = 3; function f (){ console.log(x); // xを参照可能 } f();
{ let x = 3; console.log(x); { let x = 5; console.log(x); } console.log(x); }
let func; { let o = {memo1:"安全", memo2:"大丈夫!"}; func = function(){ console.log(`無名関数の中:${o.memo1}`); //無名関数の中:安全 return o; } } let oRes = func(); console.log(oRes); // {memo1: "安全", memo2: "大丈夫!"} oRes.memo1 = "危険"; console.log(oRes); // {memo1: "危険", memo2: "大丈夫!"}
(function(){ // IIFEの本体 })();
メリット
- 独自のスコープを持つ
- スコープ内部の情報を外部に渡す(return
する)ことができる。
var
を使って宣言した変数には「巻き上げ」が発生する。
var
で宣言された同じ名前の変数があれば、それが使われている個所で宣言されたものとして扱う{ console.log(x); // undefined var x = 5; console.log(x); // x }
var x ~
は最初にx
が実行されるより後に記述されているが、「巻き上げ」が実施されるため、宣言済み扱いになる。var
を使用すると関数宣言もスコープの先頭に巻き上げられる。let
で宣言された変数は宣言されるまで存在しないということ'use strict'
、または"use strict"
を記述することで、暗黙的グローバルが禁止される。
strictモード
で実行されるstrictモード
で実行されるreturn
を使って呼び出し元に戻します。
return
で戻らない場合や値が指定されないreturn
で戻る場合、関数が戻す値はundefined
となる。JavaScript
で関数はオブジェクトです。
種類 | 記述方法 | 詳細 |
---|---|---|
呼び出し | 関数名に()をつける | 関数の本体が実行される |
参照 | 関数名のみ | 実行されない |
function getGreeting() { return "Hello World!"; } //呼び出し console.log(getGreeting()); // "Hello World!" //参照 console.log(getGreeting); /* ƒ getGreeting() { return "Hello World!"; } */ // 関数を変数に代入する(関数の名前を変更する) const f = getGreeting; console.log(f()); // "Hello World!" // 関数をオブジェクトのプロパティに代入する const o = {}; o.f = getGreeting; console.log(o.f()); // "Hello World!" // 配列の要素として関数を代入する const arr = [1,2,3]; arr[1] = getGreeting; console.log(arr[1]()); // "Hello World!"
function f(x){ console.log(`関数内1:${x}`); x = 5; console.log(`関数内2:${x}`); } const x =10; console.log(`関数外1:${x}`); f(x); console.log(`関数外2:${x}`); /* // 表示内容 関数外1:10 関数内1:10 関数内2:5 関数外2:10 */
function f1(o){ console.log(` f1-1:${o.message}`); o.message = "f1内で書き換え"; console.log(` f1-2:${o.message}`); } function f2(o){ console.log(` f2-1:${o.message}`); o ={ message:"f2内で同名オブジェクト追加", }; console.log(` f2-2:${o.message}`); } function f3(o){ console.log(` f3-1:${o.message}`); o.message = "f3内で別名オブジェクト追加"; o.message2 = "f3内で別名オブジェクト追加"; console.log(` f3-2:${o.message}`); } function f4(o){ console.log(` f4-1:${o.message}`); o.message = "f4内で別名オブジェクト削除"; delete o.message2; console.log(` f4-2:${o.message}`); } let o ={ message:"初期値", }; console.log(`呼び出し元1:${o.message}`); f1(o); console.log(`呼び出し元2:${o.message}`); f2(o); console.log(`呼び出し元3:${o.message}`); f3(o); console.log(`呼び出し元4:${o.message}`); f4(o); console.log(`呼び出し元5:${o.message}`); /* 呼び出し元1:初期値 f1-1:初期値 f1-2:f1内で書き換え 呼び出し元2:f1内で書き換え f2-1:f1内で書き換え f2-2:f2内で同名オブジェクト追加 呼び出し元3:f1内で書き換え f3-1:f1内で書き換え f3-2:f3内で別名オブジェクト追加 呼び出し元4:f3内で別名オブジェクト追加 f4-1:f3内で別名オブジェクト追加 f4-2:f4内で別名オブジェクト削除 呼び出し元5:f4内で別名オブジェクト削除 */
undefined
が指定されたものとして扱われる。function f(a,b="default",c=3){ return `${a} - ${b} - ${c}`; } let o ={ message:"初期値", }; console.log(f(5,6,7)); // 5 - 6 - 7 console.log(f(5,6)); // 5 - 6 - 3 console.log(f(5)); // 5 - default - 3 console.log(f()); // undefined - default - 3
const o = { name: "Takeshi", message: function(){return "Hello!";}, } console.log(o.name); // Takeshi console.log(o.message()); // Hello! // 上記を省略記法(ショートハンド)で表現する const o2 = { name: "Takeshi", message(){return "Hello!";}, } console.log(o2.name); // Takeshi console.log(o2.message()); // Hello!
const o = { name: "Takeshi", message(){return `Hello! My name is ${this.name}`;}, } const message = o.message; console.log(message === o.message); // true console.log(o.message()); // "Hello! My name is Takashi" console.log(message); // ƒ message(){return `Hello! My name is ${this.name}`;}
関数式
とは関数宣言に対し、関数名を省略する記法のコト
関数式
は値をとして関数を返す
関数式
は変数
などに代入することが可能関数式
はすぐに呼び出すことも可能関数式
と関数宣言
の違いは実質的にはない
const f = function(){ // ... }
特徴
function
という単語を省略できる。(
と)
を省略できる。{
と}
、それにreturn
を省略できる。通常の関数とは異なる点
this
が他の変数と同様に、語彙的に束縛されるarguments
が使えないconst f1_1 = function(){ return "Hello!";} const f1_2 = () => "Hello!"; console.log(f1_1()); // Hello! console.log(f1_2()); // Hello! const f2_1 = function(name){ return `My name id ${name}`;} const f2_2 = name => `My name id ${name}`; console.log(f2_1("Takeshi")); // My name id Takeshi console.log(f2_2("Takeshi")); // My name id Takeshi const f3_1 = function(a,b){ return a + b;} const f3_2 = (a,b) => a+b; console.log(f3_1(3,5)); // 8 console.log(f3_2(3,5)); // 8
this
を特定の値に指定したうえで、関数を呼び出すcall
の第一引数にはthis
を束縛したい値を指定する
const taro = {name :"Taro"}; const hanako = {name :"Hanako"}; // 通常はthisは使用できない function greet(){ return `My name is ${this.name}`; } console.log(greet.call(taro)); // My name is Taro console.log(greet.call(hanako)); // My name is Hanako console.log(greet()); // error
call
は引数を直接受け取る)
const arr = [2,3,-5,15,7]; console.log(Math.min.apply(null,arr)); // -5 console.log(Math.max.apply(null,arr)) // 15; // スプレッド演算子を利用した場合 console.log(Math.min.apply(...arr)); // -5 console.log(Math.max.apply(...arr)) // 15;
apply
はスプレッド演算子を使用してcall
に置き換えることが可能const taro = {name :"Taro"}; const taro2 = {name :"Taro"}; const arr = [2004,"student"]; function update(birthyear,occupation){ this.birthyear = birthyear; this.occupation = occupation; }; // applyの場合 update.apply(taro,arr); console.log(taro); // {name: "Taro", birthyear: 2004, occupation: "Student"} update.call(taro2,...arr); console.log(taro2); // {name: "Taro", birthyear: 2004, occupation: "Student"}
this
の値をある関数と永続的に結びつけることができる。
bind
でセットされた値は、call
・apply
・別のbind
とも結びつく演算子 | 説明 | 例 | 備考 |
---|---|---|---|
+ | 加算(文字列連結も可) | 3 + 2 | |
- | 減算 | 3 - 2 | |
/ | 除算 | 3 / 2 | |
* | 乗算 | 3 * 2 | |
% | 除算の余り | 3 % 2 | |
- | 単項符号反転 | -x | 符号が反転する |
+ | 単項プラス | +x | xが数値でない場合は数値への返還を試みる |
++ | 前置インクリメント | ++x | |
++ | 後置インクリメント | x++ | |
-- | 前置デクリメント | --x | |
-- | 後置デクリメント | x-- |
演算子 | 内容 | 記号 |
---|---|---|
厳密等価演算子 (厳密不等価演算子) |
- 同じオブジェクトを参照している - プリミティブ型でデータ型も値も同じである |
=== (!==) |
等価演算子 不等価演算子 |
- 同じオブジェクトを参照している - 同じ値に変換されるとき |
== (!=) |
"1"
と1
が等価とみなされる。""(空文字)
、0
、null
、undefined
が等価とみなされる。演算子 | 内容 | 例 |
---|---|---|
< | より大きい | a < b |
<= | 以上 | a <= b |
> | 未満 | a > b |
>= | 以下 | a >= b |
数値を比較する際の注意
NaN
はNaN自身
を含めどの値とも等しくなりません。
NaN === NaN
はfalse
、NaN == NaN
もfalse
。x
が数値かどうかを確認する場合は、isNaN(x)
を使用する。
isNaN(x)
はx
が数字でない場合(NaN
を含む)はtrue
を返す。それ以外はfalse
を返す。数値は全て倍精度小数点なので、小数部分を含む値を===
で比較すると計算誤差が生じて想定通り比較できない場合がある。
Number.EPSILON
という特殊な定数(二つの定数が等しいとみなすことができる差)がある。if(Math.abs(x-y) < Number.EPSILON){ console.log('same value!'); } else { console.log('different value!'); }
+
には「数値の足し算」と「文字列の連結」の意味がある。
被演算子の値を左から右に評価する。
組み合わせ | 結果 |
---|---|
両方が数値の場合 | 足し算 |
どちらかが文字列の場合 | 文字列の連結 |
console.log(3+5+"8"); // "88" console.log("3"+5+8); // "358"
true
とfalse
以外も扱うことが可能
数値
だけでなくデータ型
も評価対象となる。false とみなされる値 |
true とみなされる値 |
---|---|
undefined null false 0 NaN ""(空文字列) |
任意のオブジェクト 任意の配列 " ”(空白のみの文字列) 文字列"false" |
内容 | 記号 |
---|---|
論理積(AND) | && |
論理和(OR) | || |
論理否定(NOT) | ! |
// inputName に値がセットされていないときはdefaultNameを使用する。 const inputName ="TestName"; const name = inputName || defaultName; console.log(name); const inputName2 =""; const name2 = inputName2 || {name:"defaultName"}; console.log(name2);
JavaScriptで唯一の三項演算子(3つの被演算子を使う)
オブジェクトの要素を初期化する際のコードのサンプル
const inputName ="TestName"; const profile = {}; profile.name = inputName ? inputName : defaultName; console.log(profile);
forループ
の内部で利用されることが多い// 例1 // 1-1 let x = 0 , y = 100 , z; z = ( x++ , y++ ); console.log(z); // 100 // 1-2 x = 0 , y = 100; z = x++ , y++; console.log(z); // 0
演算子 | 説明 | 例 |
---|---|---|
& | ビット毎のAND | 0b1010 & 0b1100 // 結果は 0b1000 |
| | ビット毎のOR | 0b1010 | 0b1100 // 結果は 0b1110 |
^ | ビット毎のXOR | 0b1010 ^ 0b1100 // 結果は 0b0110 |
~ | ビット毎のNOT | ~0b1010 // 結果は 0b0101 |
<< | 左シフト | 0b1010 << 1 // 結果は 0b10100 0b1010 << 2 // 結果は 0b101000 |
>> | 符号を維持する右シフト | 0b1010 << 1 // 結果は 0b10100 0b1010 << 2 // 結果は 0b101000 |
>>> | ゼロ埋め右シフト |
let n = 22; console.log(n.toString(2)); // 10110 console.log((n >> 1).toString(2)); // 1011 console.log(n >>> 1).toString(2)); // 1011 n = ~n; console.log(n.toString(2)); // -10111 n++; console.log(n.toString(2)); // -10110 console.log((n >> 1).toString(2)); // -1011 console.log((n >>> 1).toString(2)); // 1111111111111111111111111110101
console.log(typeof undefined); // "undefined" console.log(typeof null); // "object" <- 実際の型と不一致 console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(typeof true); // "boolean" console.log(typeof 1); // "number" console.log(typeof ""); // "string" console.log(typeof Symbol()); // "symbol" console.log(typeof function(){}); // "function"
undefined
を返す演算子 | 意味 |
---|---|
x += y | x = x + y |
x -= y | x = x - y |
x *= y | x = x * y |
x /= y | x = x / y |
x %= y | x = x % y |
x <<= y | x = x << y |
x >>= y | x = x >> y |
x >>>= y | x = x >>> y |
x &= y | x = x & y |
x |= y | x = x | y |
x ^= y | x = x ^ y |
// 1 const obj = {b:2,c:3,d:4}; const {a,b,c} = obj; console.log(a); // undefined console.log(b); // 2 console.log(c); // 3 console.log(d); // Uncaught ReferenceError: d is not defined // 2 const obj = {b:2,c:3,d:4}; let a,b,c; ({a,b,c} = obj); console.log(a); // undefined console.log(b); // 2 console.log(c); // 3 console.log(d); // Uncaught ReferenceError: d is not defined // 3 const arr = [1,2,3]; let [x,y] = arr; console.log(x); // 1 console.log(y); // 2 // 4 const arr = [1,2,3,4,5]; let [x,y,...rest] = arr; console.log(x); // 1 console.log(y); // 2 console.log(rest); // [3,4,5] // 5 let a = 5, b = 10; [a,b] = [b,a]; console.log(a); // 10 console.log(b); // 5
演算子 | 説明 |
---|---|
. | プロパティ(メンバー)へのアクセス |
delete | (プロパティ(メンバー))の削除 |
[] | 計算値でのメンバーアクセス |
in | プロパティの有無を調べる |
new | オブジェクトのインスタンスを生成する |
instanceof | プロトタイプチェインをテストする |
... | 展開 |
語句 | 内容 |
---|---|
break | ループを途中で抜ける |
continue | ループ内で、実施中の繰り返し処理を終了して、次の繰り返し処理に進む。 |
return | 現在の関数を終了する |
throw | 例外ハンドラでキャッチする必要がある「例外」を示す |
while(条件) 文
以下は無限ループの代表例
while(true){ console.log('永遠は存在する。'); }
if(条件) 文1 [else 文2]
do 文 while(条件);
文
は少なくとも1回は実行されるfor([初期化],[条件],[再設定]) 文
①初期化
->②条件
->③文
->④再設定
」
②条件
の結果がfalse
の場合、ループを抜ける(③へは進まない。)
break
、return
、throw
でもループを抜ける。,
を使用すると複数条件をまとめてセットすることができる。以下は無限ループの代表例
for(;;){ console.log('永遠は存在する。'); }
switch(式){ case 値1: 文1 [break;] case 値2: 文2 [break;] ... default: 文default [break;]
①:式の評価
->②:①の結果と一致するcaseの値を探す。
->③:ヒットしたcase以下の文を実施
」
default
がある場合はdefault
以下が実行される。default
がない場合は何も実行されない。switch文
のスコープを抜ける条件は以下
break文
、return文
、continue文
、throw文
が実行される。switch文
の一番最後まで到達する。case
の末尾にbreak
を記述せずに、次のcase
を記述する制御フローをfall-through
と呼ぶ。let message = ''; let n = Math.floor(Math.random()*6+1); switch(n){ case 1: case 3: case 5: message = '奇数です'; break; default: message = '偶数です'; break; } console.log(message);
for(変数 in オブジェクト) 文
const profile = { name : 'taro', sex : 'male', age : 25, test: { test1:1, test2:"2", }, sample: { sample1, sample2, } }; for(let prop in profile){ if(!profile.hasOwnProperty(prop))continue; console.log(prop + ':'+profile[prop]); } /* name:taro sex:male age:25 test:[object Object] sample:sample1,sample2 */
for(変数 of オブジェクト) 文
const check = ['name','sex']; const profile = { name : 'taro', sex : 'male', age : 25, }; for(let prop of check){ // check と一致するキーが存在したら、キーごと削除する。 if(profile[prop]){ delete profile[prop]; } } console.log(profile);