LoginSignup
13
14

More than 5 years have passed since last update.

JavaScript(ES2015/ES6)予習会

Last updated at Posted at 2015-10-11

概要

勉強会資料 ver0.01

2015/10/16(金) 19:30 - 20:30
JavaScript(ES2015/ES6)予習会
http://fukuoka-cam-study.connpass.com/event/21220/

参考資料

ざっくり概要

予習のコーディングで使うサービス

アロー関数 Arrow Functions

var getEl = function(elementId){
  return document.getElementById(elementId);
};
window.onload = function() {
  var el1 = getEl("main-el-1");
  el1.textContent = "This is main-el-1";
};

↓functionをアロー関数に↓

var getEl = (elementId)=> document.getElementById(elementId);

window.onload = () =>{
  var el1 = getEl("main-el-1");
  el1.textContent = "This is main-el-1";
};

var getEl = (elementId)=> document.getElementById(elementId);

window.onload = () =>{
  var ids = ["main-el-1","main-el-2"];
  ids.forEach(function(id){
    getEl(id).textContent = "This is " + id;
  });
};

↓forEachのfunctionをアロー関数に↓

  ids.forEach(id=>getEl(id).textContent = "This is " + id);

テンプレート Template Strings

window.onload = () =>{
  var ids = ["main-el-1","main-el-2"];
  ids.map(id=>getEl(id).textContent = "This is " + id);
};

↓文字列連結をテンプレートに↓

  ids.map(id=>getEl(id).textContent = `This is ${id}`);

クラス Classes

クラス定義 Class Definition

var getEl = (elementId)=> document.getElementById(elementId);

window.onload = () =>{
  var ids = ["main-el-1","main-el-2"];
  ids
    .map(id=>new UiLabel(id, `This is ${id}!`))
    .map(label=>label.render());
};

var  UiLabel = function(id, text){
  this.id = id;
  this.text = text;
};

UiLabel.prototype.render = function(){
  getEl(this.id).textContent = this.text;
};

↓prototypeをclassを使った書き方に↓

class UiLabel {
  constructor(id,text){
    this.id = id;
    this.text = text;
  }
  render(){
    getEl(this.id).textContent = this.text;
  }
} 

継承 Class Inheritance

// Base Class
var UiBase = function(id){
  this.id = id;  
};

UiBase.prototype.getEl = function(elementId){
  return document.getElementById(elementId);
};

// Sub Class
var UiLabel = function(id, text){
  UiBase.call(this, id);
  this.text = text;
};

UiLabel.prototype = Object.create(UiBase.prototype);
UiLabel.prototype.constructor = UiLabel;

UiLabel.prototype.render = function(){
  this.getEl(this.id).textContent = this.text;
};

↓callやObject.createからextendsへ↓

// Base Class
class UiBase {
  constructor(id){
    this.id = id;
  }

  getEl (elementId){
    return document.getElementById(elementId);
  }
}

// Sub Class
class UiLabel extends UiBase {
  constructor(id, text){
    super(id);
    this.text = text;
  }

  render(){
    this.getEl(this.id).textContent = this.text;
  }
}

スタティックメソッド Classes Static Members

window.onload = () =>{
  var ids = ["main-el-1","main-el-2"];
  ids
    .map(id=>UiUtil.create(id))
    .map(label=>label.render());
};

var UiUtil = function() {};
UiUtil.create = function(id){
  return new UiTextBox(id,`This is ${id}!`);
};

↓staticを使って書き換え↓

window.onload = () =>{
  var ids = ["main-el-1","main-el-2"];
  ids
    .map(id=>UiUtil.create(id))
    .map(label=>label.render());
};

class UiUtil {
  static create(id){
    return new UiTextBox(id,`This is ${id}!`);
  }
}

分割代入 Destructuring Assignment

window.onload = () =>{
// ...省略...
  ids
    .map(obj=>UiUtil.create(obj.id, obj.type))
    .map(label=>label.render());
};

class UiUtil {
  static create(id, type){
    if (type === UiUtil.TYPE.LABEL){
      return new UiLabel(id,`This is ${id}!`);
    }
    return new UiTextBox(id,`This is ${id}!`);
  }
// ...省略...
}

↓関数引数での分割代入↓

window.onload = () =>{
// ...省略...
  ids
    .map(obj=>UiUtil.create(obj))
    .map(label=>label.render());
};

class UiUtil {
  static create({id, type}){
    if (type === UiUtil.TYPE.LABEL){
      return new UiLabel(id,`This is ${id}!`);
    }
    return new UiTextBox(id,`This is ${id}!`);
  }  
// ...省略...
}

関数パラメータの拡張

デフォルトパラメータ

window.onload = () =>{
  var ids = [
    {id: "main-el-1"},
    {id: "main-el-2", type: UiUtil.TYPE.INPUT}
  ];

  ids
    .map(obj=>UiUtil.create(obj.id, obj.type))
    .map(label=>label.render());
};

class UiUtil {
  static create(id, type){
    type = (type===undefined)? UiUtil.TYPE.LABEL: type;
    if (type === UiUtil.TYPE.LABEL){
      return new UiLabel(id,`This is ${id}!`);
    }
    if (type === UiUtil.TYPE.INPUT){
      return new UiTextBox(id,`This is ${id}!`);
    }
    throw new Error("No UI!");
  }
// ...省略...
}

↓typeのデフォルトパラメータでLABEL設定↓

class UiUtil {
  static create(id, type = UiUtil.TYPE.LABEL ){
    if (type === UiUtil.TYPE.LABEL){
      return new UiLabel(id,`This is ${id}!`);
    }
    if (type === UiUtil.TYPE.INPUT){
      return new UiTextBox(id,`This is ${id}!`);
    }
    throw new Error("No UI!");
  }

// ...省略...
}

アロー関数 Arrow Functions

thisの動きが違います

class UiTextBox extends UiBase {
// ...省略...
  setEvents(){
    var _this = this;
    this.el.addEventListener("change",function(){
      _this.handlers.forEach(
        (handler)=>handler(_this.el.value)
      )
    });
  }
// ...省略...
}

↓functionをアロー関数に↓

  setEvents(){
    this.el.addEventListener("change", ()=>
      this.handlers.forEach((handler)=>handler(this.el.value))
    );
  }

ブロックスコープ

let

class UiLabel extends UiBase {
  constructor(id, model){
    super(id, model);
  }

  render(){
    this.getEl(this.id).innerHTML = null;
    for (var i=0; i<3; i++){
      var span = document.createElement("span");
      span.textContent = ` ${i}:${this.model.text} `;
      setTimeout(
        ()=>this.getEl(this.id).appendChild(span)
      , 1000*i);
    }
  }
}

↓varをletに変えると動作が変わります↓

class UiLabel extends UiBase {
  constructor(id, model){
    super(id, model);
  }

  render(){
    this.getEl(this.id).innerHTML = null;
    for (let i=0; i<3; i++){
      let span = document.createElement("span");
      span.textContent = ` ${i}:${this.model.text} `;
      setTimeout(
        ()=>this.getEl(this.id).appendChild(span)
      , 1000*i);
    }
  }
}

クラス Classes

Getter/Setter が使えます

class Model {
  constructor(text){
    this.text = text;
  }
}

↓値を設定するときに処理を挟めます↓

class Model {
  constructor(text){
    this.version = 1;
    this._preText = "";
    this._text = text;
  }

  set text(text){
    if ( this._text === text ){
      return;
    }
    this.version++;
    this._preText = this._text;
    this._text = text;
    console.log(`ver ${this.version} pre: ${this._preText}`);
  }

  get text(){
    return this._text;
  }
}

関数パラメータの拡張

Rest Parameter

window.onload = () =>{
  var model = new Model("hello");
  UiUtil.createEls(
    model,
    {id: "main-el-1"},
    {id: "main-el-2", type: UiUtil.TYPE.INPUT},
    {id: "main-el-3"}
    // ...増やしたいだけ増やす...
  );
};

class UiUtil {
  static createEls(model){
    var handlers = [];
    var ids = Array.prototype.slice.call(arguments, 1);

    var els = ids.map(obj=>UiUtil.create(obj.id, obj.type, model))
                 .map((el)=>el.setHandlers(handlers));

    var handler = (value)=> {
      model.text = value;
      els.forEach((el)=>el.render());
    };

    handler(model.text);
    handlers.push(handler);
  }
// ...省略...
}

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
slice メソッドは 「配列の様なオブジェクト」も変換する事が可能です。配列の様なオブジェクトの一例として、arguments(関数が受け取った引数)が挙げられます。

↓argumentsを変換してとっていたのが ...でとれる↓

  static createEls(model, ...ids){
    var handlers = [];

    var els = ids.map(obj=>UiUtil.create(obj.id, obj.type, model))
                 .map((el)=>el.setHandlers(handlers));

// ...省略...
  }

Generator Functions

var f = function(){
  var cnt = 0;
  return function(){
    cnt++;
    if (cnt===1){
      return "aaa";
    }
    if (cnt===2){
      return "bbb";
    }
  };
}();
window.onload = function() {
  console.log(f());
  console.log(f());
}

↓yieldで書くと↓

var f = function *(){
  yield "aaa";
  yield "bbb";
};
window.onload = function() {
  var gene = f();
  console.log(gene.next().value);
  console.log(gene.next().value);
}


TODO

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14