ES2015のクラスと基本

ES2015からJavascriptも正式にオブジェクト指向のクラスに対応するようになった。

ブラウザ対応状況

2017年1月時点では4大ブラウザ、Opera,Chrome,Firefox,Edgeで対応している。
しかし、IE11は未対応である。

Eclipseでの対応

Elipse Neon はES2015をデフォルトでサポートしている。
ただし初期状態ではjsファイルは表示されないので次の設定を必要とする。
	Window → Preferences → JavaScript → Validator
	「Source type:」でModuleを選択する。
	

検証

基本的なクラス


	$(function(){
		var animal = new Animal('ネオンテトラ');
		animal.test_func();
	});
	
	class Animal{
		
		constructor(animal_name){
			this.name = animal_name;
		}
		
		test_func(){
			let name = this._test2();
			console.log(`hello_world=${name}`);
		}
		
		_test2(){
			return this.name;
		}
	}
	

注意点

publicメソッドとprivateメソッドを区別するコードがないようである。
引き続き、privateメソッドの先頭に「_」を付加する慣習を採用した方が無難である。

メンバまたはプロパティは、constructorメソッド内で宣言しなければならない。
class名の直下に記述することはできない。

新たにコンストラクタ(constructor)が使えるようになった。
constructorの引数は、クラス生成時に指定する。

letとconst

変数宣言にletとconstが使えるようになった。
letは変数、constは定数に用いる。
varも引き続き利用できる。
letはvarと異なり、ブロック内でのみ有効な変数である。

文字列の埋込

変数を文字列に埋め込めるようになった。
ただし、バッククォートで文字列を囲む必要がある。
let str = `動物の名前は${animal_name}です`


コールバック地獄対策 | Promise

デモ


	Promise.resolve()
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res').append('コールバック1<br>');
				fulfilled(); // →達成:コールバック2へ
			},1000);
		})
	})
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res').append('コールバック2<br>');
				fulfilled(); // →達成:コールバック3へ
			},1000);
		})
	})
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res').append('コールバック3<br>');
				fulfilled();
			},1000);
		})
	});
	

クラス版のPromiseの使い方

デモ


	function test2(){
		var promiseTest = new PromiseTest();
		promiseTest.func1();
	}
	
	class PromiseTest{
		
		constructor(){
			this.test_a = 999;
		}
		
		func1(){
			Promise.resolve()
			.then(() => {
				return new Promise((fulfilled, rejected) => {
					window.setTimeout(() => {
						$('#res').append(this.test_a + ' コールバック1<br>');
						this.test_a ++;
						fulfilled();
					},1000);
				})
			})
			.then(() => {
				return new Promise((fulfilled, rejected) => {
					window.setTimeout(() => {
						$('#res').append(this.test_a + ' コールバック2<br>');
						this.test_a ++;
						fulfilled();
					},1000);
				})
			})
			.then(() => {
				return new Promise((fulfilled, rejected) => {
					window.setTimeout(() => {
						$('#res').append(this.test_a + ' コールバック3<br>');
						this.test_a ++;
						fulfilled();
					},1000);
				})
			})
			;
			
		}
	}
	

Promiseのエラーキャッチ | rejected

デモ


	Promise.resolve()
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res3').append('コールバック1X<br>');
				fulfilled();
			},1000);
		})
	})
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res3').append('コールバック2<br>');

				rejected('リジェクト:エラーキャッチのテストです。');

			},1000);
		})
	})
	.then(function(){
		return new Promise(function(fulfilled, rejected){
			window.setTimeout(function(){
				$('#res3').append('コールバック3<br>');
				fulfilled();
			},1000);
		})
	}).catch(function(e) {
		console.log(e);
		alert(e);
		
    })
	;
	

仮想DOMとは | Virtual DOM

仮想DOMはVirtual DOMのことである。
Virtual DOMはJavaScriptのデータと連動しているHTMLのDOMのこと。
JavaScript側でデータを変更すると連動してDOM側の表示も変わる。この部分のコーディングは不要である。
逆にDOM側(テキストボックスなど)に一般ユーザーが入力を行うと、何もせずともJavaScript側のデータにも反映される。

もちろん最初に、通常のDOMとデータを連携(データバインド)設定は必要になる。
Virtual DOMは、Vue.jsやReact.jsなどが実装している。


ES6のthisとjQuery.eachのthisが競合してしまう問題


	function main(){
		var obj = new Animal();
		obj.funcA();
	}
	
	class Animal{
	
		funcA(){
			$('ul li').each((i,elm) => {
				var animal_name = $(elm).html();
				this._funcB(animal_name);
			});
		}
		
		_funcB(animal_name){
			console.log(animal_name);
		}
	}
	

ES6のthisとjQuery.clickのthisが競合してしまう問題


	$('#btn1').click(evt=>{
		var btnElm = $(evt.currentTarget);
		alert(btnElm.val());
	});
	

ES6のヒアドキュメント

ソースコード中の改行がそのまま\nと認識される。
${}で文字列に埋め込むこともできる。


	var str1 = '苦しんでいる者たちを地から';
	var str2 = `歯が剣,
		そのあご骨が屠殺用の刀となっており,${str1},
		貧しい者たちを人の中から食い尽くそうとする世代がある`;
	
	console.log(str2);
	
コンソール出力
歯が剣,
		そのあご骨が屠殺用の刀となっており,苦しんでいる者たちを地から,
		貧しい者たちを人の中から食い尽くそうとする世代がある
	

参考

クラスの継承

DEMO

JavaScript

	$(()=>{
		var neko = new Neko();
		neko.test1();
		neko.test2();
	});
	
	class Animal{
		
		constructor(){
			$("#res1").append('Animalクラスのconstructorが呼び出されました。<br>');
		}
		
		test1(){
			$("#res1").append('Animalクラスのtest1メソッドが呼び出されました。<br>');
		}
	}
	
	// ※注意 : サブクラス(Neko)は基本クラス(Animal)の下に記述すること
	class Neko extends Animal{
		
		constructor(){
			super();
			$("#res1").append('Nekoクラスのconstructorが呼び出されました。<br>');
		}
		
		test2(){
			$("#res1").append('Nekoクラスのtest2メソッドが呼び出されました。<br>');
			this.test1();
		}
	}
	

出力
	Animalクラスのconstructorが呼び出されました。
	Nekoクラスのconstructorが呼び出されました。
	Animalクラスのtest1メソッドが呼び出されました。
	Nekoクラスのtest2メソッドが呼び出されました。
	Animalクラスのtest1メソッドが呼び出されました。
	

ES6クラス内のファイルアップロードイベントで「this」が重複して使えなる問題

デモ

ES6クラスの「this」とchangeイベント「this」が競合する問題が起きる。
下記のサンプルではアロー演算子を使って問題を回避している。

HTML


	<input id="img_fn" type="file" name="img_fn" accept="image/*" /><br>
	<img id="img1" src="" alt="" style="width:200px;height:200px" />
	<div id="res" class="text-success"></div>
	

JavaScript


	$(() => {
		
		var fileuploadImg = new FileuploadImg();
	
	});
	
	/**
	 * ES6のクラス
	 */
	class FileuploadImg{
	
		constructor(param){
			
			jQuery("#img_fn").change(e => {
	
				this.test(); // thisは当クラスを指しているならメソッドを呼び出せる。
	
			});
		}
		
		test(){
			this.output('thisによるメソッドの呼び出しテスト。');
		}
		
		output(msg){
			console.log(msg);
			jQuery("#res").append(msg + '<br>');
		}

		
	}