javascript アロー関数のサンプル

javascript アロー関数のサンプル

ES2015(ES6)から利用できるJavaScriptの構文であるアロー関数のサンプルコードを記述してます。アロー関数を使用することにより「function」を記述することがないので、より簡潔にコードを書くことができます。

環境

  • OS windows11 pro 64bit
  • Apache 2.4.43
  • ブラウザ chrome 108.0.5359.99

アロー関数サンプル

以下は、通常の関数をアロー関数で記述したサンプルとなります。

通常の関数の場合

function sample(a, b){
  return a + b;
}

<出力結果>
console.log(sample(1,2)); // 3

これをアロー関数で記述すると、以下のように記述することができます。

const sample = (a, b) => {
  return a + b;
};

<出力結果>
console.log(sample(1,2)); // 3

即時関数として利用

アロー関数は、以下のように、すぐ実行できる「即時関数」としても、利用できます。

((a, b) => { console.log(a + b); })(1, 2); // 3

return省略

return命令を省略することも可能です。

const sample  = (a, b) => a + b;

<出力結果>
console.log(sample(1,2)); // 3

ただし、オブジェクト返す場合は、( )がなければエラーとなります。

const sample  = (a, b) => { x : a , y : b };

<出力結果>
Uncaught SyntaxError: Unexpected token ':'

constt sample  = (a, b) => ({ x : a , y : b });

( )を使用するとエラーにはなりません。

const sample  = (a, b) => ({ x : a , y : b });

console.log(sample(1,2)); // {x: 1, y: 2}

改行もできます。

const sample  = (a, b) => 
a + b

console.log(sample(1,2)); // 3

ただし「=>」の前で改行するとエラーとなります。

const sample  = (a, b) 
=> a + b

// Uncaught SyntaxError: Unexpected token '=>'

引数が1つ

引数が1つしかない場合は、()も省略して記述することができます。

const sample = a => a * 3;

<出力結果>
console.log(sample(1)); // 3

引数なし

引数がない場合は、以下のように記述することができます。

const sample = () => console.log('Hello world'); 

<出力結果>
sample(); // Hello world

厳格モード

厳格モードでもエラーにはなりません。

'use strict';

const sample = () => console.log('Hello world'); 

async

async functionもアロー関数で記述できます。

async function sample() {
  return Promise.resolve("hello");
}

sample().then(function(v) {
  console.log(v) // hello
});

上記のコードをアロー関数で記述すると、以下のようになります。

const sample = async () => {
  return "hello";
}

sample().then(v => console.log(v)); // hello

サンプルコード

filterなどのコールバック関数に使用すると、コードを短縮化することができます。

通常の関数

[1, 2, 3, 4, 5].filter(function (n) { return n > 2 });
// [3, 4, 5]

アロー関数

[1, 2, 3, 4, 5].filter(n => n > 2);
// [3, 4, 5]

その他は下記に記載してます。

thisの参照先の違い

thisの参照先

アロー関数と通常の関数では、呼び出し方によっては、thisの参照先が異なります。

this.str = 'a';

function hoge() {  
  console.log(this.str);
}

const foo = () => {  
  console.log(this.str);
};

hoge(); // a
foo();  // a

const func = {
  str: 'b',
  f: hoge
};

const arrowfunc = {
  str: 'c',
  f: foo
};


func.f(); // b
arrowfunc.f(); // a

アロー関数の場合は「宣言された時点で、thisが確定」され、
通常の関数は「宣言された時点では、thisが何かは決まってない」ので呼び出し元により、変わります。

例えば以下のように、通常の関数の場合は、宣言された元のオブジェクトが参照されますが、

this.str = 'hello';

function hoge(){
  console.log(this.str);
}

let obj1 = {
  str: 'obj1です',
  f: hoge
}
let obj2 = {
  str: 'obj2です',
  f: hoge
}

obj1.f(); // obj1です
obj2.f(); // obj2です

アロー関数の場合は、宣言された時点でthisが確定されます。ようするにアロー関数はthisを持っていないことになります。

this.str = 'hello';

const foo = () => {
  console.log(this.str);
}

let obj1 = {
  str: 'obj1です',
  f: foo
}
let obj2 = {
  str: 'obj2です',
  f: foo
}

obj1.f(); // hello
obj2.f(); // hello

ちなみに、「use strict」で厳格モード時は以下の場合は、エラーとなります。

'use strict';

this.str = 'a';

function hoge() {  
  console.log(this.str);
}

hoge();
// Uncaught TypeError: Cannot read property 'str' of undefined

アロー関数は、thisを持たないので、以下のようなコードを実行するとwindowオブジェクトを参照します。

console.log(`グローバルの${this}`);  // window 

const func = {  
  f: function () {
        console.log(`通常の${this}`);
    }
};

const arrowfunc = {  
  f: () =>console.log(`アローの${this}`)
};


func.f(); // Object
arrowfunc.f(); // window

実行結果

addEventListenerに使用する

例えば「onclick」イベントを通常の関数とアロー関数で記述した場合は「this」の参照先が異なります。

通常の関数の場合は、ハンドラー(コールバック関数)の中の「this」の値は要素への参照となるため「button」そのものが参照されます。

<button id="main">実行</button>

<script>

document.getElementById('main').addEventListener('click',
  function () {
    console.log(this);
  }
)

// onclick
document.getElementById('main').onclick = function(){ 
  console.log(this);
};

</script>

実行結果(通常の関数)

アロー関数の場合は、windowオブジェクトが参照されます。

<button id="main">実行</button>

<script>

document.getElementById('main').addEventListener('click',
  () => {
    console.log(this);
  }
)

// onclick 
document.getElementById('main').onclick = () => { 
  console.log(this);
};

</script>

実行結果(アロー関数)

なので、アロー関数は通常の関数のように、windowオブジェクトが参照する際に、bind()メソッドを使用しなくてもよくなります。

<button id="main">実行</button>

<script>

document.getElementById('main').onclick = function(){ 
  console.log(this);
}.bind(this);

</script>

実行結果(通常の関数 bind使用時)

また、イベントハンドラーを指定しないと「removeEventListener」は機能しないので、アロー関数は使用できません。

<button id="btn1">ボタン</button>
<button id="btn2" onclick="hoge()">除去</button>

<script>

window.onload = () =>{
  btn1.addEventListener('click', (e) => { console.log('hoge') });  
}

const hoge = () =>{
  btn1.removeEventListener('click', (e) => { console.log('hoge') })
}

</script>

アロー関数を、使用する場合は以下のようにします。

<button id="btn1">ボタン</button>
<button id="btn2" onclick="hoge()">除去</button>

<script>

const foo = (e) => { console.log('hoge') }

window.onload = () =>{
  btn1.addEventListener('click', foo);  
}

const hoge = () =>{
  btn1.removeEventListener('click', foo)
}

</script>

実行結果

コールバック関数に利用

また、アロー関数はコールバック関数に利用すると同様にbind()メソッド使用しなくてもよくなります。

const hoge = function (name) {
  this.name = name;
};

hoge.prototype.func = function () {

  // 通常関数なのでthisには yamadaがセットされる
  console.log(this); // hoge {name: "yamada"}

  // アロー関数なので、thisを持たないので外側のthisを参照する
  setInterval(() => {
    console.log(this);  // hoge {name: "yamada"}
    console.log(this.name); // yamada
  }, 1000);

};

// 関数をnewする
(new hoge('yamada')).func();

実行結果(アロー関数)

通常の関数の場合は、thisを持つので、この場合はwindowオブジェクトを見ます。

const hoge = function (name) {
  this.name = name;
};

hoge.prototype.func = function () {
  
  console.log(this); // hoge {name: "yamada"}
  
  // 関数はthisを持つので、この場合はwindowオブジェクトを見る
  setInterval(function(){
    console.log(this);  // windowオブジェクトを見る
    console.log(this.name); // 値なし
  }, 1000);

};

// 関数をnewする
(new hoge('yamada')).func();

実行結果(通常の関数)

その他の違い

newできない

アロー関数は、newすることができません。コンストラクタとして使用することができません。

function hoge() {
  console.log('Hello world');
}
const foo = () => console.log('Hello world');

new hoge();
new foo(); // Uncaught TypeError: foo is not a constructor

なので、以下のような使用方法はできません。

function hoge( name ){ this.name = name; };
console.log( new hoge( 'yamada' ) ); 
// hoge {name: "yamada"}

const foo = ( name ) => { this.name = name; };
console.log( new foo( 'yamada' ) ); 
// Uncaught TypeError: foo is not a constructor

継承できない

継承することもできません。

function hoge() {}
const foo = () => {}

class Hoge extends hoge {}
class Foo extends foo {} // Uncaught TypeError: Class extends value () => {} is not a constructor or null

arguments使用できない

argumentsを使用することもできません。

function hoge(a, b) {
  let a = arguments[0]
}

const foo = (a, b) => {let a = arguments[0]}

hoge(1,2);
foo(1,2); // Uncaught ReferenceError: arguments is not defined

ie11でエラー

ie11ではアロー関数は、構文エラーとなります。

function hoge() {
  console.log('Hello world');
}
const foo = () => console.log('Hello world');

アロー関数のブラウザ対応状況はこちらで確認できます。

また無名関数であれば、ie11でも利用することは可能です。

const foo = function() { console.log('Hello world')}

foo();

呼び出す順番

アロー関数は、コードを記述してからでないと呼び出せません。

hoge();

function hoge() {
  console.log('Hello world');
}

foo(); // Uncaught ReferenceError: Cannot access 'foo' before initialization

const foo = () => console.log('Hello world');

無名関数も同様なので、変数の宣言順序によるエラーとなります。

bar(); // console.html:30 Uncaught ReferenceError: Cannot access 'bar' before initialization

const bar = function(){console.log('Hello world')};

prototypeプロパティ

アロー関数に、prototypeプロパティはありません。

function hoge() {}
const foo = () => {}

console.log(typeof hoge.prototype) // object
console.log(typeof foo.prototype) // undefined

同じ名前の引数

アロー関数の場合は、同じ名前の引数を使用することはできません。

function hoge(a, a){
  return a + a;
}

console.log(hoge(1,2)); // 4

const foo = (a, a) => {
  return a + a;
}; // Uncaught SyntaxError: Duplicate parameter name not allowed in this context

console.log(foo(1,2));

ちなみに、「use strict」で厳格モード時は通常の関数でもエラーとなります。

'use strict';

function hoge(a, a){
  return a + a;
} // Uncaught SyntaxError: Duplicate parameter name not allowed in this context

アロー関数を使用しない方がいいパターン

オブジェクト内でのthisの参照

以下のように、thisをオブジェクト内のメソッドで参照している場合は
「NAN」が返ります。

const obj = {
  num: 5,
  f1: (x) => 5 * x,
  f2: function (x) { return this.num * x; },
  f3: (x) => this.num * x,
};
console.log(obj.f1(3));  // 15
console.log(obj.f2(3));  // 15
console.log(obj.f3(3));  // NAN

prototypeメソッドでも同じです。

const obj = function() { this.num = 5; };

obj.prototype = {  
  f1: (x) => 5 * x,
  f2: function (x) { return this.num * x; },
  f3: (x) => this.num * x,
};

const Obj = new obj;

console.log(Obj.f1(3));  // 15
console.log(Obj.f2(3));  // 15
console.log(Obj.f3(3));  // NAN

イベント発生時に自身を操作したい場合

「onclick」イベント時に、クリックした要素自体の色を変えたい時などの場合に、thisを使用するとアロー関数の場合はエラーとなります。

document.getElementById('main').onclick = () => {
  this.style.backgroundColor = "orange";
};

実行結果(アロー関数)

通常の関数の場合は、正しく動作します。

/* html */

<button id="main">実行</button>

/* javascript */

document.getElementById('main').onclick = function(){
  this.style.backgroundColor = "orange";
};

実行結果(通常の関数)