yano3nora
7/1/2017 - 9:40 AM

[js: note] Basic knowledge of JavaScript for recruiter. #js

[js: JavaScript Note] Basic knowledge notes of JavaScript. #js

OVERVIEW

JavaScript という言葉は狭義には Mozilla が仕様を策定し実装しているスクリプト言語を指す。 このスクリプト言語は Ecma インターナショナルで ECMAScript (ECMA-262) として標準化されており、多くのウェブブラウザ等はこの標準化された ECMAScript を実装している。(Wikipedia)

WEB 上でインタラクティブな表現をする為に開発されたオブジェクト指向のスクリプト言語。現在ブラウザ上で動作(ブラウザ上で解釈・実行される)する唯一のプログラミング言語。Ajax による非同期通信や HTML5 ウェブプラットフォームの普及、近年の SPA などリッチクライアントアプリの流行を受け急成長した。また、それとは別に Node.js など新たなプラットフォームの出現により、サーバサイドでの実行環境も整備されつつあり、フロントエンド~バックエンドまで利用ケースが拡大している。

History of JavaScript / EcmaScript

[基礎知識] JavaScriptの歴史
JavaScript: The First 20 Years - JavaScriptの歴史については「JavaScript: The First 20 Years」を読む
JavaScript 25 周年

以下のような歴史をたどっており、名前も仕様もかなりこんがらがっとる。Web リファレンスの検索時は「一体いつの情報なのか?」に注意。

  1. ネスケから始まり色んなブラウザで勝手気ままに実装された黎明期
  2. Ecma 社が標準化をめざす → es3 (ブラウザ主軸)
  3. なんか迷走してすげー黒歴史言語に → es4 (没アプデ)
  4. Ajax の流行と HTML5 を契機に需要が拡大 → es5 (機能拡張版でモダンブラウザほぼ対応)
  5. もういい加減普通の言語っぽくしたいけど後方互換もしたい → ES2015 (es6: クラスベースのモダンJSでモダンブラウザでも実装はまちまち)
  6. jQuery いらなくね?論とか出てくる

Refs

for Beginner

for Intermediate

for Professor

Dev Tools


SYNTAX

MDN - Mozilla Developer Network
標準ビルトインオブジェクト
EcmaScript
Node.js

なんかわかんないコトはオフィシャルなマニュアルを参照。

クラスとモジュールパターン

Google流JavaScriptにおけるクラス定義の実現方法(ES6以前)
秘匿化に向けたJavaScriptの旅
不要なクラス宣言、やめちゃおっか?

言語に依らずクラスを独自実装したくなるなら FW / ライブラリ導入を検討した方がいい。

  • js は prototype ベースのオブジェクト指向言語で、元々クラスベースじゃない
  • クラスベースっぽく書けるよう es6 から prototype の syntax sugar として class 構文がサポートされた
  • とはいえ内部では prototype ベースの拡張なので、他言語と違って扱いがややこしい
    • this が外部と共有されるため、thisが自身のインスタンスではなくなることがある
    • prototype を使ったメソッドがクラス内のローカル変数を参照している場合、その変数はインスタンス間で共有されるため、想定外の値になることがある
    • 経験的にも class 使わない方がいいケースの方が多い
  • typescript 使うならまぁ選択肢としてなくもない ... くらい

あとカプセル化 (private メンバ) 欲しいだけなら モジュールパターン も検討していい。

知っておきたいデザインパターン 1.モジュールパターン

// モジュールパターンで秘匿性を頑張る

export const users = (() => {
  const _users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
  ];

  const all    = () => {};
  const find   = (id) => {};
  const add    = (id) => {};
  const remove = (id) => {};
  
  // _users は秘匿されている
  return { all, find, add, remove };
})();

そもそも js は関数が第一級オブジェクトなので、関数で解決できるものが多い。react なんかの一般的な js ライブラリ / FW も最近は関数型ちっくに実装するので、独自でクラスを実装していく必要性があまりない。

データ型

  • プリミティブデータ型 ( int, str, bool, null )
    • int , str など基本的な型は全てオブジェクトの prototype が用意されておりインスタンス化できるが プリミティブのままでも存在できる
    • JavaScript では文字列や数値などをプリミティブデータ型とオブジェクト型両方で用意できる
    • var str = "hello"; と var str = new String("hello"); が別物になる
  • オブジェクト型
    • リファレンス型 ( 関数, 配列, オブジェクトインスタンス )
      • 下記プロトタイプオブジェクトのインスタンスで変数に代入すると参照が入る
    • プロトタイプ
      • オブジェクトは Array.prototype のようにプロトタイプ ( 親クラスみたいなヤツ ) が存在する
    • 独自オブジェクトを新規作成した場合は自動生成される
    • このプロトタイプのメソッドやプロパティを拡張すれば全ての子インスタンスがアクセスできる
  • シンボル型

データ型別 True / False

PHPと比べてとくに注意すべきは undefined 。存在チェックは if (value == null) が null と undefined をいっぺんにチェックできてよさげ?困ったら (variable) ? 'あるよ' : 'ないよ' みたいに () で評価しちゃうのが早いかも。

// Is falsy ?
console.log( Object ? true : false);    // true
console.log( undefined ? true : false); // false
console.log( null ? true : false);      // false
console.log( true ? true : false);      // true
console.log( false ? true : false);     // false
console.log( 0 ? true : false);         // false
console.log( 1 ? true : false);         // true
console.log( -1 ? true : false);        // true
console.log( '' ? true : false);        // false
console.log( 'a' ? true : false);       // true
console.log( [] ? true : false);        // true
console.log( {} ? true : false);        // true

// Is blank array ?
console.log( [].length ? true : false);    // false
console.log( ['a'].length ? true : false); // true

// Is blank object ?
console.log( Object.keys({}).length ? true : false);
console.log( Object.keys({a:'a'}).length ? true : false);

// __get() Property of blank object
let obj = {value:'hoge'}
console.log(obj.key);  // Becomes 'undefined' rather than error.

in 演算子と Object.hasOwnProperty() によるキー存在判定

in - MDN
Object.prototype.hasOwnProperty() - MDN
[Javascript] オブジェクトが指定されたプロパティを保持しているかどうかの判定

基本的に両者は同じだが Object.prototype.hasOwnProperty() は子孫の prototype まで遡らず「判定対象の、そのオブジェクトにあるかどうか?」を判定する。対して in は子孫の prototype まで遡る。以下では toString() 実装の有無について判定に違いが出る。

// in
const obj = { a: 1, b: "xxx" }
console.log('a' in obj)         // true
console.log('x' in obj)         // false
console.log('toString' in obj)  // true

// hasOwnProperty()
console.log(obj.hasOwnProperty('a'))         // true
console.log(obj.hasOwnProperty('x'))         // false
console.log(obj.hasOwnProperty('toString'))  // false

短絡評価 || による null セーフ処理

論理演算子 > 短絡評価
あなたが知らないJavaScriptの便利すぎるショートハンド19選

const falsy = null
const var1  = falsy || 'Default Value'
console.log(var1)  // Default Value

const string = 'Not Falsy'
const var2   = string  || 'Default Value'
console.log(var2)  // Not Falsy

動的型付け / 暗黙キャスト

他スクリプト言語と同様の動的型づけのほかに、プリミティブ → オブジェクトへの変換が起こる。string がプリミティブな文字列だった際に string.substr() のように定義していないはずのプロパティやメソッドにアクセスしようとした時 string はプリミティブな文字列型から String Object に変換されアクセスが続行される

配列

Array - MDN

JavaScript は配列も「 Array オブジェクト」を prototype に持つオブジェクトなので、メソッドやプロパティを持っている。また PHP の場合は「配列」と「連想配列」が内部的には同じ「連想配列」として処理されるが、JavaScript をはじめ多くの言語では 配列は純粋な列挙データ となり、添え字は必ず 0 始まりになる ( PHP では配列に [2 => 'fuga', 14 => 'piyo'] のような状態が存在するが一般的な配列でこの状態はありえない ) 。

const newArray = [1, 2, 3]
console.log(newArray)         // [1, 2, 3]
console.log(newArray.length)  // 3
console.log(newArray[0])      // 1

// Array like なオブジェクトから配列を生成 - Array.from()
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from
const arrayFromString = Array.from('hello')
console.log(arrayFromString)  // ['h', 'e', 'l', 'l', 'o']

// 配列への要素追加 - Array.prototype.push()
const animals = ['pigs', 'goats', 'sheep']
animals.push('cow')
console.log(animals)  // ['pigs', 'goats', 'sheep', 'cow']

// 配列への要素追加 - Array.prototype.concat()
// push() と違ってこちらは非破壊 ( 引数にとった要素を破壊せず新規要素を生成 )
const array1 = ['a', 'b', 'c']
const array2 = ['d', 'e', 'f']

console.log(array1.concat(array2));  // ['a', 'b', 'c', 'd', 'e', 'f']

// 配列要素へクロージャーを適用し、新たな配列を返す - Array.prototype.map()
const numbers = [1, 4, 9, 16]
const results = numbers.map(function(number) {
  return number * 2
})

console.log(results)  // [2, 8, 18, 32]

オブジェクト

Object - MDN

JavaScript の {} は PHP でいう「連想配列」と混同されがちだが、これは「オブジェクト」であり中身は全てプロパティ・メソッドになる。Array なのか Object なのかで利用できるメソッドが変わる ( prototype が違うので ) ため、この違いをしっかり認識すること。

var myObject = {
  value: 10,
  show: function() {
    console.log(this.value)
  }
}

myObject.value = 2
myObject.show()  // 2

チェーン記法 / ドット記法

オブジェクトのプロパティやメソッドに myObject.myProperty のようにアクセスできる。この際に返り値がオブジェクトであれば ( オブジェクトでなかったらキャストされる ) 再びドットつなぎで次のオブジェクト・メソッドに渡すことができる。この鎖のような連結した書き方をドット記法・チェーン記法と呼ぶ。

this.property
this.method()
var arr = [1, 2, 3, 4, 5]
var result = arr.slice(0,4).slice(0,3)

ブラケット記法

配列への添え字アクセス array[0] や、オブジェクトのプロパティアクセス object['hogeProperty'] に用いる。また、メソッドチェーンでは呼び出す際のキーに変数を用いた動的な呼び出しを行えないが、ブラケット記法であれば可能。

const myObject = {
  name: 'John',
}

const index = 'name'

console.log(myObject.index)  // ng
console.log(myObject[index]  // John

Computed Property Names

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names

オブジェクトのキー名を動的にしたいときはこうじゃ。

const key = 'my-key'
const value = 'my-value'

const obj = {
  [`template_literal_${key}`]: value 
}

ループ

ループと反復処理
Iterator protocol

for

なんてことない普通の for 。主に配列や回数指定ループに利用する。

let sum = 0
let array = [1, 3, 4, 7]
for(let i = 0; i < array.length; i++) { // 配列の長さ分の繰り返し
  sum += array[i]
}

console.log(sum)  // 15

for in

Iterable な Object からキーを取り出す。反復処理に不必要なキーでも引っ張てきちゃうので注意 参考 。

let obj = { foo : 'hello', bar : 'world' }
for ( let key in obj ) {
  console.log( key + '->' + obj[key] )  // 'foo->hello', 'bar->world'
}

for of ( es6 )

Iterable な Object に対して列挙可能なコレクションを抜き出しながらループ処理を行う。利用可能なオブジェクトは Array, Map, Set, String, TypedArray など。予め列挙可能なアイテムがオブジェクト内に定義 ( Symbol.iterator ) されている必要がある。

また NodeList は Iterable なので列挙可能だが HTMLCollection は Not Iterable なので for of で回せない など、オブジェクトによって利用可能なものとそうでないものがあるので注意。 - 参考 。

let score = [70, 65, 55, 80, 100]
for (let s of score) {
  console.log(s)  // 70 65 55 80 100
}

スプレッド演算子 ( 要素展開 )

Spread Operator
【JavaScript】スプレッド演算子の便利な使い方まとめ

es6 からの新演算子 ... で 配列ライクなオブジェクト ( 正確には for of で展開できるオブジェクト ) を個々の値に展開する。純粋な配列の展開だけではなく Iterable Object なら何でも内包する反復要素全てを展開できるのがポイント 。ここで展開されたものから新たな配列を [...items] みたいな感じで作れるので 何か → 配列への変換がらくちん になる理解でいいのかな。

function myFunction(x, y, z) { ... }
var args = [0, 1, 2];

// 配列を関数の引数として使用したい場面では
// 慣習的に Function.prototype.apply が使用される
myFunction.apply(null, args);

// ES2015 の スプレッド演算子 を利用すると以下のようになる
myFunction(...args);

// 可変長引数としても利用可能
const sum = (...nums) => nums.reduce((p, c) => p + c, 0);  // reduce() - https://goo.gl/PnENoA
console.log(sum(1, 2, 3, 4, 5));  // 15

// オブジェクトの部分更新代入とか
const user = { model: 'user', id: 1, name: 'john', age: 19 };
const updatedUser = {
  ...updatedUser,  // updatedUser の key value を展開して同じ object に
  age: 20,         // ↑ ののち age キーだけを更新
};

スプレッド演算子のより良い利用

const data1 = [1, 2, 3];
const data2 = ['d', 'e', 'f'];

// push
data1.push(...data2);  // ループや Array.prototype.push.apply(data1, data2) を使わなくてよくなる
console.log(data1);    // [1,2,3,"d","e","f"]

// unshift
data1.unshift(...data2);
console.log(data1);    // ["d", "e", "f", 1, 2, 3]

// merge
const merged = ['あ', ...data1, 'い', ...data2, 'う'];
console.log(merged);    // ["あ",1,2,3,"い","d","e","f","う"]

// 分割代入 - https://goo.gl/oL114d
let [a, b, ...other] = [1, 2, 3, 4, 5];
console.log(a);        // 1
console.log(b);        // 2
console.log(other);    // [3, 4, 5]

// 文字列 → 配列
const word = 'JavaScriptプログラミング';
const converted = [...word];  // .split() や Array.from(word) で生成しなくてよくなる
console.log(converted);       // ["J","a","v","a","S","c","r","i","p","t","プ","ロ","グ","ラ","ミ","ン","グ"]

// 配列から重複を取り除く - Set Object https://goo.gl/RWGqkU
const data = ['a', 'b', 'c', 'a', 'b', 'd'];
const dist = [...(new Set(data))]; 
console.log(dist);    // ["a","b","c","d"]
// Set オブジェクトは与えられた Iterable Object から一意の値のみコレクションしたオブジェクトを返す
// 上記では返ってきた Set オブジェクトから配列生成している

// 配列コピー
const ary = ['Pen', 'Pineapple', 'apple'];
const myAry = [...ary];        // Array.prototype.slice.call を使わなくて良くなる
console.log(ary === myAry);    // false → 新たな Array オブジェクトとして生成され...
console.log(myAry);            // ["Pen","Pineapple","apple"] → 中身はコピーされている

// 配列コピー時、中のオブジェクト要素参照は保たれる
const fruits = [
  { 'banana': 100 },
  { 'cherry': 200 }
];
const myFruits = [...fruits];
fruits["0"].banana = 300;
console.log(myFruits);    // [{"banana":300},{"cherry":200}] → 変わってるね!

// HTMLCollection から配列つくって配列系メソッドでループ操作する
const elems = document.getElementByClassName('checkboxClassName');
const filtered = [...elems].filter(el => el.checked && el.classList.contains('foo'));
setCheckBox('fruits', 'apple', 'banana');

即時関数

// クロージャー ( 無名の関数オブジェクト ) を生成し即実行する手法
// 読み込み時に即実行され、かつグローバル空間を汚染しないため
// es6 以前のモジュール分割ができなかった時代に重宝された

(function () {

  var scopedVar = 'hello!';
  
  function scopedFunc () {
    alert('world!')
  }

  console.log(scopedVar)  // hello!
  scopedFunc()            // Display alert 'world!'

})()

// グローバルでは undefined になる
console.log(scopedVar)  // undefined
scopedFunc()            // undefined

アロー関数

Arrow Functions

es6 より追加された機能で function () {} 式の別の書き方で {} スコープ内で this, arguments, super, new.target などを束縛しない ( 上位スコープの this などがそのまま利用できる ) 。また内容によって return や引数を省略した記述が可能。

var materials = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
]

console.log(materials.map((material) => {
  return material.length
}))
// Array [8, 6, 7, 9]

// 省略記法
console.log(materials.map(material => material.length));

アロー関数でオブジェクトの返却

// なんでか意味わかんないけど parentheses で囲えばいいみたい
(p) => ({ foo: 'bar' });

this ( 疑似変数 )

オブジェクトの定義スコープ内で「自身オブジェクト」を参照する擬似演算子。基本的に this は常に現在のスコープから見た「呼び出し元オブジェクト」を参照する。

// object 定義内の this
var myObject = {
  value: 10,
  show: function() {
    console.log(this.value);  // this は現在スコープを呼び出す myObject オブジェクトを指す
  }
}
myObject.show(); // 10


// global で宣言された function 内の this 
function show() {
  console.log(this);  // this は現在スコープ function の呼び出し元であるグローバル window を指す
  this.value = 1;     // value はグローバル変数になる (window.value)
}
show(); // this は グローバルオブジェクト window をさす

アロー関数で this をバインドする

this は 現在スコープによってその参照を変えてしまうが アロー関数 を利用することでその束縛を回避できる。

window.onload = function (){
  var node = this.document.querySelector('#node')
  node.addEventListener('click', (evt) => {
    console.dir(this)
    // this は関数スコープに束縛されず Event オブジェクトではなくグローバルの window オブジェクトを指す
  })
}

暗黙のグローバルオブジェクト - window

JavaScript は純粋オブジェクト指向につき Node.js 環境下を除いたブラウザ実行環境下では、グローバルに暗黙の最上位オブジェクト window が存在する。

// トップレベル ( 暗黙の window )
var hoge = "fuga";  
window.foo = "bar";
console.log(this.hoge + "+" + this.foo); // fuga+bar
(function(){
    console.log(this.hoge + "+" + this.foo);
})(); // fuga+bar

// 関数内(≠メソッド) > トップレベル参照
var func = function() {
    console.log(this.foo);
};
func();  // undefined (window.foo)

モジュール ( import & export / require )

import - MDN
export - MDN

JavaScript のモジュール管理は死ぬほどややこしい歴史があるが、平たく言えば「別の JS ファイルなどのリソースからオブジェクトやらなんやら引っ張ってくる、あるいは引っ張ってもらえるようにする」ための仕組み。Browserify や CommonJS など様々なモジュール解決のツールや API が存在したが、現在は nodejs 環境下の require() API と、es6 構文である import および export で落ち着いてる ( ぽい ) 。

require()とは何か?何が便利なのか
ES6のexportについて モダンなJSの話──importとexport
[意訳]初学者のためのJavaScriptモジュール講座 Part1

// import
import Hoge from './Hoge.js'
const hoge = new Hoge()  // hello!!

//Hoge.js for import
export default class Hoge {
  constructor () {
    this.hello();
  }
  hello () {
    console.log("hello!!")
  }
}


const Hoge = require('./Hoge.js')
const hoge = new Hoge()  // hello!!

//Hoge.js for require()
module.exports = class Hoge {
  constructor () {
    this.hello();
  }
  hello () {
    console.log("hello!!")
  }
}

DOM API

DOM リファレンス
DOM - Core

JavaScript は純粋オブジェクト指向言語なので、String や Array などのデータは全てオブジェクトとして実装されている。これと同様に JavaScript は HTML 操作においても、ブラウザが HTML を解釈する際に利用する DOM インタフェースを利用するために実装された各種オブジェクト をとり扱うことで実現している。

DOM とは Document Object Model の略で、HTML および XML ドキュメントへアクセスするための API 。ブラウザは HTML を解釈する際にその内部のドキュメントを「ツリー構造のデータ集合」として取り扱い DOM ツリー を生成する。このツリーの1つ1つのオブジェクトは Node と呼ばれ、親子関係を持つ。JavaScript は このツリーを経由して、HTML の内容や表現を変更できるようになっている。これら仕様の標準化は W3C によって行われている。

Document / Window

Document - MDN Window - MDN

JavaScript でいうところの document は DOM ツリーのエントリーポイント ( ルート ) であり、DOM API の Document インタフェースを継承したオブジェクト。通常、ブラウザを操作するためのグローバルオブジェクト window 配下にぶら下がっている ( document.body のようにアクセスする場合、暗黙のトップレベルオブジェクト window を省略したことになる → window.document.body ) 。

これに対して window はブラウザへのアクセスのためのオブジェクト。JavaScript はブラウザをプラットフォームとしたプログラミング言語なので、履歴 ( History ) や アドレスバー ( Location ) に対するアクセスを可能とする API オブジェクト ( ブラウザオブジェクトなどと呼ばれる ) を標準で保持している。

Element

こちらは DOM API の Element インタフェースを継承したオブジェクト。HTML の一要素(ノード)を document.getElementById() や document.querySelector() なんかで取得した場合は DOM API の Element と HTMLElement インタフェースを継承した Element オブジェクトということになる(ややこしいんですけど...)。DOM ツリー内の特定ノード。大体の場合はまぁタグ要素のことと思っておけばいい。

HTMLCollection / NodeList

document.forms や node.children や document.getElementsByClassName() や document.getElementsByTagName() なんかで取得できる 要素集合 (ノード集合) を HTMLCollection と呼ぶ。これらは上記 Element オブジェクトの集合であり 配列ライクなオブジェクト みたいな表現をされる。HTMLCollection は配列ライクなのだが Not Iterable なためループ処理時に Array.from() にぶっこんで配列キャストするひと手間が必要。また、ノードが変更された際は動的に変化するという ライブな特徴を持つ 。

上記に対して、document.querySelectorAll() では NodeList と呼ばれる 静的な(ライブでない)要素集合 が取得できる。HTMLCollection と違い内包する Element Node を含む全てタイプのノードを取得するのが特徴。また、こちらは Iterable なため for of とかでさっさとループできたりする。ややこしいんですけど...?

要注意ポイント - getElementsByTagName / getElementsByClassName

NodeListとHTMLCollectionも別物なので気を付けよう。
HTMLCollection vs NodeList
ParentNode.childrenをfor...ofループするときの注意点
配列ライクなオブジェクトをforEachするときのイディオム

getElementsByTagName() および getElementsByClassName() について、ブラウザ間で返り値が異なり、Chrome は NodeList を FireFox は HTMLCollection を返すという意味不明な仕様がある。それぞれループ処理にぶっこむ作法が違うので混同すると結構危険なことになる。

querySelectorAll() で毎回 NodeList をとるか、どっちが来ても大丈夫なように配列キャストをするのが今風みたい。

Event

Event - MDN
イベントリファレンス
DOM イベントリファレンス - Drafted
addEventListener

ブラウザには DOM ツリーの他に「マウスでクリックした」「リロードした」などの イベント が存在する。JavaScript はこのようなブラウザで起こる様々なイベントに対して、イベントがトリガーした際の「コールバック」を「リスナー」として登録する ... といった「イベント駆動型プログラミング」に適している。

<table id="outside">
  <tr><td id="t1">one</td></tr>
  <tr><td id="t2">two</td></tr>
</table>
// t2 のコンテンツを変更する関数
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// イベントリスナーを table に追加
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

合成イベント

Refs


Vanilla JS & JQUERY

以下 jQuery のイディオムを Native JavaScript で書いたらどうなるの集。

window.onload / $(document).ready

  • $(document).ready(function(){...}) は DOMツリー完了。
  • window.onload = function(){....} は 全体読込完了。

jQueryなしDOMツリー完了は以下。

document.addEventListener('DOMContentLoaded', function() {
    console.log('DOMContentLoaded')
})
// ※Riot.jsなど仮想DOM系はこれで捕まらないよ

window.addEventListener('load', function() {
  console.log('loaded')
})

フォームインプット / 属性操作

// jQuery val()
document.querySelector('#my-input').value
document.querySelector('#my-input').value=1

// jQuery attr()
el.getAttribute('foo')
el.setAttribute('foo', 'bar')
// readonlyとかは el.readOnly = true とか可

// jQuery data()
el.getAttribute('data-foo')
el.dataset['foo'] // ie11~

エレメントの取得 / セレクター

// jQuery
$('.class')

// Native - jQueryぽくかけます
document.querySelector('#id')
document.querySelectorAll('.class') document.querySelectorAll('a[target=_blank]')

// Native-oldPattern document.getElementsByClassName('class')

兄弟要素

// jQuery
  $el.find('li')

// Native
  el.querySelectorAll('li')

スタイル

// jQuery
  $el.css({ color: "#ff0011" })

// Native
  el.style.color = '#ff0011'

クラス操作

// jQuery
  $el.addClass(className)  //追加
  $el.removeClass(className)  //削除
  $el.hasClass(className)//有無

// Native
  el.classList.add(className)
  el.classList.remove(className)
  el.classList.contains(className)

HTML取得・設定

// jQuery
  $el.html()
  $el.html(htmlString)

// Native
  el.innerHTML
  el.innerHTML = htmlString

エレメント追加・削除

// jQuery
  $el.prepend("<p>hello</p>")
  $el.append("<p>hello</p>")
  $el.remove()

// Native
  el.insertAdjacentHTML("afterbegin","<p>hello</p>")
  el.insertAdjacentHTML("beforeend","<p>hello</p>")
  el.parentNode.removeChild(el)

コピー(クローン)

// jQuery
  $el.clone()

// Native
  el.cloneNode()

イベントリスナー

// jQuery
$(document).ready(function(){
  $('#node').on('click',function(){
    console.dir($(this))
  })
})

// es6
window.onload = function (){
  this.document.querySelector('#node')
  .addEventListener('click',function(evt){
    console.dir(this)
  })
}

addEventListener の順序

誰よりも先にイベントリスナを呼び出す 通常 addEventListener で登録されたイベントリスナは登録された順番に実行される
但し useCapture 引数を true で渡すと誰よりも先に実行される

// target.addEventListener(type, listener[, useCapture]);

document.addEventListener('click', function() { alert('2'); });
document.addEventListener('click', function() { alert('1'); }, true);
document.addEventListener('click', function() { alert('3'); });

Element の動的生成

// select に option 追加
var select = document.querySelector('#select')
var option = document.createElement('option')
option.setAttribute('value', 'value属性に入れる値')
option.innerHTML = '要素に入れる文字列'
select.appendChild(option)

イベントのトリガ

document.getElementById("#target").dispatchEvent(new Event('change'))

// 旧iOS対応
const el  = document.getElementById('#target')
const evt = document.createEvent('HTMLEvents')
evt.initEvent('change', true, true)
el.dispatchEvent(evt)