JavaプログラマのJS忘備録[ES5] ref: http://qiita.com/k4h4shi/items/68dd0ceff2e504ce0fae
var x = 1
{ var x = 2; console.log('x = ' + x); } // x = 2と出力する
console.log('x = ' + x) // ブロックスコープがないため、x = 1と出力する
var i = 1
for (var i = 0; i < 10; i++) {
// ループの処理
}
console.log(i) // 10と出力される
let x = 1
{ let x = 2; console.log('x = ' + x); } // x = 2と出力する
console.log('x = ' + x) // x = 1と出力する
let i = 1
for (let i = 0; i < 10; i++) {
// ループの処理
}
console.log(i) // 1と出力される
var s = "string"
var n = 10
var b = true
// ,で区切ることで一つの文で複数の変数を宣言することもできる
var obj = {}, func = function() {};
s // => "string"
n // => 10
b // => true
obj // => {}
func // => function() {}
// オブジェクトリテラルを変数に代入
var person = {name: 'k4h4shi', age: 23}
// 関数の返り値でオブジェクトリテラルを返す
function createPerson() {
return {
name: 'k4h4shi',
age: 23
}
}
// 引数にオブジェクトリテラルを渡し、名前付きオプションを渡す
function operation({
name: 'k4h4shi',
age: 23,
married: false
})
// 関数リテラルを変数に代入
var func = function() {
console.log('hello')
}
// 関数の返り値で関数を返す
function returnFunction() {
return function() {
console.log('it will be returned.')
}
}
// 定義済みの関数の引数に関数を渡し、処理を行う
function executeFunction(function() {
console.log('it will be executed')
})
var s = 'str'
var n = 100
var b = true
var o = {}
var f = function() {}
var undef = undefined
var nul = null
typeof s // => 'string'
typeof n // => 'number'
typeof b // => 'boolean'
typeof o // => 'object'
// 関数はobject型だが'function'と判定される
typeof f // => 'function'
typeof undef // => 'undefined'
// nullはnull型だが'object'と判定される
typeof nul // => 'object'
try {
console.log("1行目実行中");
throw new Error("エラー");
console.log("例外がthrowされると、この行は実行されない");
} catch(err) {
console.log("エラーが起こった");
console.log(err.stack);
} finally {
console.log("finally中のこの文はいつも実行される");
console.log("リソースの解放をここで行う");
}
/** 実行結果
1行目実行中
エラーが起こった
Error: エラー
...
finally中のこの文はいつも実行される
リソースの解放をここで行う
*/
function validateEmail(email) {
return email.match(/@/);
}
try {
const email = 'これはメールアドレスです';
if (!validateEmail(email)) {
throw new Error(`メールアドレスが不正です: ${email}`);
// 例外がthrowされた場合、以降の文は実行されない
}
console.log(`メールアドレスは正常です: ${email}`);
} catch(err) {
console.error(`エラー: ${err.message}`);
}
// 実行結果 => エラー: メールアドレスが不正です: これはメールアドレスです
Boolean('') // => false
Boolean('true') // => true
Boolean('false') // => true
Boolean(true) // => true
Boolean(false) // => false
!!0 // => false
!!NaN // => false
!!null // => false
!!undefined // => false
!!'' // => false
!!{} // => true
Boolean({}) // => true
Boolean(0) // => false
// オブジェクトは全てtrueになるので注意
var b = new Boolean(false)
!!b // => true
// 論理演算による型変換
b || false // => true
b && false // => false
'use strict'
function a() {
console.log('a: bを呼び出す前');
b();
console.log('a: 終了');
}
function b() {
console.log('b: cを呼び出す前');
c();
console.log('b: 終了');
}
function c() {
console.log('c: エラーをスローする');
throw new Error('c error');
console.log('c: 終了');
}
function d() {
console.log('d: cを呼び出す前');
c();
console.log('d: 終了');
}
try {
a();
} catch(err) {
console.log('--- a呼び出し後のerr.stack ---')
console.log(err.stack);
console.log('--- 終わり ---');
}
try {
d();
} catch(err) {
console.log('--- d呼び出し後のerr.stack');
console.log(err.stack);
console.log('--- 終わり ---');
}
/** 処理結果(一部省略) =>
a: bを呼び出す前
b: cを呼び出す前
c: エラーをスローする
--- a呼び出し後のerr.stack ---
Error: c error
at c (stackTrace.js:15:9)
at b (stackTrace.js:9:3)
at a (stackTrace.js:3:3)
--- 終わり ---
d: cを呼び出す前
c: エラーをスローする
--- d呼び出し後のerr.stack
Error: c error
at c (stackTrace.js:15:9)
at d (stackTrace.js:21:3)
--- 終わり ---
*/
var obj = { id: 0, name: "unknown" }
for (var prop in obj) {
console.log(prop) // id, nameが出力される。
console.log(obj[prop]) // 0, "unknown"が出力される
}
function f() {
var s = 'hello'
function g() {
console.log(s);
}
return g
}
f() // => [Function: g]
// コンストラクタによる生成
var regExp1 = new RegExp('^[0-9]')
regExp.test('foo') // => false
regExp.test('123Bar') // => true
// リテラルによる生成
var regExp2 = /^[0-9]/
regExp2.constructor === RegExp // => true
regExp2.test('123Foo') // => true
regExp2.exec('123') // => [ '1', index: 0, input: '123' ]
// フラグありの正規表現
var regExp1 = new RegExp('^\\s+', 'g')
regExp1.test(' 123 asdf') // => true
var regExp2 = /^\s[abc]/gi
regExp2.test(' A') // => true
(function(n) {if (n <= 1) return 1; else return n * arguments.callee(n - 1); })(5);
function factorial(n) {
if (n <= 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
function MyObject(x, y) {
this.x = x
this.y = y
}
MyObject.prototype.show = function() {
console.log(this.x, this.y)
}
var myInstance = new MyObject(0, 1)
// プロトタイプから振る舞いを引き継いでいるため、0 1 と出力することができる
myInstance.show()
var small = Number.EPSILON // 1と1より大きい最小の値の差
var maxInt = Number.MAX_SAFE_INTEGER; // 表現できる最大の整数
var max = Number.MAX_VALUE; // 表現できる最大の数値
var minInt = Number.MIN_SAFE_INTEGER; // 表現できる最小の整数
var min = Number.MIN_VALUE; // 表現できる最小の数値
var inf = Number.POSITIVE_INFINITY; // 無限
var ninf = Number.NEGATIVE_INFINITY; // マイナスの無限
var nan = Number.NaN; // Not a Number (数値ではない)
var obj = { a:1, b:2, c:3 };
obj.a // => 1
obj['b'] // => 2
// JSON文字列からJavaScriptオブジェクト
var jsonStr = '{"x": 1, "y": 2, "val": "foobar"}';
var obj = JSON.parse(jsonStr);
obj // => { x: 1, y: 2, val: 'foobar' }
// JavaScriptオブジェクトからJSON文字列
var s = JSON.stringify(obj)
s // => '{"x":1,"y":2,"val":"foobar"}'
// 親となるオブジェクト
function Parent() {
this.type = 'parent'
this.isParent = function() {
return this.type === 'parent'
}
}
// 子となるオブジェクト
function Child() {
this.type = 'child'
}
// 子のプロトタイプに親を設定し引き継ぐ
Child.prototype = new Parent()
// 親子関係にあるインスタンスを生成
var parent = new Parent();
var child = new Child();
parent.isParent() // => true
// プロトタイプから振る舞いを引き継いでいるため呼び出せる
child.isParent() // => false
// インスタンスのconstructorプロパティが適切になるよう設定する
child.constructor // => [Function: Parent]
Child.prototype.constructor = Child
child.constructor // => [Function: Child]
var array = ['zero', 'one', 'two']
array.forEach(function(e, i, a) {
console.log(e, i, a)
})
// 以下のように出力される
// zero 0 [ 'zero', 'one', 'two' ]
// one 1 [ 'zero', 'one', 'two' ]
// two 2 [ 'zero', 'one', 'two' ]
// その他の値の数値への変換
+true // => 1
+false // => 0
+null // => 0
+undefined // => NaN
// オブジェクトが適切な数値へ変換できない場合はNaNとなる
var obj = {}
obj++ // => NaN
{
name: 'k4h4shi',
age: 23
}
String(100) // => '100'
(100).toString() // => '100'
// 暗黙の型変換を利用した文字列への変換のイディオム
var n = 100
n+'' // => 100
// 数値リテラル
var count = 10; // 10進数
var blue = 0x0000ff; // 16進数
var umask = 0o0022; // 8進数
var roomTemp = 22.5; // 少数
var c = 3.0e6; // 指数表記
var e = -1.6e-19; // -の指数表記
// 無効な値
var inf = Infinity; // 無限
var ninf = -Infinity; // マイナスの無限
var nan = NaN; // Not a Number (数値ではない)
// NaNかどうかを判定する関数
isNaN(count) // => false
isNaN(nan) // => true
isNaN(inf) // => false
// 無効な値でないことを判定する関数
isFinite(count) // => true
isFinite(nam) // => false
isFinite(inf) // => false
var x = 0;
while(true) {
x += 0.1;
console.log(x);
// xと0.3の差をとって、その絶対値がNumber.EPSILONより小さい場合、等しいとみなします。
if (Math.abs(x - 0.3) < Number.EPSILON) break;
}
var x = 0;
while(true) {
x += 0.1;
console.log(x);
// 3回目のループではxが0.3となることを期待しているが、そうならない。
// そのためにこのループは無限ループとなる
if (x === 0.3) break;
}
function f() {
var s = 'hello'
function g() {
console.log(s);
}
g()
}
f() // 'hello'と出力する
function f() {
function g() {
console.log('hello');
}
g()
}
f() // 'hello'と出力する
var x = 1
function func() {
console.log('x = ' + x);
var x = 2
console.log('x = ' + x)
}
func()
// 上記のfuncの呼び出しは、以下のように出力する
// x = undefined
// x = 2
// 外側へ向けた名前の探索
function func1() {
let x = 1
{ console.log(x) } // 1を出力する
}
// let宣言より前でも、名前は有効
function func2() {
let x = 1
{
console.log(x) // let x = 2のスコープだが、代入前のためにundefinedを出力する
let x = 2
console.log(x) // let x = 2によって代入が行われたため、2を出力する
}
}
var array = [0, 1, 2]
for (var i = 0, len = array.length; i < len; i++) {
console.log(array[i])
}
// 以下のように出力される
// 0
// 1
// 2
function Parent() {}
function Child() {}
Child.prototype = new Parent()
var child = new Child()
Child.prototype.isPrototypeOf(child) // => true
Parent.prototype.isPrototypeOf(child) // => true
Object.prototype.isPrototypeOf(child) // => true
// シングルクォートで囲った文字列
var s = JSON.parse("'foo'"); // SyntaxError: JSON.parse
// 文字列でないプロパティ名
var s2 = JSON.parse("{x: 1}") // SyntaxError: JSON.parse
var date = new Date()
date instanceof Date // => true
date instanceof Object // => true
function Parent() {}
function Child() {}
Child.prototype = new Parent()
var child = new Child()
child instanceof Child // => true
child instanceof Parent // => true
child instanceof Object // => true
var array = ['x', 'y', 'z']
array.forEach(function(e) { console.log(e) })
x = x || 0 // => xがundefinedの場合0を、そうでなければxをxに代入。
1 + '1' // => '11'
var obj = { prop: 'ownProperty' }
// in演算子
'prop' in obj // => true
'toString' in obj // => true
// hasOwnProperty関数
obj.hasOwnProperty('toString') // => false
obj.hasOwnProperty('prop') // => true
function Person(name, age) {
this.name = name
this.age = age
this.greeting = function() {
console.log('hello world.')
}
}
var person = new Person('john', 23);
person.name // => 'k4h4shi'
person.age // => 23
person.greeting // => function() { console.log('Hello!') }
person.greeting() // コンソールにHello!と出力する
function func() {}
func.constructor // => [Function: Function]
func.constructor === Function // => true
func.__proto__ === Function.prototype // => true
function() {
console.log('hello world');
}
function Parent() {}
function Child() {}
Child.prototype = new Parent()
var child = new Child()
Child.prototype.isPrototypeOf(child) // => true
Parent.prototype.isPrototypeOf(child) // => true
Object.prototype.isPrototypeOf(child) // => true
var date = new Date()
date instanceof Date // => true
date instanceof Object // => true
function Parent() {}
function Child() {}
Child.prototype = new Parent()
var child = new Child()
child instanceof Child // => true
child instanceof Parent // => true
child instanceof Object // => true
1 == '1' // => true
1 === '1' // => false
1 != '1' // => false
1 !== '1' // => true
// 宣言のみの変数の判定
var x;
x === undefined // => true
// 値がnullかの判定
var y = null;
y === null // => true
var obj = {}
obj.operate = function() { console.log('operate!') }
if ('operate' in obj && typeof obj.operate === 'function') {
// 'operate!'と出力する
obj.operate()
}
var date = new Date() // 引数なしのコンストラクタで現在時刻のインスタンス生成
date // => 2017-07-24T14:12:14.415Z
// 日の数値を返す
date.getDate() // => 24
// 0を日曜とする曜日を返す
date.getDay() // => 1
// 年を設定する
date.setFullYear(2018) // => 1532441534415
// 文字列へ変換する
date.toDateString() => 'Tue Jul 24 2018'
date.toString() // => 'Tue Jul 24 2018 23:12:14 GMT+0900 (JST)'
var sum = Function('a', 'b', 'return a + b')
var div = new Function('a', 'b', 'return a - b')
sum(3, 5) // => 8
div(3, 5) // => -2
var date = new Date()
date.constructor // => [Function: Date]
var obj = {}
obj.constructor // => [Function: Object]
var obj = {}
typeof obj.constructor // => 'function'
typeof Object // => 'function'
typeof Object() // => 'object'
obj.constructor === Object // => true
function MyObject() {}
typeof MyObject // => 'function'
var obj = new MyObject()
obj.constructor // => [Function: MyObject]
typeof obj.constructor // => 'function'
var x = 1, y = 2, z;
z = ++x, y++;
z // => 2
var rspModule = (function(x, y) {
var choise = {r: 'グー', s: 'チョキ', p: 'パー'}
var errorMsg = 'そうかそうか君はそんなやつだったんだな'
return {
win: function(input) {
switch(input) {
case choise.r: return choise.p
case choise.s: return choise.r
case choise.p: return choise.s
default: return errorMsg
}
}
}
})()
m.win('グー') // => 'パー'
m.win('チョキ') // => 'グー'
m.win('パー') // => 'チョキ'
m.win('ピストル') // => 'そうかそうか君はそんなやつだったんだな'
// モジュール自体にはプロパティが存在しないためアクセスできない
m.choise // => undefined
function greeting(name) {
var msg = 'hello ' + name + '.'
return function() {
console.log(msg);
}
}
function greeting(name) {
var msg = 'hello ' + name + '.'
function g() {
console.log(msg);
}
return g
}
var greeting1 = greeting('anthony')
var greeting2 = greeting('john')
greeting1() // => 'hello anthony'と出力する
greeting2() // => 'hello john'と出力する
function f() {
var s = 'hello'
function g() {
console.log(s);
}
return g
}
var rg = f()
rg() // => 'hello'と出力する
function closure() {
var cnt = 0;
return function() { return cnt++ }
}
var fn = closure()
fn() // => 0
fn() // => 1
fn() // => 2
var b = true;
var c = false;
var n = b ? 1 : 0;
n // => 1
var m = c ? 1 : 0;
m // => 0
function boolToNum(b) {
return b ? 1 : 0;
}
boolToNum(b) // => 1
boolToNum(m) // => 0
// 識別子に使えないプロパティ名を使う場合
var obj = { 'foo-bar': 5}
obj['foo-bar'] // => 5
// obj.foo-bar // obj.fooとbarの減算と解釈されるためにエラー
// 変数の値をプロパティ名に使う場合
var obj = { x: 10 }
var key = 'x';
obj[key] // => 10
// 式の評価結果をプロパティ名に使う場合
// TBD
function func() {
var x
console.log('x = ' + x);
x = 2
console.log('x = ' + x)
}
var array = [0, 1, 2, 3]
typeof array // => 'object'
array.length // => 4
var array2 = [0, 'str', true, function() {}, {}]
array2.length // => 5
// コンストラクタの生成の際は、1つの数値を指定するとその要素数の配列となる
var array3 = new Array(5)
array3 // => [5 empty items]
// 2つ以上の引数を渡すと、それらを要素とした配列となる
var array4 = new Array(0, 3, 5)
array4 // => [0, 3, 5]
var array = ['1', '2', '0']
// 最後尾に要素を追加
array[array.length] = '3'
array // => ['1', '2', '0', '3']
// 数値配列に変換(要素が数値変換可能な場合)
array.map(function(e, i, a) {
a[i] = +e
})
array // => [1, 2, 0, 3]
// 数値配列のソート
array.sort(function(a, b) { return a - b; })
array // => [0, 1, 2, 3]
// 配列を使った文字列生成
var arr = []
arr.push('<div>')
arr.push(Date())
arr.push('</div>')
var s = arr.join('')
s // => '<div>Mon Jul 24 2017 22:41:00 GMT+0900 (JST)</div>'
// 文字列から配列生成
var s = 'Mon Jul 24 2017 22:41:00 GMT+0900 (JST)'
var a = s.split(/\s/)
a // => [ 'Mon', 'Jul', '24', '2017', '22:41:00', 'GMT+0900', '(JST)' ]
// 配列のコピー(shallowコピー)
// concatを用いた場合
var arr = [3, 5, 4]
var arrCp = [].concat(arr)
arrCp // => [3, 5, 4]
// sliceを用いた場合
var arr = [3, 5, 4]
var arrCp = arr.slice(0, arr.length)
arrCp // => [3, 5, 4]
function printArgs() {
console.log(arguments.length, arugments[0], arugments[1], arugments[2])
}
printArgs(0) // 1 0 undefined undefined
printArgs(0, 1) // 2 0 1 undefined
printArgs(0, 1, 2) // 3 0 1 2
var person = {
name: 'k4h4shi',
age: 23,
greeting: function() {
console.log('Hello!')
}
}
person.married = false
person.married // => false
'married' in person // => true
delete person.married // => true
'married' in person // => false
function counter(init) {
// 変数cntは、Javaにおけるprivateフィールド相当
// initがundefined、つまり引数が渡されなかった場合に0で初期化するidiom
var cnt = init || 0
return {
// 以下のプロパティはpublicメソッド相当
show: function() { console.log(cnt) },
up: function() { cnt++; return this },
down: function() {cnt--; return this }
}
}
var c = counter();
c.show() // => 0
c.up().show() // => 1
c.down().show() // => 0
var person = {
name: 'k4h4shi',
age: 23,
greeting: function() {
console.log('Hello!')
}
}
person.name // => 'k4h4shi'
person.age // => 23
person.greeting // => function() { console.log('Hello!') }