Movatterモバイル変換


[0]ホーム

URL:


mizuky fujitani, profile picture
Uploaded bymizuky fujitani
509 views

JSer Class #1

「JSer Class - JavaScriptの基礎と軽量フレームワーク」と題して職場で開催した勉強会の資料の第1回分。

Embed presentation

Download to read offline
JSer ClassJavaScriptの基礎と軽量フレームワーク
目的• 一般的観点• Webアプリケーション開発のなかで存在感を増し続けるJavaScriptについて、「なんとなくわかる」でない知識を身に付ける。• JavaScriptのメリット、デメリット、代替技術について知ることで、保守/開発の生産性や品質を向上させる。• 特殊的観点• 数カ月後に身近な存在となる某クライアントサイドMVCライクなアプリケーションの保守/開発のための基礎知識を得る。
開催概要• 開催日時• 3/2(水)〜 毎週水曜 19:30〜21:30 全3回予定• 会場• コラボレーションスペース(N・W)• コンテンツ• 第1回 JavaScriptの言語仕様• 第2回 DOMとXmlHttpRequest、軽量フレームワーク• 第3回 クライアントサイドMVC
参考情報• サイト• JavaScriptガイド@MDN• https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide• 書籍• JavaScript 第6版(サイ本)• http://www.amazon.co.jp/dp/4873115736• Effective JavaScript• http://www.amazon.co.jp/dp/4798131113
JSer Class #1JavaScriptの言語仕様
あらためてJavaScriptとは何か?
歴史• その端緒は前世紀末のWWW民間利用解放後のブラウザ競争。• そのなかで生まれたJavaScriptとJScript、そしてECMAScript。• 実装と仕様• JavaScript(実装名) → Netscape社が開発(1995〜)• JScript(実装名) → Microsoft社が開発(1996〜)• ECMAScript(仕様名) → Ecma International(旧称・欧州電子計算機工業会)で策定(1997〜)• はじめに実装ありき。あり方はSQLと似ている。
現状〜今後• 当初• あくまでブラウザ上で何かしらの小規模な処理をこなすための言語• 数年前(v3〜5)• Webサイトの高機能化にともないコード量が増大• ブラウザ間差異の吸収と言語拡張を目的としたライブラリが登場• 現状(v5.1)• V8エンジンを独立ランタイムとして転用したNode.jsの登場• クライアントサイドMVCというデザイン・パターンの登場• TypeScript、CoffeeScript、ClojureScript、Scala.jsといった代替技術の登場• 今後(v6〜)• ???
今、JavaScriptを学ぶ意味なぜあらためて学ぶ必要があるか? 例えば─• 活用シーンの多いから。• ともすえばJavaやC#よりもリーディング力が必要だから。• TypeScriptなど代替技術(上位技術)の挙動理解に重要だから。• 「曖昧に済ませられる」言語で「きっちり動く」「メンテしやすい」アプリをつくるにはテクニックが余計に必要だから。
テキストの構成• わりと行き当たりばったりに:かいつまんだJavaScript言語仕様の提示注意すべきポイント、べき論の提示サンプルコード、例題コードの提示• 例題コードについて:示されるのは極限的状況。それを解くことを通じて「臭う」コードを見分けられるようになってほしい。JavaScriptには言語仕様上、JavaにおけるようなIDEは存在し得ない。「自力でコードを読み解く」能力が重要になる。
学び方• Web上の情報に目を通す• MDNなど。あくまで入門。体系的理解を期待しないこと。• 書籍を読む• 前掲書をおすすめ。• Webブラウザで試してみる• ブラウザが内蔵する開発者ツール、Firebugのような拡張機能、JSFiddleのようなWebサイトを利用する。
JavaScriptにおけるOOP
OOPとは?• Object Oriented Programming。• プログラムの処理(関数)とそれに関係性の強いデータとを「オブジェクト」という単位にまとめることで、プログラムの生産性を高めようという思想=実践。• カプセル化は求められていない点に注意。カプセル化はプログラムの疎結合化を推進するための別の思想=実践。FPでも有効な概念。cf.Haskell、Erlangにおけるエクスポート。オブジェクトデータ 処理(関数)
補足)FPとは?• Functional Programming。• OOPの反対に、関数とデータを完全に切離し、関数の高機能化をはかることで、プログラムの安全性や保守性の向上、並列分散処理系実装の容易化を推し進めようとする思想=実践。• やや「実験場」的で難解。高階関数、クロージャ、ケース式などOOPにも応用できる技術が次々と輸出されている。• 例)Haskell、Erlang、Lisp(およびその方言)
OOPの種類• クラス・ベースのOOP• JavaやC#、Python、Rubyなどはこちらに該当• オブジェクトの「かたち」をクラスであらかじめ宣言• クラスのかたちでオブジェクト(インスタンス)のかたちも決まる• プロトタイプ・ベースのOOP• JavaScriptはこちらに該当(ていうかそれ以外にあるのか?)• 「かたち」はすべて実行時に動的に決定される• プロトタイプ(原型)として指定されたオブジェクトがメンバー(フィールドやメソッド)の継承元となり、それらと自分自身が備えたメンバーでそのオブジェクトの「かたち」が決まる。
プロトタイプ・チェーン• あるオブジェクトにメンバ(フィールド/メソッド)が存在するか確認する際に利用される概念。• メンバ検索の順序:• あるオブジェクトAそのものがメンバを持つかチェック• オブジェクトAのコンストラクタのprototypeフィールドが指すオブジェクトBがメンバを持つかチェック• オブジェクトBのコンストラクタのprototypeフィールドが…(中略)• Object.prototypeが指すオブジェクトXがメンバを持つかチェックfoo bar bazFoo.prototype Bar.prototype
かたち(型)の扱い方• 型とは何か?• プリミティブもオブジェクトも区別せず、味も素っ気もない言い方をすれば「メモリ上に確保されるサイズとそのフォーマット」。• 静的型付け• データには型がある(当たり前)。• 変数・引数・フィールドにも型がある(これが特徴)。• 動的型付け• データには型がある(〃)。• 変数・引数・フィールドには型がない(これが特徴)。
クラスvsプロトタイプ静的型付けvs動的型付け言語 クラスvsプロトタイプ 静的vs動的 ジェネリクスJavaScript プロトタイプ動的 ×Python/RubyクラスJava静的△(イレイジャ)C# ○(非イレイジャ)
なぜ動的&プロトタイプになった?• そもそもは「ちょっとした処理」しか想定していなかった。• Webサイトはいろいろなリソースの寄せ集め。動的協働のためには、バージョン問題を惹起するクラスは厄介。cf.ECMAScript v6におけるクラスとモジュール導入。cf.Erlangにおける動的型付けの意義。cf. TypeScriptにおける「構造的部分型」の導入
動的型付けで得られるもの• ダックタイピングの自由(あるいは責務)• どんな型のデータでも受け取れる・代入できる、ということは取りも直さず、どんな型のデータでもきちんと処理できなくてはならない。この規則に例外はない。• コンパイラやIDEの助けは得られない。• 多重定義メソッドからの解放(もしくは追放)• 受け取るデータの型ごとに多重定義メソッドを宣言しなくてよい。というか、やりたくてもできない。• コンパイラやランタイムが適切なメソッドを選択してくれていたのと同じことを、開発者が自分のコードで行わなくてはならない。
プロトタイプベースで得られるもの• クラスやインターフェース宣言の省略• どうせ変数が動的型付けなら、データの側もあらかじめかたちが決まっている必要はない(やや投げやり)。• メモリの節約• 継承したいオブジェクトがいるなら、直接プロトタイプとして参照してしまえばいい。そうすれば個別インスタンスごとにextendsしたクラスのフィールド分までメモリを消費したりしないで済む。• 代償としてJava/C#にも存在する「継承による強結合」の病弊がもう一段深刻なかたちで発現する点に注意。
ちょっとまとめ• JavaScriptはそのビルディング・ブロックからして他のメジャーな言語とはちがう。• これはそれ自体「悪」というわけではなく、そもそもの目的や設計思想によるもの。• しかし利用方法の変化は以下の諸問題を顕在化させた:• 静的型付けとクラスが提供する事前検証の一切が利用できない• オーバーロード、ジェネリクスなどの可能性も根本から絶たれている• IDEはせいぜい予約語の補完くらいしか開発者をサポートできない• コード量が多くなるにつれてコーディングは煩雑で危険になる• 複数ソースのスクリプトの混在でセキュリティ・リスクが増大する
オブジェクト・グラフ
基本型(プリミティブ)• boolean いまさら説明不要。• number 整数と浮動小数点数の区別はない。• string 文字列はJava同様イミュータブル。• null 基本型なのにtypeof nullは”object”を返す。• undefined 未初期化・未設定を示す。なぜか非予約語。
特殊値null• nullという型の唯一の値/インスタンスがnull。• Javaなどの「オブジェクト参照がない」という意味ではない。• 定義上変数や配列の要素のスロット、関数の戻り値はあるのだが、設定すべき値がないときに、nullを明示的に利用する。
特殊値undefined• 代入まえの変数、指定されなかった引数、存在しない添字アクセスに対する戻り値、return文のない関数の戻り値などで登場。• 強制的に値を生み出したいときはvoid演算子を使う。• 非・予約語なので変数宣言により上書きが可能…。// JavaString hello;System.out.print(hello);// JavaScriptvar hello;console.log(hello);
暗黙型変換• Javaも含む他の多くの言語と同様に暗黙型変換が行われるケースがある。しかしその規則はわかりにくい。• わかりにくい規則を覚えることを考えるまえに、そのようなコーディングを原則禁止とすることを考えるべきである。• ==演算子は暗黙型変換を生起する。代わりに===を使う。• ifの条件式、&&や||の被演算子にboolean以外を指定すると暗黙型変換(ぽい何か)が起こる。以下6値はfalse(ぽい):• 0, -0, ””, NaN, null, undefined
暗黙型変換// JavaScriptvar a = 0;var b = ”0”;var c = + ”0”;var d = + ”a”;console.log(a == b); // (1)console.log(a === b); // (2)console.log(a === c); // (3)console.log(a || false); // (4)console.log(a === NaN); // (5)この変換方法は非常にしばしば利用されている。しかしdの例が示すように危険性も大きく、「文字列が数字の並びだけでできている」という前提なしに利用してはならない。
暗黙型変換ですらない何か// JavaScriptvar a = 0;var b = ”0”;console.log(a || b); // (1)console.log(b || a); // (2)console.log(a && b); // (3)console.log(b && a); // (4)
オブジェクト型(例)• Object オブジェクト(としか言いようがない何か)• Array 配列(ないしマップ)• Arguments 「配列っぽい」オブジェクト• Function 関数オブジェクト• RegExp 正規表現オブジェクト• String 基本型stringに対応するオブジェクト• Number 基本型numberに対応するオブジェクト• Boolean 基本型booleanに対応するオブジェクト
JavaScriptのObjectの特徴• JavaでいえばMap<String,Object>みたいなもの(*)。• キーと値で表現されるプロパティのセット。• JavaScriptでは関数もオブジェクトの一種に過ぎないから、フィールドとメソッドの区別は存在しない。• Mapと異なるのはプロトタイプ・チェーンを備えていること。* 類似性の観点でいうと、Typesafe社のTypesafe Configオブジェクトがもっと適当(参考記事:http://m12i.hatenablog.com/entry/2015/08/17/004038)
オブジェクトの生成(1)リテラルで記述する// JavaScriptvar foo = { bar: 123, baz: ”456” };console.log(foo.bar); // (1)console.log(foo.baz); // (2)console.log(foo.foo); // (3)
オブジェクトの生成(2)コンストラクタで記述する// JavaScriptvar Foo = function() {this.bar = 123;this.baz = "456";};Foo.prototype = { foo: "789" };var foo = new Foo();console.log(foo.bar); // (1)console.log(foo.baz); // (2)console.log(foo.foo); // (3)
プロパティにアクセスするA) ドット表記(obj.prop)B) 添字表記(obj["prop"])// JavaScriptvar obj = { foo: "123", "b a r": 456, "789": "baz" };console.log(obj.foo); // (A)console.log(obj["foo"]); // (B)console.log(obj["b a r"]); // (C)console.log(obj["bar"]); // (D)console.log(obj[789]); // (E)
プロトタイプ・チェーン(再掲)prop0: 123// JavaScriptconsole.log(foo.prop2);console.log(foo.prop3);foo// JavaScriptfoo.prop2 = 987;console.log(foo.prop2);prop2: 987プロパティ参照時はチェーンを遡るプロパティ更新時はチェーンを遡らない
// JavaScriptvar Foo = function() {this.bar = 123;this.baz = "456";};Foo.prototype = { foo: "789" };プロトタイプを通じた参照共有
配列の生成と要素アクセス// JavaScriptvar arr = [1, 2, 3];console.log(arr[1]); // (A)console.log(arr["1"]); // (B)arr["2"] = arr["2"].toString();console.log(arr[2]); // (C)arr.length = 2;console.log(arr[2]); // (D)
for ... in 文• Javaの拡張for文に似ているが、別物。• inの左辺の変数にはinの右辺のオブジェクトのプロパティ名が設定される。• プロパティの検索はプロトタイプ・チェーンを遡って行われる(toStringなどの組込みプロパティをのぞく)。• プロパティ名は例え右辺が配列であろうとstring型。
in演算子とhasOwnPropertyメソッド• in演算子• あるプロパティ名(左辺)があるオブジェクト(右辺)に存在するかどうかを判定する。• 存在判定に際してプロトタイプ・チェーンを遡る。• hasOwnProperty(String)• あるプロパティ名(第1引数)があるオブジェクト(レシーバ)に存在するかどうか判定する。• 存在判定に際してプロトタイプ・チェーンを遡らない。
String/Number/Booleanコンストラクタとしての利用は禁止• ラッパーを使ってオブジェクトを生成していはいけない。• メモリの無駄というだけでなく、同値比較(===)が機能しない。// JavaString a0 = ”a”;String a1 = ”a”;String a2 = new String(”a”);// JavaScriptvar a0 = ”a”;var a1 = ”a”;var a2 = new String(”a”);
ユーティリティとしての利用やオートボクシングの利用はOK• Java同様ユーティリティ・クラスとしての機能は便利。• 基本型に対してメソッド呼び出しを行うと自動的にラッパーが生成され、すぐに破棄される。// JavaScriptNumber.isNaN(100);(100).toExponential();”hello”.replace(”l”, ”r”);実態はどうあれ仕様上はstringはあくまでも基本型であり、メソッドは持たない。
モンキー・パッチは禁止• 以下の前提のもとに組込みオブジェクトを「自分好み」に拡張してしまうこと:• JavaScriptでは一般に定数もしくは再代入不可の変数をサポートしていない。• そしてJavaScriptではオブジェクトの鋳型としてのクラスは存在しない(〜v5.1)。• よって組込みオブジェクトを含むほとんどあらゆるものは変更可能である。
蛇足)Rubyにおけるクラス• RubyはクラスベースのOOP言語。• しかしクラスは実行時に動的に拡張することができる。• それどころか継承ツリーに割り込みをかけることすらできる。• そしてJavaScript同様標準ライブラリを変更できる。• この言語の開発者がクラス概念を採用した理由が分からない。
ちょっとまとめ• JavaScriptのプリミティブ:• 種類が少なく覚えるのは簡単。• ただしundefinedやNaNという特殊値の扱いには注意。• 暗黙型変換はきちんと覚えようとすると大変。• JavaScriptのオブジェクト:• 構造的には非常にシンプル。• ただし曖昧さは無限大。
関数を定義する
オブジェクトとしての関数• JavaScriptでは関数はオブジェクトである。cf. C#のデリゲート、Java8のクロージャ、Rubyのブロック。• したがって関数を格納した配列、関数を引数にとる関数、関数を戻り値とする関数をつくることができる(高階関数)。• 関数はそれが定義されたスコープに存在した変数への参照を保持(束縛)する(後述)。• 定義方法がいろいろある。
関数を定義する(1)Functionコンストラクタ関数• 引数名も関数本体も文字列として渡す。本体はeval()で評価される。このため関数定義のエンクロージング・スコープを参照できない。つまりクロージャとなり得ない。• ふつう使わない。使うべきでもない。
関数を定義する(2)function文• その名の通り関数を定義するための文(statement)。• あるスコープでfunction文で定義された関数は、スコープの他のすべての手続きが行われる前に評価される(「巻き上げ」と呼ばれる現象)。つまりコード上より後方で宣言された関数を、より前方にある手続きで使用できる。なおあるスコープでfunction文で定義された関数は、スコープの外からは参照できない。
関数を定義する(3)匿名function式• 手続きを表す文ではなく、値を返す式(expression)で定義。• 式を書ける場所ならどこにでも書ける。• オブジェクトとしての関数を強調する構文。
関数を定義する(4)名前付きfunction式• 3つ目と異なるのは定義された関数に名前が付いており、自分自身を再帰呼出するときなどに使用できること。• 仮にエンクロージングスコープで同じ名前が使用されていてもこれをシャドウ化する。• ECMAScript v3仕様/実装では、関数ボディのスコープでプロトタイプ・チェーンが発生するため危険。使うべきでない。
存在意義の疑われる仮引数(1)• JavaScriptでは関数の仮引数を宣言できる(当たり前)。• しかし引数の数はすべて実行時に決まる。• 仮引数がなくても引数は受け取られる。• いずれにせよ引数には関数ローカルスコープに自動定義されるargumentsを介してアクセスできる。• 引数が設定されなかった仮引数にはundefinedが設定される。
存在意義の疑われる仮引数(2)// JavaScriptvar foo = function(arg0, arg1) {console.log(arg1);};var bar = function() {console.log(arguments.length);console.log(arguments[0]);};foo(123); // (A)bar(456); // (B)bar(456, undefined); // (C)
関数とスコープ
スコープとは?• 変数/定数が参照できる範囲を制限するもの。スコープ外の変数や定数を参照することはできない。• 視点を変えると、ある変数/定数をコード上に記載した時、その変数/定数はスコープという限定された範囲から検索される。• 同じ名前空間で同じ名前の変数を宣言・代入すれば、上書きが発生してしまう(Java・C#ではコンパイルエラーになる)。• スコープはスタック+α。• スコープがどのような入れ子構造をとるか、どのように生成されるか、どのような寿命を持つか・・・は、言語により異なる。
JavaScriptのスコープ• グローバル・スコープが存在する。• 関数がスコープを形成する。• ブロック・スコープは存在しない。• パッケージは存在しない。• スコープの変数≒オブジェクトのプロパティのケースがある。• スコープが閉じても変数が延命するケースがある。
グローバルスコープが存在する• <script>タグのすぐ内側や*.jsファイルのすぐ内側。• スクリプト・ローカルの考え方はないので名前衝突の危険大。• Java・C#でいえばデフォルトpackageに近い。≠internal// foo.html<script type="text/javascript">var foo = 123;console.log(foo);</script>グローバル・スコープ
関数がスコープを形成する• 関数がスコープを形成する。• そしてこれが明示的にスコープ形成を行う唯一の手段。• Java・C#におけるthisなしのインスタンス/静的変数参照などは×。// JavaScriptvar foo = 123;var bar = function() {var foo = 456;};グローバル・スコープローカル・スコープ
スコープ・チェーン• JavaScriptのスコープ・チェーンは重層構造を持つ。グローバルスコープグローバルで宣言された関数のローカルスコープローカルで宣言された関数のローカルスコープローカルのローカルスコープで変数が検索され、存在しなければより外側のスコープから検索される。
変数宣言には必ずvarを使う// JavaScriptvar foo = 123;var bar = function() {console.log(foo); // (A)foo = 456;console.log(foo); // (B)var foo = 456;console.log(foo); // (C)};bar();console.log(foo); // (D)
ブロック・スコープは存在しない• JavaScriptでは「まるでブロック・スコープがあるかのうような変数宣言」ができる。• しかしブロック・スコープは存在しない。cf.Java。// JavaScriptvar i = "je";for (var i in [1,2,3]) {console.log(i); // (A)}console.log(i); // (B)
パッケージは存在しない• Javaでいうところのpackage、C#でいうところのnamespace、Rubyでいうところのmoduleといった概念が存在しない。• 代わりにオブジェクト・プロパティ・チェーンが利用されることがある。// JavaScriptvar pkg0 = {};pkg0.pkg1 = {};pkg0.pkg1.foo = 123;pkg0.pkg1.bar = function() { ...; };
スコープの変数≒オブジェクトのプロパティというケースがある• グローバル・スコープで変数宣言することは、windowオブジェクトにプロパティを追加することにほかならない。• ほかにも「名前付きfnction式」(後述)のような特殊な動きをするケースがある。// JavaScriptvar foo = 123;console.log(foo); // (A)console.log(window.foo); // (B)
スコープ・チェーン(再掲+α)• JavaScriptのスコープ・チェーンは重層構造を持つ。グローバルスコープグローバルで宣言された関数のローカルスコープローカルで宣言された関数のローカルスコープ名前付きfunction式の関数のプロパティ名前付きfunction式で宣言された関数では、なぜか同関数のプロパティがまず検索されるローカルのローカルスコープで変数が検索され、存在しなければより外側のスコープから検索される。
スコープが閉じても変数が延命するケースがある• 関数が終わればローカル・スコープは閉じる。• しかし関数Aで定義されたローカル・スコープ(a)内で定義された関数Bがあったとき、関数Bで定義されたローカル・スコープ(b)から(a)の変数αを参照していると、(a)が閉じたあともその変数だけは引続き延命して、関数B実行のたびに参照・更新ができる状態になる。• これを「関数Bが変数αを束縛する」とか「関数Bはクロージャである」とか表現する。
スコープが閉じても変数が延命するケースがある// JavaScriptvar A = function() {var a = "foo";var B = function(arg0) {console.log(a);a = arg0;console.log(a);};return B;};// JavaScriptvar B = A();B("bar"); // (1)B("baz"); // (2)var B2 = A();B2("boo"); // (3)
匿名関数でスコープをつくる• 匿名関数式で関数を定義して即座にこれを呼び出す。するとグローバル・スコープの汚染/被汚染を気にせずに済む自分だけのローカル・スコープを手に入れられる。// JavaScriptvar foo = 123;(function(){// anonymous namespacevar foo = 456;...})();
ちょっとまとめ• JavaScriptのスコープは、Javaなどと比べて簡素。• ようするにグローバルとローカルしか存在しない。• JavaScriptにはpackageやnamaspaceの概念がない(〜v5.1)ので「名前空間汚染」は常時・深刻な問題となる。• 「クロージャ」はJavaの内部クラス同様(それ以上)に便利な概念。ただしちょっと難解。• JavaScriptの関数はスコープ・チェーンのかなめとなる。• スコープ・チェーンにはときどきプロトタイプ・チェーンが関与する。
コンストラクタとthis
コンストラクタとしての関数• 関数にnewをつけて呼びだすとコンストラクタとして機能する。• このとき関数本文内のthisは新しく生成されたオブジェクトを指す。// JavaScriptvar Foo = function(arg0) { this.bar = arg0; };var foo = new Foo(123);console.log(foo.bar); // (A)Foo(456);console.log(bar); // (B)
メソッドとしての関数• オブジェクトのプロパティに設定された関数が、オブジェクトをレシーバとして実行されるとメソッドとして振る舞う。• このときthisはレシーバ・オブジェクトを指す。// JavaScriptFoo.prototype.baz = function() {console.log(this.bar);};var foo = new Foo(123);foo.baz(); // (A)// JavaScriptvar baz2 = foo.baz;var bar = 456;baz2(); // (B)
曖昧なthis(1)関数の状況 関数の機能(役割)とthisが指すオブジェクトグローバルスコープで定義されたコンストラクタグローバルスコープで定義された関数で、new演算子ありで実行……関数はコンストラクタ関数として機能。関数はコンストラクタ関数として機能し、thisはObject.prototypeからプロパティを継承する新しいオブジェクトを指す。明示的にreturn式が実行されない限りこのthisが呼出元に返される。グローバルスコープで定義された関数グローバルスコープで定義された関数で、new演算子なしに実行……thisはwindowを指す。プロパティ参照されたコンストラクタオブジェクトのプロパティに設定された関数で、new演算子ありで実行……関数はコンストラクタ関数として機能。1つ目と同じ。プロパティ参照された関数(メソッド)オブジェクトのプロパティに設定された関数で、new演算子なしに実行(メソッドとして実行)……thisはオブジェクトを指す。
曖昧なthis(2)関数の状況 関数の機能(役割)とthisが指すオブジェクトローカルで定義されたコンストラクタローカルスコープで定義された関数で、new演算子ありで実行……関数はコンストラクタ関数として機能。1つ目と同じ。ローカルで定義された関数ローカルスコープで定義された関数で、new演算子なしに実行……thisはwindowを指す。エンクロージングスコープを形成する関数がメソッドであり、そのthisがメソッドの所属するオブジェクトを指していようとも、そのスコープで定義された関数のthisはwindowを指す。* この2スライドで取り上げた関数のパターンは右の参考記事でも解説している:http://m12i.hatenablog.com/entry/2013/08/12/000858*
補足)板挟み状態の再帰関数論• arguments.calleeは「今呼び出されている関数自体」を指す。• 過去において再帰関数の定義にはこのプロパティが用いられた。• しかし現在は代わりに名前付きfunction式を用いるべきとされる(*)。これは「末尾再帰最適化」の妨げとなるためだとか。• ところが名前付きfunction式で宣言された関数のスコープ・チェーンの最前面には関数オブジェクト自身のプロパティ(プロトタイプから継承したものも含む)が来る(v3)。• よってこれはこれで危険。再帰関数の実装において、匿名関数の利用はあきらめるべき・・・か。* なぜarguments.calleeの利用が非推奨となったかの説明はMDBの右のページに解説がある:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee
call/applyによるレシーバ差し替え• 前述のとおり関数内のthisの意味はその宣言方法と呼び出し方法の組み合わせで決まる。• ところでJavaScriptには意図的にレシーバ(this)の差し替えを行う方法が用意されている。// JavaScriptFoo.prototype.baz = function() {console.log(this.bar);};var foo = new Foo(123);var obj = {bar: 456};// JavaScriptfoo.baz.apply(obj, []);関数オブジェクトへの参照thisに参照させたい値関数の引数(配列形式)
補足)安全なthis• 実用的ではないがとにかく安全性を求めなくてはならないケースでは、call/applyを使ってthisを無効化する手法をとることができる。// JavaScriptFoo.prototype.baz = function(v) {this.bar = v;};var foo = new Foo(123);foo.baz.apply(undefined,["456"]);
ちょっとまとめ• JavaScriptの関数は、関数、メソッド、コンストラクタを兼ねる。• thisの扱いはとても微妙で、使いどころに注意する必要がある。
まとめ
まとめ• 繰り返しになるが「自力でコードを読み解く」能力は重要。• JavaScriptの言語要素はとても少ない。しかしそれらを組み合わせたときの挙動は予測しづらい面がある。• そのためにプロトタイプ・チェーンとスコープ・チェーン、そしてthisの振る舞いをきちんと理解しておかなくてはならない。
次回は• 以下の項目について取り上げる予定:• DOM(Document Object Model) API• XmlHttpRequestオブジェクト• 軽量フレームワーク(prototype.js、jQuery)

Recommended

PDF
JSer Class #3
PDF
JSer Class #2
PDF
JavaScript 研修
PDF
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
PDF
大規模なJavaScript開発の話
PPT
Word Press on Movable Type
PDF
Getting start with knockout.js
PDF
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
PDF
むずかしくないJavaScriptのやさしい話 jQueryからの次のステップ #ndsmeetup8
PDF
はじめよう Backbone.js
PDF
JavaScript MVC入門
PDF
Javascriptのあれやこれやをまとめて説明してみる
PDF
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
PDF
Javaな人が気を付けるべきJavaScriptコーディングスタイル
PDF
TypeScriptへの入口
PDF
モダンJavaScript環境構築一歩目
PDF
XPages Day 2013 [B-3] XPages開発を始める Notes技術者のためのWeb技術概論
PDF
Web制作勉強会 #2
PDF
JavaScriptユーティリティライブラリの紹介
PPTX
T119_5年間の試行錯誤で進化したMVPVMパターン
PPTX
AngularJS2でつまづいたこと
PDF
クライアントサイドjavascript簡単紹介
PDF
JavaScript基礎勉強会
PDF
XPagesDay2013 【B-4】 Dojo 徹底解剖! ~ XPages で Dojo を有効活用するには ~
PDF
Java女子部 Java EEハンズオン(応用編)
PDF
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
PDF
JSF2.2で簡単webアプリケーション開発
PPTX
xUnitハンズオン第3回テキスト
PDF
Erlangを触ってみた
PPTX
Erlang

More Related Content

PDF
JSer Class #3
PDF
JSer Class #2
PDF
JavaScript 研修
PDF
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
PDF
大規模なJavaScript開発の話
PPT
Word Press on Movable Type
PDF
Getting start with knockout.js
PDF
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
JSer Class #3
JSer Class #2
JavaScript 研修
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
大規模なJavaScript開発の話
Word Press on Movable Type
Getting start with knockout.js
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~

What's hot

PDF
むずかしくないJavaScriptのやさしい話 jQueryからの次のステップ #ndsmeetup8
PDF
はじめよう Backbone.js
PDF
JavaScript MVC入門
PDF
Javascriptのあれやこれやをまとめて説明してみる
PDF
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
PDF
Javaな人が気を付けるべきJavaScriptコーディングスタイル
PDF
TypeScriptへの入口
PDF
モダンJavaScript環境構築一歩目
PDF
XPages Day 2013 [B-3] XPages開発を始める Notes技術者のためのWeb技術概論
PDF
Web制作勉強会 #2
PDF
JavaScriptユーティリティライブラリの紹介
PPTX
T119_5年間の試行錯誤で進化したMVPVMパターン
PPTX
AngularJS2でつまづいたこと
PDF
クライアントサイドjavascript簡単紹介
PDF
JavaScript基礎勉強会
PDF
XPagesDay2013 【B-4】 Dojo 徹底解剖! ~ XPages で Dojo を有効活用するには ~
PDF
Java女子部 Java EEハンズオン(応用編)
PDF
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
PDF
JSF2.2で簡単webアプリケーション開発
むずかしくないJavaScriptのやさしい話 jQueryからの次のステップ #ndsmeetup8
はじめよう Backbone.js
JavaScript MVC入門
Javascriptのあれやこれやをまとめて説明してみる
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
Javaな人が気を付けるべきJavaScriptコーディングスタイル
TypeScriptへの入口
モダンJavaScript環境構築一歩目
XPages Day 2013 [B-3] XPages開発を始める Notes技術者のためのWeb技術概論
Web制作勉強会 #2
JavaScriptユーティリティライブラリの紹介
T119_5年間の試行錯誤で進化したMVPVMパターン
AngularJS2でつまづいたこと
クライアントサイドjavascript簡単紹介
JavaScript基礎勉強会
XPagesDay2013 【B-4】 Dojo 徹底解剖! ~ XPages で Dojo を有効活用するには ~
Java女子部 Java EEハンズオン(応用編)
Vue.jsの関連ツール・ライブラリ(Vuex, Vue-Router, Nuxt)
JSF2.2で簡単webアプリケーション開発

Viewers also liked

PPTX
xUnitハンズオン第3回テキスト
PDF
Erlangを触ってみた
PPTX
Erlang
PDF
GHC 6.12.1 マルチコア対応ランタイムシステムについて
PDF
Yesod(at FPM2012)
PDF
関数型軽い紹介
PDF
第一回関数型言語勉強会 大阪
PPTX
関数型言語初心者の俺がF#触ってみた
PDF
F#で学ぶ関数プログラミング入門?
PDF
FP習熟度レベルとFSharpxのIteratee
PDF
レスポンシブおっぱいでまなぶスケーラブルグラフィックス
PDF
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
PDF
SIMD.js(ECMAScript 7)
PDF
Katagaitai CTF勉強会 #4 Crypto
 
PDF
これから Haskell を書くにあたって
PPTX
純粋関数型アルゴリズム入門
PDF
120901fp key
 
PDF
One night Vue.js
PDF
関数型言語とオブジェクト指向言語(序章)
PPTX
xUnitハンズオン第1回テキスト
xUnitハンズオン第3回テキスト
Erlangを触ってみた
Erlang
GHC 6.12.1 マルチコア対応ランタイムシステムについて
Yesod(at FPM2012)
関数型軽い紹介
第一回関数型言語勉強会 大阪
関数型言語初心者の俺がF#触ってみた
F#で学ぶ関数プログラミング入門?
FP習熟度レベルとFSharpxのIteratee
レスポンシブおっぱいでまなぶスケーラブルグラフィックス
Pythonista による Pythonista のための Scala 紹介 in BPStudy #49
SIMD.js(ECMAScript 7)
Katagaitai CTF勉強会 #4 Crypto
 
これから Haskell を書くにあたって
純粋関数型アルゴリズム入門
120901fp key
 
One night Vue.js
関数型言語とオブジェクト指向言語(序章)
xUnitハンズオン第1回テキスト

Similar to JSer Class #1

PDF
JavaScript.Next
PDF
JavaScript.Next Returns
PDF
Kanazawa.js.Next
PDF
Java scriptの進化
PDF
JavaScriptことはじめ
PDF
Effective JavaScript Ch.1
KEY
いまさらJavaScript
PPTX
Java scriptの基礎
PDF
JavaScript入門
PDF
JavaScript ライブラリーを使い倒そう #buildinsider
PDF
Buildinsider OFFLINE TypeScriptの基礎から実践・利用事例まで
PDF
JavaScript (ECMAScript) 2013
PPTX
Javascriptのデザインパターン【勉強会資料】
PPT
20090121 J QueryからはじめるJava Script~初級編~
PPTX
JSX
PDF
最強オブジェクト指向言語 JavaScript 再入門!
KEY
春のJavaScript祭り
PPTX
Javascript3
PPT
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
PDF
JavaScriptおよびXPages Vote技術解説
JavaScript.Next
JavaScript.Next Returns
Kanazawa.js.Next
Java scriptの進化
JavaScriptことはじめ
Effective JavaScript Ch.1
いまさらJavaScript
Java scriptの基礎
JavaScript入門
JavaScript ライブラリーを使い倒そう #buildinsider
Buildinsider OFFLINE TypeScriptの基礎から実践・利用事例まで
JavaScript (ECMAScript) 2013
Javascriptのデザインパターン【勉強会資料】
20090121 J QueryからはじめるJava Script~初級編~
JSX
最強オブジェクト指向言語 JavaScript 再入門!
春のJavaScript祭り
Javascript3
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
JavaScriptおよびXPages Vote技術解説

JSer Class #1


[8]ページ先頭

©2009-2025 Movatter.jp