メモブログ

技術的なことを書き連ねるブログ

javascriptのthisについてまとめる

頭ではなんとなく理解しているけど、javascriptのthisはややこしい なのでちゃんとまとめようと思いました。

そもそも、javascriptにおいて「this」は何を指すか? 色々調べていてとてもしっくりくる説明があった。

thisが呼ばれた関数(メソッド)が所属しているオブジェクトのこと
thisはfunctionが呼ばれる前の「.(ドット)」の前についているオブジェクトのこと

簡単な例で言えば、

var obj = {
  name: 'taro',
  func: function(){
    console.log(this)
  }
}
obj.func(); // {name: "taro", func: ƒ}

この場合で言えば、funcというメソッドが所属しているobjオブジェクトである。

しかし、javascriptのthisは
以下の呼び出し方で、諸々挙動が変わる。

1. 関数呼び出し
2. メソッド呼び出し
3. コンストラク
4. apply/call/bindでthisを設定

ちなみに、最初の例は(2)となる。
それぞれのパターンを噛み砕いて見ようと思う。

(1). 関数呼び出し

function func1(){
  console.log(this)  // Window
  function func2(){
    console.log(this)  // Window
  }
  func2()
}
func1();

thisはwindowオブジェクトになった。
これは、func1,func2はwindowオブジェクトのメソッド、メンバだから。
関数呼び出しだから。

ちなみにstrictモードだと

'use strict';

function func1(){
  console.log(this)  // undefined
  function func2(){
    console.log(this)  // undefined
  }
  func2()
}
func1();

undefinedになる。
これは、もともと、thisとなるものが定義されていない場合(undefinedやnull)に、
thisをwindowオブジェクトに自動変換してくれていて、strictモードだとその変換をしないため このような挙動になるそうな。

var f = () => {'use strict'; return this};
f() === window; // またはグローバルオブジェクト

アロー関数ではthisに関するstrictモードの規則は無視されるのでundefindにはならず
thisはwindowとなる。他の規則は適用される。

(2).メソッド呼び出し

これは冒頭での例、イメージはしやすい。
this = objを指す。

var obj = {
  name: 'taro',
  func: function(){
    console.log(this)
  }
}
obj.func(); // {name: "taro", func: ƒ}

ちなみにES6だと
メソッドはこういう書き方も出来る。

var obj = {
  name: 'taro',
  func(){
    console.log(this)
  }
}
obj.func(); // {name: "taro", func: ƒ}

でも、以下のようにすると関数呼び出しになるので、
this = windowになる。

var obj = {
  name: 'taro',
  func: function(){
    console.log(this);
  }
}
var func = obj.func;
func(); // Window 

逆もまたしかり

var func = function(){
  console.log(this)
}
var obj = {
  name: 'taro'
}
obj.func = func;
obj.func(); // {name: "taro", func: ƒ}

要するに(レシーバオブジェクト)次第でthisが変化する。

これ、アロー関数だとどうなるか、

var obj = {
  name: 'taro',
  func: ()=>{
    console.log(this);
  }
}
obj.func(); // Window 

アロー関数は宣言された時にthisを拘束してしまう。(これでいうとwindowオブジェクト)
obj.funcで呼び出してもthisの参照は変わらない
MDNにも
「アロー関数式は非メソッド型の関数に最もよく合っています。」
と書いてある。

var obj = {
  name: 'taro',
  func: function(){
    console.log(this) // obj
    var func2 = ()=>{
      console.log(this) // obj
      var func3 = ()=>{
        console.log(this) // obj
      }
      func3();
    }
    func2();
  }
}
obj.func();

アロー関数は、関数なりメソッドで囲わないと、
thisのスコープがwindowのままっぽい。。(ここはちゃんと説明出来ない、、)
これだとfunc3のthisはfunc2のthisを、func2のthisは、funcのthisを拘束する。
入れ子の時は便利かもしれない。

(3).コンストラク

function Person(name){
  this.name = name;
  console.log(this);
}

var p = new Person('taro'); // Person {name: "taro"}

「new function」はオブジェクトを返すので
この場合は、thisはPersonインスタンス(オブジェクト)になる

アロー関数はコンストラクタとしては使えない。

var Person = name =>{
  this.name = name;
  console.log(this);
}

// Uncaught TypeError: Person is not a constructor
// これは出来ない
var p = new Person('taro');

(4).apply/call/bindでthisを設定

例えば、以下のような時、 setTimeoutのコールバックによりthisのスコープが変わってしまうので、 期待通りに動かない

var obj = {
  name: 'taro',
  getName(){
    console.log(this.name)
  },
  func(){
    this.getName(); // 'taro'
    setTimeout(this.getName,1000); //  thisがwindowだから getNameがundefindになる
  }
}
obj.func();

なので、 bindでthisを拘束する

var obj = {
  name: 'taro',
  getName(){
    console.log(this.name)
  },
  func(){
    this.getName(); // 'taro'
    setTimeout(this.getName.bind(this),1000); // 'taro'
  }
}
obj.func();

アロー関数でもいける、 外側のthisを参照するので。

var obj = {
  name: 'taro',
  getName(){
    console.log(this.name)
  },
  func(){
    this.getName(); // 'taro'
    setTimeout(()=>{
      this.getName();
    },1000); // 'taro'
  }
}
obj.func();

apply (call) は指定したオブジェクトでメソッドを実行出来るので
以下のようにして thisを変更することも出来る。

var obj = {
  name: 'taro',
  func(){
    function func2(){
      return this.name
    }
    return func2.apply(this)
  }
}
obj.func();

ちなみにMDNより↓↓↓

アロー関数では this は束縛されないので、call() や apply() メソッドは引数しか渡せません。this は無視します。

var adder = {
  base: 1,

  add: function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base: 2
    };

    return f.call(b, a);
  }
};

console.log(adder.add(1));         // 2 を出力する
console.log(adder.addThruCall(1)); // やはり 2 を出力する

まとめ

・thisは4タイプの使い方によって挙動が変わる。
・アロー関数か、そうで無いかで挙動が変わる。

■参考文献 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this https://qiita.com/takkyun/items/c6e2f2cf25327299cf03 https://chaika.hatenablog.com/entry/2017/03/31/083000 https://liginc.co.jp/277527

macで簡易ローカルサーバーを立てる

とりあえず、なにも準備しないで簡易的にローカルサーバーを立てる時、

macOSにはデフォルトで Pythonphpが入っています。

python --version
Python 2.7.10
php -v
PHP 7.1.19 (cli) (built: Aug 17 2018 18:03:17) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

pythonサーバーを立てたい

ディレクトリまで移動して (どこに作成するかは自由です)

cd /Users/ユーザー名/Desktop/testDir(自分で設定した)
python -m SimpleHTTPServer 7777

// サーバーが立ち上がる
Serving HTTP on 0.0.0.0 port 7777 ...

で以下のURLでアクセス出来ます。
ポートは他で使用しているもので無ければ自由に設定出来ます。
http://localhost:7777
終了はCtrl-cです。

phpサーバーを立てたい

cd /Users/ユーザー名/Desktop/testDir(自分で設定した)
php -S localhost:9999
PHP 7.1.19 Development Server started at Sun Oct 28 11:22:13 2018
Listening on http://localhost:9999

で立ち上がります。このサーバーだとphpも動くので簡易的な開発やチェックには便利ですね。
こちらもポートは自由に設定出来ます。 終了はCtrl-cです。
ドキュメントにも書いてありますが使用出来るのは、PHP 5.4.0からで、 あくまでも開発での使用目的でのみ使用してくださいとのこと。

■参考記事
手っ取り早く Mac でローカルサーバーを立てる方法 - tacamy--log
PHP: ビルトインウェブサーバー - Manual

nodeのバージョン管理をnodebrewからndenvに変更した

nodeのバージョン管理にnodebrew

https://github.com/hokaccha/nodebrew

を使っていた。
とても便利だったのだがプロジェクトごとにnodeのバージョンを変えるのが

いちいち手動で面倒だった。
そして、「あれ、このプロジェクト nodeのバージョンなんだっけ??」

となることもしばしばあったので
プロジェクトごとで自動でバージョンを切り替えてくれるndenvに切り替えることにした。

インストール方法はこちらを参照
ndenv を使用して複数のバージョンの Node.js を管理する方法と基本的な使い方 - Qiita


■ nodeのインストール

ndenv install v6.10.0

で、
以下にインストールされる。
/Users/hogehoge/.ndenv/versions


プロジェクトディレクトリに移動して、

ndenv local v6.10.0

と打つと、
.node-version というファイルが出来る
中身は「v6.10.0」とバージョンだけ書いてある。

次回以降は、そのディレクトリに移動すると
自動でnodeのバージョンが切り替わる。

$ node -v
v6.10.0

ただし、これはあくまで「.node-version」ファイルがある環境での話なので
それがない場合は、nodeのコマンドを打ってもエラーが起きてしまう。

なので、globalの環境では、どのバージョンを使うかをセットしてあげましょう。

$ ndenv global v8.11.1

これで、ndenv local していない環境では このバージョンがデフォルトになります。

$ ndenv global
v8.11.1

今までにインストールしたnodeのバージョンを確認したいときは、以下。

bash-3.2$ ndenv versions
  v10.0.0
  v6.10.0
  v6.10.1
* v8.11.1 (set by /Users/hogehoge/.ndenv/version)

特定のバージョンをアンインストールするときは

$ ndenv uninstall v6.10.1

.bash_profile と .bashrc の違い

.bashrcしか使っていなかったのと
毎回違いを調べて忘れるのでメモ。

ここのリンクに詳しく載っていました、ありがたい。

.bash_profile と .bashrc は何が違うの?使い分けを覚える - Corredor


bash_profile
・bashrcより先に実行される
・ログイン時に1回だけ実行される
環境変数を書く(export コマンドで宣言する変数)(環境変数はプロセス間で共有されるので、シェルを起動するたびに何度も呼ぶ必要がない)


■bashrc
bash_profileより後に実行される、というかbash_profileから読み込まれる
・シェルを起動するたびに実行される
環境変数ではない変数、エイリアス、独自のシェル関数を書く

cssアニメーションで JQueryのfadeIn fadeOutを実装する

最近、脱jQueryの流れがあるので、大好きではあるが今やっている案件は、jQueryを使わないで実装することにした。

そこで以外にめんどくさいのがfadeIn fadeOut。

jQueryでは、

opacity:1 → opacity:0 → display:none
display:block → opacity:0→ opacity:1

のようにやっているが
これを素のJSでやると結構めんど臭い。

どうしてもCSS + classをつけたり消したりで、実装したかったのだが
そもそも「display」 プロパティが css transitionや animationに対応したプロパティではないので 色々試したがうまくいかなかった。

そこで見つけたのが、「visibility」プロパティ。 普段、「display」プロパティの影に隠れて使うことがほぼなかったんだけど、 このプロパティは、 hiddenとvisibleの2つの値しか無いが、 transitionやanimationに対応していて

timing functionの値が(tf = 0) => hidden;
timing functionの値が(0 < tf <= 1) => vislble;

となる仕様なので、(以下参照)
https://www.w3.org/TR/css-transitions-1/#animtype-visibility

 .hoge{
    opacity:0;
    visibility:hidden;
    transition: opacity 0.3s , visibility 0.3s;
   &.is-show {
     opacity: 1;
     visibility: visible;
  }

こんな感じで実装ができました。 そういえば、tweenMaxのautoAlphaもvisibilityを使っていたなー。。

かなり便利。ありがとうvisibility

■参考記事 qiita.com qiita.com

photoshop cc でPSDからテキストデータを抜いてくれるスクリプト『ps_bramustextexport』

【PS_Bramus.TextExport-1.3】なるものを見つけたので共有

スクリプトダウンロード先
https://www.bram.us/2008/03/16/ps_bramustextexport-13-automatically-export-all-text-layers-from-photoshop-psd-to-a-text-file/

◆インストール、使い方
Photoshopのテキストレイヤーからテキストを抽出する方法 – Web雑記帳。
「Photoshop上の文字をテキストファイル化、修正、PSに戻す」ができるPS_BRAMUS.TextConvert | ブロックワークス

インストールは、CCでは(Macです)、

/Applications/Adobe Photoshop CC 2017/Presets/Scripts
の中に、
/Applications/Adobe Photoshop CC 2017/Presets/Scripts/ps_bramustextexport-13/PS_Bramus.TextExport-1.3.jsx
のような感じで、フォルダごと入れました。

すると、ccメニューの 【ファイル】→【スクリプト】→【ps_bramustextexport-13】と選択できるようになりました。
レイヤー名と、実際のテキストデータを、テキストファイルにして抽出してくれます。

結構便利かも。

gulp(node)でjsonのデータを読み込む時、jsonファイルの修正が都度反映されない件

gulp(node)を使用時、jsonなどの外部ファイルにデータを持っておき、それを読み込んで処理をしたい時があると思います。

が、以下のように requireで読み込んだ場合、初期に読み込んだものがキャッシュされてしまいタスクを走らせた後に、jsonファイルを修正してもその変更が反映されません。なので、毎回タスクを起動、停止、起動みたいにしのいでました。

gulpfile.js その1

#pug
gulp.task 'pug', ()->
  gulp.src [
    paths.root + '/**/*.pug'
    "!"+ paths.root + '/**/_*.pug'
  ]
    .pipe plumber()
    .pipe data (file)->
        {
          'conf':require './src/data/config.json', 'utf8' 
          'conf':require './src/data/data.json', 'utf8' 
        }
    .pipe pug {pretty: true}
    .pipe gulp.dest(paths.dist)
    .pipe browser.reload({stream:true})


調べたら、同じことで悩んでいる人がいましたw
nodeにデフォルトでビルドインされている
「fs」モジュールを使用してfs.readFileSyncメソッドを使うようです!


gulpfile.js その2

fs   = require 'fs' # これ必要 デフォルトの機能なので npm installは不要です

#pug
gulp.task 'pug', ()->
  gulp.src [
    paths.root + '/**/*.pug'
    "!"+ paths.root + '/**/_*.pug'
  ]
    .pipe plumber()
    .pipe data (file)->
        {
          'conf':JSON.parse(fs.readFileSync('./src/data/config.json', 'utf8'))
          'data':JSON.parse(fs.readFileSync('./src/data/data.json', 'utf8'))
        }
    .pipe pug {pretty: true}
    .pipe gulp.dest(paths.dist)
    .pipe browser.reload({stream:true})

これで、リアルタイムに更新が反映されるようになりました!!

【参考サイト】
node.jsでjsonファイルを読み込む方法 - まーぽんって誰がつけたの?

.gitignoreでフォルダ内を複雑に無視する方法

ディレクトリ内にある特定のフォルダのみignoreしたい場合は(今回の場合はhoge
面倒だが以下のように書いていくしかないみたい。
全体を無視

その下の特定のディレクトリだけ許可

その下の特定のディレクトリの下を無視

その下の特定のディレクトリの下の特定の・・・・

めんどくさいけどwordpressのテーマディレクトリのみ管理したと行った場合に使えます。

#wp
cms/wp/*
!cms/wp/wp-content/
cms/wp/wp-content/*
!cms/wp/wp-content/themes/
cms/wp/wp-content/themes/*
!cms/wp/wp-content/themes/hoge/

【参考サイト】
[ようやく見つけたかもしれない]WordpressサイトをGit管理する方法[メモ] - Qiita
[Git] .gitignoreの仕様詳解 - Qiita

gulpで引数によって処理を分けたい

例えば、引数によって開発環境ではjsをそのまま、本番環境ではminifyする。
などしたい場合。

gulplife.coffee

############
# module
############

gulp = require 'gulp'
coffee = require 'gulp-coffee' # coffeescriptを書くのに必要
uglify = require 'gulp-uglify' # ファイルをminify
gulpIf = require 'gulp-if' # 条件文を使えるようにする
minimist = require 'minimist' # タスクに引数を渡せる


############
# path
############

paths =
  assets: "./src/root/assets"
  assets2: "../htdocs/assets"

############
# 変数
############

# 引数をタスクに渡す
knownOptions =
  string: 'env'
  default:
    env: process.env.NODE_ENV || ''  #ここでデフォルト値を設定できる

options = minimist(process.argv.slice(2), knownOptions)

############
# タスク
############
gulp.task 'coffee',()->
  gulp.src paths.assets + '/js/**/*.coffee', { sourcemaps: true }
  .pipe coffee({ bare: true })
  .pipe gulpIf(!(options.env is 'dev'), uglify())
  .pipe gulp.dest(paths.assets2 + '/js')

重要なのは、「gulpIf」と「minimist」 です。
gulpIfはタスクのpipeの中で、if文が使えるというもの。
minimistは、コマンドラインを叩くときの引数をパースしてオブジェクトとして返してくれる。

引数を付け忘れる、なにも付けないとき -> minifyされる

$ gulp coffee

引数にdevをつける -> minifyされない

$ gulp coffee --env dev

引数にdev以外をつける -> minifyされる

$ gulp coffee --env production

【参考サイト】
CLIから引数を渡す | gulp 日本語リファレンス | js STUDIO

mac で VirtualBoxを使い ieの検証環境を準備する

webmem.hatenablog.com

kudakurage.hatenadiary.com

pc-karuma.net

pc-karuma.net

上記記事にも記述してあるが、ダウンロードする仮想マシンがデフォルトだと、
Windowsのものがダウンロードされてしまうので、macのものに手動で変更する必要がある。

https://az412801.vo.msecnd.net/vhd/VMBuild_20141027/VirtualBox/IE11/Windows/IE11.Win8.1.For.Windows.VirtualBox.zip

https://az412801.vo.msecnd.net/vhd/VMBuild_20141027/VirtualBox/IE11/Mac/IE11.Win8.1.For.Mac.VirtualBox.zip

vagrantの設定

フロントエンドの開発だけならばnode.jsなりでローカルサーバーを立てればいいが、サーバーサイドのローカル開発環境も欲しい!ってなったとき&Windowsマシンでもlinux環境が欲しいとなったので(MTやWordpressレベルならxamppやmampでいいかも)、
vagrant」を導入。

f:id:resistance_underground:20160603113357p:plain

vagrantを使うにはvirtualboxが必要なので、これを先にインストールする。
Oracle VM VirtualBox

それが出来たら、vagrantをインストールする。
Vagrant by HashiCorp

vagrantのいいところは「box」というOS(centosubuntuとか)から何やらのパッケージの詰め合わせものがあり、
それをここからダウンロードする。色々な人が様々なboxをここに用意してくれているのでこれを拝借する。
なお、今回はvirtualboxを元にvagarntを使っているが
[Provider filter]の箇所に
vmwareとか dockerとか parallelsって書いてあるので他の仮想環境でもいけるみたい。

http://www.vagrantbox.es/

gulpでbabelを導入する

まだブラウザだったりnodeで対応していない箇所もあるけど、
そろそろES6の勉強もしないとなぁということで、手っ取り早くgulpにbabelを導入することにしました。

f:id:resistance_underground:20160525215925p:plain

https://babeljs.io/

インストール

   npm install --save-dev gulp-babel babel-preset-es2015

babelのバージョンが上がったため、
gulp-babelだけだと es6→es5 に変換してくれない。
変換用のプリセットが必要です。

ここに色々まとめてあります。
React.js用のプリセットもあるようですね。
babeljs.io

gulpfile.jsはこんな感じ

const gulp = require('gulp');
const webserver = require('gulp-webserver');
const babel = require('gulp-babel');
const rename = require('gulp-rename');
const plumber = require('gulp-plumber');

gulp.task('webserver',function(){ // ローカルサーバー立ち上げ
	gulp.src('./')
		.pipe(webserver({
			host: '0.0.0.0',
			port: 8888,
			livereload: true
		}));
})

gulp.task('babel',function(){
	gulp.src('./*_es6.js')
		.pipe(plumber())
		.pipe(babel(
		{ presets: ['es2015']} // ここでプリセットを指定する
			))
		.pipe(rename(function(path){
			var len = path.basename.length - 4;
			path.basename = path.basename.slice(0, len);
			// renameモジュールを使って、hogehoge_es6.js(es6ファイル)を
			// distフォルダ内に hogehoge.js(es5ファイル)に変換&リネームして格納する
		}))
		.pipe(gulp.dest('dest'))
});

gulp.task('babel_watch', function(){
	gulp.watch('./*_es6.js', ['babel']) // ファイル監視
});


これを走らせてみる。

index_es6.js(変換前)

'use strict';

// 関数
var fn = () =>{
	console.log("hoge");
}

// 分割代入と入れ替え
var [a,b] = [22,"#"];
	[a,b] = [b,a];

index.js(変換後)

'use strict';

// 関数

var fn = function fn() {
	console.log("hoge");
};

// 分割代入と入れ替え
var a = 22;
var b = "#";
var _ref = [b, a];
a = _ref[0];
b = _ref[1];
_ref;


babelがすべてのES6に対応しているわけではないので、調べながら
使ってみようと思う。

Arrayオブジェクトのメンバ

arr.concat(arr2)

2つの配列を結合

var arr1 = ["りんご","バナナ","みかん"];
var arr2 = [1,22,333,4444];
console.log(arr1.concat(arr2))
// ["りんご", "バナナ", "なし", 1, 22, 333, 4444]

arr.join(del)

配列内の要素を区切り文字で結合

var arr1 = ["りんご","バナナ","みかん"];
console.log(arr1.join("と"))
// りんごとバナナとみかん

arr.slice(start [,end])

start+1番目からend番目の要素で配列を作成

var arr = [11,22,33,44,55,66];
console.log(arr.slice(2,5))
// [33,44,55]

arr.splice(start,cnt [,rep,..])

start+1番目からstart+cnt+1番目の要素をrepで差し替え。
差し替えられた要素を返す、元の配列は差し替えられて変更される。

var arr = [11,22,33,44,55,66];
console.log(arr.splice(2,3,"★","▲")) // [33,44,55]
console.log(arr) // [11, 22, "★", "▲", 66]

arr.pop()

配列の最後の要素を取得して返す
その要素は元の配列からは取り除かれる。

var arr = [11,22,33,44,55,66];
console.log(arr.pop()) // 66
console.log(arr) // [11, 22, 33, 44, 55]

arr.push(data1,data2,..)

配列の最後の要素に指定した要素を追加して、配列の長さを返す。
元の配列は変更される。

var arr = [11,22,33,44];
console.log(arr.push("P","S")) // 6
console.log(arr) // [11, 22, 33, 44, "P", "S"]

arr.shift()

配列の最初の要素を取得して返す
その要素は元の配列からは取り除かれる。

var arr = [11,22,33,44,55,66];
console.log(arr.shift()) // 11
console.log(arr) // [22, 33, 44, 55, 66]

arr.unshift(data1,data2,..)

配列の最初に指定した要素を追加して、配列の長さを返す。
元の配列は変更される。

var arr = [11,22,33,44];
console.log(arr.unshift("P","S")) // 6
console.log(arr) // "P", "S", 11, 22, 33, 44]

arr.reverse()

配列の順序を逆に並べ替える。
元の配列は変更される。

var arr = [11,22,33,44];
console.log(arr.reverse()) // [44, 33, 22, 11]
console.log(arr) // [44, 33, 22, 11]

arr.sort(fnc)

配列の順序を昇順に並べ替える。
元の配列は変更される。
fncに独自の関数を定義してソートを再定義できる。
その際「引数は2つあること」、「第一引数が第二引数より小さいと負を、大きいと正を返す」、という仕様にする必要がある。

var arr = [100,55,9,404];
var arr2 = [[1,2,9],[122,2],[1,2,4,3],[100]];

console.log(arr.sort()) // [100, 404, 55, 9] 文字列としてソート
console.log(arr) // [100, 404, 55, 9]

console.log(arr.sort(
	function(x,y){
		return x-y;
	}
)) // [9, 55, 100, 404] 数字の大きさでソートする場合はこのように定義

document.writeln(
arr2.sort(
	function(x,y){
		return x.length - y.length;
	}
)
	)
console.log(arr2.sort(
	function(x,y){
		return x.length - y.length;
	}
)) // [[100],[122,2],[1,2,9],[1,2,4,3]] 配列の長さでソートする場合はこのように定義

console.log(arr2.sort(
	function(x,y){
		var x1 = 0;
		var y1 = 0;
		for(var i=0; i<x.length; i++){
			x1 +=x[i];
		}
		for(var i=0; i<y.length; i++){
			y1 +=y[i];
		}
		return x1 - y1;
	}
)) // [[1,2,4,3],[1,2,9],[100],[122,2]] 配列の中身を足したものの小さい順に並べる

arr.toString()

配列を文字列に変換

var arr = [100,55,9,404];
console.log(arr.toString()) // 100,55,9,404 配列を文字列に変換
console.log(arr) // [100, 404, 55, 9]

arr.reduce(func(prev,cur,index,array))


隣り合う2つの配列要素に対して(左から右へ)同時に関数を適用し、単一の値にする。

  • prev が一つ前に処理していた要素
  • cur が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

結構便利で、以下のように色々定義できる。
IE9からサポート

var arr = [4,3,2,1];
var arr2 = [[11,22],[33,44],[55,66]];

var sum = function(){
	return arr.reduce(function(prev,cur,index,array){
		return prev + cur;
	});
}
var max = function(){
	return arr.reduce(function(prev,cur,index,array){
		return Math.max(prev,cur);
	});
}
var min = function(){
	return arr.reduce(function(prev,cur,index,array){
		return Math.min(prev,cur);
	});
}
var con = function(){
	return arr2.reduce(function(prev,cur,index,array){
		return prev.concat(cur);
	});
}

console.log(sum()); // 10 配列内を全て足した関数
console.log(max()); // 4 配列内で一番大きいものを返す関数
console.log(min()); // 1 配列内で一番小さいものを返す関数
console.log(con()); // [11, 22, 33, 44, 55, 66] 複数の配列を一つの配列に結合して返す関数

これと似たメソッドのreduceRightは配列の右から左へ処理を行う

var arr = [1,2,3,4,5];
console.log(
	arr.reduce(function(prev,cur,index,array){
		return prev - cur;
	})
);
// -13
console.log(
	arr.reduceRight(function(prev,cur,index,array){
		return prev - cur;
	})
);
// -5


サポートしてないブラウザもこれを入れればいけるようです

※参考
Array.prototype.reduce() - JavaScript | MDN

if (!Array.prototype.reduce) {
  Array.prototype.reduce = function reduce(accumulator){
    if (this===null || this===undefined) throw new TypeError("Object is null or undefined");

    var i = 0, l = this.length >> 0, curr;

    if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
      throw new TypeError("First argument is not callable");

    if(arguments.length < 2) {
      if (l === 0) throw new TypeError("Array length is 0 and no second argument");
      curr = this[0];
      i = 1; // start accumulating at the second element
    }
    else
      curr = arguments[1];

    while (i < l) {
      if(i in this) curr = accumulator.call(undefined, curr, this[i], i, this);
      ++i;
    }

    return curr;
  };
}

arr.map(func(val,index,array))


配列の各要素に、引数として渡された関数を適用した配列を作る。

  • val が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

IE9からサポート

var arr = [1,2,3,4,5];
console.log(
	arr.map(function(val,index,array){
		return Math.pow(val,2);
	})
)
// [1, 4, 9, 16, 25] それぞれの要素を2乗した配列を返す
console.log(arr) // [1, 2, 3, 4, 5]

arr.filter(func(val,index,array))

配列の各要素を、引数として渡した関数でフィルタリングしたもので配列を作る。

  • val が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

IE9からサポート

var arr = [1,2,3,4,5,6,7,8,9,10];
console.log(
	arr.filter(function(val,index,array){
		return val % 2 === 0;
	})
)
// [2, 4, 6, 8, 10] 偶数のみで配列を作る
console.log(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

arr.some(func(val,index,array))

配列中の処理で、引数として渡した関数でテストしたものに一つでもあえばtrueを返す。

  • val が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

IE9からサポート

var arr = [1,2,3,4,5,6,7,8,9,10];
console.log(
	arr.some(function(val,index,array){
		return val % 2 === 0;
	})
)
// true 配列の各要素で1つでも条件があうものがあればtrue

arr.every(func(val,index,array))

配列中の処理で、引数として渡した関数でテストしたものが全てあえばtrueを返す。

  • val が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

IE9からサポート

var arr = [1,2,3,4,5,6,7,8,9,10];
var arr2 = [2,4,6,8,10];
console.log(
	arr.every(function(val,index,array){
		return val % 2 === 0;
	})
)
// false 偶数と奇数があるので
console.log(
	arr2.every(function(val,index,array){
		return val % 2 === 0;
	})
)
// true 全て偶数なので

isArray(obj)

チェックするオブジェクトが配列であればtrueを、そうでなければfalseを返す。

IE9からサポート

// 以下の呼び出しはすべてtrueを返す
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// あまり知られていないもののArray.prototypeは配列:
Array.isArray(Array.prototype); 

// 以下の呼び出しはすべてfalseを返す
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });

IE8も以下のコードを追加することで使用が可能

if (!Array.isArray) {
	Array.isArray = function(arg) {
		return Object.prototype.toString.call(arg) === '[object Array]';
	};
}

arr.indexOf(data)

配列内に検索対象の要素があったらそのインデックスを返す。

var arr = [1,2,3,4,1,4,3,4];
console.log(
	arr.indexOf(4) // 3
);
console.log(
	arr.indexOf(4,4) // 5 5番目の要素から4を探す
);
console.log(
	arr.indexOf(-1) // -1
);
console.log(
	arr.indexOf(3,-2) // 6 後ろから
);
console.log(
	arr.indexOf(3,9)// -1 配列の長さを超えるとだめ
);

arr.lastIndexOf(data)

配列内に検索対象の要素があったらそのインデックスを返す。
後ろから前へ検索する。

var arr = [1,2,3,4,1,4,3,4];
console.log(
	arr.lastIndexOf(4) // 7
);
console.log(
	arr.lastIndexOf(4,4) // 3
);
console.log(
	arr.lastIndexOf(-1) // -1
);
console.log(
	arr.lastIndexOf(3,-2) // 6 後ろから
);
console.log(
	arr.lastIndexOf(3,9)// 6 
);

arr.forEach(func(val,index,array))

配列の各要素で処理を行う。

  • val が今処理している要素
  • index 今処理している要素のインデックス
  • array 処理している配列が入っている

IE9からサポート

var arr = [10,20,30];
arr.forEach(function(val, index, array){
		console.log(index + " is " + val)
})
// 0 is 10
// 1 is 20
// 2 is 30

Mathオブジェクトのメンバ

abs(num)

絶対値

document.writeln(Math.abs(-20)); // 20 絶対値

max(num1,num2)

2つのうち大きいほうを返す

document.writeln(Math.max(11,2)) // 11

min(num1,num2)

2つのうち小さいほうを返す

document.writeln(Math.max(11,2)) // 2

pow(base,p)

べき乗、baseのp乗

document.writeln(Math.pow(3,4)) // 3の4乗

random()

0-1未満の乱数を返す

document.writeln(Math.random()) // 0.20274491156190222

ceil(num)

小数点以下の切り上げ(num以上の最小の整数)

document.writeln(Math.ceil(1.03)); // 2

floor(num)

小数点以下の切り捨て(num以下の最大の整数)

document.writeln(Math.floor(1.03)) // 1

round()

四捨五入

document.writeln(Math.round(1.03)) // 1
document.writeln(Math.round(1.53)) // 2
document.writeln(Math.round(1.43)) // 1

sqrt(num)

numの平方根

document.writeln(Math.sqrt(2)) // 1.4142135623730951

三角関数

角度の単位はラジアン

document.writeln(Math.PI) // 円周率 3.1415
document.writeln(Math.cos(1)) // 0.5403023058681398
document.writeln(Math.sin(1)) // 0.8414709848078965
document.writeln(Math.tan(1)) // 1.5574077246549023
document.writeln(Math.acos(1)) // 0
document.writeln(Math.asin(1)) // 1.5707963267948966
document.writeln(Math.atan(1)) // 0.7853981633974483

指数・対数

document.writeln(Math.E) // 自然対数の底 2.71828182845904
document.writeln(Math.LN2) // 2の自然対数 0.6931471805599453
document.writeln(Math.LN10) // 10の自然対数 2.302585092994046
document.writeln(Math.LOG2E) // 2を底としたeの対数 1.4426950408889634
document.writeln(Math.LOG10E) // 10を底としたeの対数  0.4342944819032518
document.writeln(Math.log(Math.E)) // 自然対数 1
document.writeln(Math.exp(1)) // 指数対数(eの累乗) 2.718281828459045

Stringオブジェクトのメンバ

indexOf(substr [,start])

文字列前方(start+1文字)から部分文字列substrを検索

var str1 = "あいうえおあいうえお";
document.writeln(str1.indexOf("えお")); // 3 前から検索
document.writeln(str1.indexOf("えお",-5)); // 3 マイナスにしても0から?
document.writeln(str1.indexOf("えお",5)); // 8 6文字目から右を検索
document.writeln(str1.indexOf("えこ")); // -1 無し

var str1 = "C3P-O and R2-D2";
document.writeln(str1.indexOf("anakin") > -1 || str1.indexOf("C3P-O") > -1); // true ユーザーエージェントとかで使ったり

lastIndexOf(substr [,start])

文字列後方(start+1文字)から部分文字列substrを検索

var str2 = "あいうえおあいうえお";
document.writeln(str2.lastIndexOf("えお")); // 8 後ろから検索
document.writeln(str2.lastIndexOf("えお",5)); // 8 6文字目から左を検索
document.writeln(str2.lastIndexOf("えお",15)); // 8 文数超えるとよくわからん
document.writeln(str2.lastIndexOf("えお",-5)); // -1 マイナスはだめそう?
document.writeln(str2.lastIndexOf("えこ")); // -1 無し

charAt(n)

n文字目を抽出

var str3 = "あいうえおあいうえお";
document.writeln(str3.charAt(3)); // え 4文字目を抽出
document.writeln(str3.charAt(13)); // "" 空文字

slice(start [,end])

start+1文字目からend文字目までを抽出

var str4 = "123456789";
document.writeln(str4.slice(3)); // 456789
document.writeln(str4.slice(2,7)); // 34567
document.writeln(str4.slice(5,2)); // "" (start > end) は空文字
document.writeln(str4.slice(5,-2)); // 67 後方から数えたら -2は7文字目になる

substring(start [,end])

start+1文字目からend文字目までを抽出

var str5 = "123456789";
document.writeln(str5.substring(3)); // 456789
document.writeln(str5.substring(2,7)); // 34567
document.writeln(str5.substring(5,2)); // 345 (start > end)は入れ替える
document.writeln(str5.substring(5,-2)); // 12345 -2は0とみなす、そのあと入れ替える

substr(start [,cnt])

start+1文字目からcnt文字を抽出

var str6 = "123456789";
document.writeln(str6.substr(3)); // 456789 4文字目から最後までを抽出
document.writeln(str6.substr(2,7)); // 3456789 3文字目から7文字を抽出

split(start [,limit])

文字列を分割文字列strで分割し、その結果を配列として取得(引数limitは最大分割数)

var str7 = "あいうえおあいうえおあいうえおあいうえお";
document.writeln(str7.split("い")); // あ,うえおあ,うえおあ,うえおあ,うえお 「い」で分割して配列を返す
document.writeln(str7.split("い",3)); // あ,うえおあ,うえおあ 「い」で分割して配列を返すけど長さ3まで

toLowerCase(), toUpperCase()

小文字に変換、大文字に変換

var str8 = "ABC";
document.writeln(str8.toLowerCase()); // abc 小文字化
document.writeln(str8.toLowerCase().toUpperCase()); // ABC 大文字化
document.writeln(navigator.userAgent.toLowerCase()); // uaを小文字にして分岐に使うとか
// mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/50.0.2661.102 safari/537.36

concat(str)

文字列の後ろにstrを結合

var str9 = "元気に";
document.writeln(str9.concat("挨拶")); // 元気に挨拶

length

文字列の長さ

var str10 = "元気に123ダー";
document.writeln(str10.length); // 8 日本語も1文字と数える