TypeScriptを学べばJavaScriptも学べるらしいと信じて...

f:id:ts0818:20211225140141j:plain

japan.zdnet.com

 Wizによると、影響を受けるのは、「Azure App Service」内のクリーンなデフォルトアプリケーション上で、2017年9月以降に「Local Git」を用いてデプロイしたすべてのPHPやNode.js、RubyPythonのアプリケーションだという。また、アプリケーションコンテナー内でファイルを作成したり、修正したりした後、2017年9月以降にGitソースを用いてAzure App Service内にデプロイしたすべてのPHPやNode.js、RubyPythonのアプリケーションも影響を受けるという。

マイクロソフト、「Azure」に存在する「NotLegit」脆弱性への対応を発表 - ZDNet Japan

⇧ う~ん、「Azure App Service」が何なのかと言うと、

tech-lab.sios.jp

f:id:ts0818:20211225135531p:plain

App Serviceは上図のPaaSの部分に相当します。OSやミドルウェアの部分はぜーんぶAzure側が面倒を見てくれます。開発エンジニアが見る部分はランタイムより上の部分です。App Serviceで提供されているランタイムを選択して、ビルド済みのアプリケーションをデプロイするだけです。

推しのAzureリソース「App Service」について語り尽くしました | SIOS Tech. Lab

⇧ ということのよう。

「NotLegit」の脆弱性について、Javaには言及されてないところを見ると、「WAR(Web application ARchive)」のデプロイとかは影響を受けないってことですかね。

今回は、「TypeScript」についてです。

レッツトライ~。

TypeScriptとは?

Wikipediaさんによりますと、

TypeScript はマイクロソフトによって開発され、メンテナンスされているフリーでオープンソースプログラミング言語である。TypeScriptはJavaScriptに対して、省略も可能な静的型付けとクラスベースオブジェクト指向を加えた厳密なスーパーセットとなっている。C#のリードアーキテクトであり、DelphiTurbo Pascalの開発者でもあるアンダース・ヘルスバーグがTypeScriptの開発に関わっている。

TypeScript - Wikipedia

TypeScriptはクライアントサイド、あるいはサーバサイド (Node.js) で実行されるJavaScriptアプリケーションの開発に利用できる。

TypeScriptは大規模なアプリケーションの開発のために設計されている。

TypeScriptはJavaScriptのスーパーセットであるため、既存のJavaScriptプログラムは、全て有効なTypeScriptプログラムとなる。

TypeScript - Wikipedia

⇧ ということらしいのですが、「TypeScript」を大雑把に解釈すると、

 TypeScript = JavaScript \times 静的型付け \times クラスベースオブジェクト指向

のコラボレーションということで、「JavaScript」に、

の機能を加えたものということらしい。

ちなみに、「JavaScript」は「動的型付け」言語という位置付けらしいです。

github.com

TypeScript is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the playground, and stay up to date via our blog and Twitter account.

https://github.com/microsoft/TypeScript

Microsoftの公式の説明によると、ブログやTwitterで最新情報を入手して欲しいということでしょうか、なかなか辛いところですな...

JavaScriptとは?

そんじゃ、「JavaScript」って?

JavaScript(ジャバスクリプト)とは、プログラミング言語のひとつである。JavaScriptプロトタイプベースオブジェクト指向スクリプト言語であるが、クラスなどのクラスベースに見られる機能も取り込んでいる。

JavaScript - Wikipedia

利用される場面はWebサイトWebアプリ・バックエンド・デスクトップアプリモバイルアプリなど、ブラウザからサーバ、デスクトップからスマートフォンまで多岐にわたっている。

JavaScript - Wikipedia

⇧ とあるのですが、

新しい (ES2015以降) JavaScriptではクラスの構文によりプロトタイプを意識せずにオブジェクト指向プログラミングをすることが可能になったが、言語設計はプロトタイプベースの設計を維持している。

JavaScript - Wikipedia

⇧「オブジェクト指向プログラミング」が可能になったとあるけど、そも「プロトタイプベース」って?

プロトタイプベース (Prototype-based) は、オブジェクト指向プログラミングOOP)のスタイルのひとつであり、オブジェクトの生成に既存オブジェクトのクローン(複製)を用いるスタイルを指している。これには直後にメンバを拡充するための空オブジェクトの複製も含まれている。このスタイルは、インスタンスベース(Instance-based)とも呼ばれている。これと対比されるOOPスタイルにクラスベースがある。

プロトタイプベース - Wikipedia

⇧ ということらしいのですが、「プロトタイプベース(prototype base)」と「クラスベース(class base)」の違いとして、イメージ的には、

jsstudy.hatenablog.com

⇧ 上図のような感じになるらしい。

で、「JavaScript」は、

JavaScriptの言語仕様はECMAScriptとして標準化され、実装は各種のJavaScriptエンジンによって提供されている。JavaScriptエンジンの例としてGoogle ChromeV8FirefoxSpiderMonkeySafariJavaScriptCoreが挙げられる。

JavaScript - Wikipedia

言語仕様を定義するECMAScriptのほかに、ウェブブラウザへアクセスするためのAPI仕様にDOMなどがある。これらはECMAScriptとは独立しておりJavaScriptとは独立した概念である。

JavaScript - Wikipedia

⇧ いろんな概念と絡んでるらしく、いまいち定義がモヤっとしてる感がありますな。

オブジェクト指向の面では、JavaScriptのオブジェクトはクラスベースではなくプロトタイプベースである。

JavaScript - Wikipedia

関数型の面では、第一級関数をサポートし関数を第一級オブジェクトとして扱える。

JavaScript - Wikipedia

⇧「関数型」をサポートしてるから、コーディングもトリッキーな感じになりそうですな...

TypeScriptを学べばJavaScriptも学べるらしい

「TypeScript」は最終的に「JavaScript」に変換する必要がありますと。

qiita.com

coliss.com

⇧ 上記サイト様によりますと、「JavaScriptエンジン」にも種類がいろいろあるらしく、「Google Chrome」なんかで使われてるのは「V8」というものらしく、

v8.dev

⇧ なんか、JavaScriptファイルじゃなくても動くんかい!っていうような図を見せさせられる流れはどうなのよ。

そもそも、「CSA(CodeStubAssembler)」って何?

v8.dev

V8’s CodeStubAssembler is a custom, platform-agnostic assembler that provides low-level primitives as a thin abstraction over assembly, but also offers an extensive library of higher-level functionality.

https://v8.dev/docs/csa-builtins

⇧「a custom, platform-agnostic assembler」ってことらしいのですが、「platform-agnostic」と言われましてもね、

情報工学において、アグノスティック (agnostic) であるとは、ソフトウェアハードウェアが、特定のプロトコルプログラミング言語オペレーティング・システムに依存しない、あるいはその仕様の詳細に関知しない設計であることを指す。英語で不可知論を意味する agnosticism に由来する。

アグノスティック (情報工学) - Wikipedia

プラットフォームを問わない場合はplatform agnostic(ほぼクロスプラットフォームと同じ意味)、あるデータの処理や送受信において使用されるインターフェースやOSを問わない場合 data agnostic英語版などといった成句として使われる。

アグノスティック (情報工学) - Wikipedia

⇧ プラットフォームに依存しない「アセンブラ」ってことらしい。

ただ、

Note: Torque replaces CodeStubAssembler as the recommended way to implement new builtins. See Torque builtins for the Torque version of this guide.

https://v8.dev/docs/csa-builtins

⇧「Torque」ってものを使った方がお勧めらしい。

v8.dev

V8 Torque is a language that allows developers contributing to the V8 project to express changes in the VM by focusing on the intent of their changes to the VM, rather than preoccupying themselves with unrelated implementation details.

https://v8.dev/docs/torque

⇧ う~ん、「V8」自体の開発の場合の話ってことなんかな?

typescriptbook.jp

⇧ 上図によると、「ECMAScript」が「JavaScriptエンジン」によって実行されるということらしい。

JavaScript engine is a software component that executes JavaScript code. The first JavaScript engines were mere interpreters, but all relevant modern engines use just-in-time compilation for improved performance.

https://en.wikipedia.org/wiki/JavaScript_engine

JavaScript engines are typically developed by web browser vendors, and every major browser has one. In a browser, the JavaScript engine runs in concert with the rendering engine via the Document Object Model.

https://en.wikipedia.org/wiki/JavaScript_engine

The use of JavaScript engines is not limited to browsers. For example, the V8 engine is a core component of the Node.js and Deno runtime systems.

https://en.wikipedia.org/wiki/JavaScript_engine

Since ECMAScript is the standardized specification of JavaScriptECMAScript engine is another name for these engines. With the advent of WebAssembly, some engines can also execute this code in the same sandbox as regular JavaScript code.

https://en.wikipedia.org/wiki/JavaScript_engine

⇧ う~ん、何か、「ECMAScript」の仕様に準拠しているなら「JavaScript」ファイルでなくても「JavaScriptエンジン」で実行できるってことなんかな?

TypeScriptを学んでみる

結局「JavaScriptエンジン」について、モヤモヤ感しか残らなかったのだけど、「TypeScript」を学んでみますか。

Microsoftの公式のドキュメントによると、「TypeScript」は、

github.com

⇧ 上図のような構成になっているらしいのですが、「TypeScript」は「npm」でインストールする必要があるということで、「Node.js」が必要ということは記述されてないという安定の不親切さ、流石はMicrosoftさん。

自分の環境でインストールされてる「Node.js」を確認してみます。自分は「nvm-windows」という「Node.js」のバージョン管理を行うツールをインストールしているので、「nvm-windows」で「Node.js」のバージョンを確認してます。

「nvm-windows」については、

docs.microsoft.com

Microsoftの公式ドキュメントを参照ください。

f:id:ts0818:20211224211348p:plain

⇧ バージョンが旧い...

全量は確認できないけど、利用可能な「Node.js」のリストを確認。

f:id:ts0818:20211224211724p:plain

⇧ 表示された一覧の中の「LTS(Long Time Support)」版の新し目のをインストールします。

f:id:ts0818:20211224212017p:plain

で、「TypeScript」がインストールできるようになったので、適当に「TypeScript」プロジェクト用のフォルダを作成で。

f:id:ts0818:20211224212250p:plain

コマンドプロンプトで、上記で作成したフォルダへ移動。

npmでインストールできるtypescriptのバージョンを確認。

f:id:ts0818:20211224213004p:plain

f:id:ts0818:20211224213124p:plain

⇧ npm自体のバージョンアップを促されたけども、頑なにグローバルインストールさせようとするの止めて欲しい...
とりあえず、「typescript」は現時点での「LTS(Long Time Support)」の最新っぽいのをインストールしておきます。

f:id:ts0818:20211224213408p:plain

f:id:ts0818:20211224213451p:plain

⇧ インストールされた「node_modules」フォルダの中を確認すると、

f:id:ts0818:20211224213558p:plain

⇧ 「typescript」がインストールされてるようです。

ちなみに、Windowsの場合で、「typescript」をグローバルインストールしない場合、「node_modules\.bin」の中の「tsc」ファイルまでのフルパスを指定してコマンド実行する必要がありますかね。

f:id:ts0818:20211224214127p:plain

f:id:ts0818:20211224214011p:plain

⇧ まぁ、グローバルインストールすると、複数バージョンの使い分けとか面倒くさくなりそうですし、悩ましいところではありますが...

そんでは、適当に、「.ts」ファイルを作成して、

f:id:ts0818:20211224214708p:plain

ファイルの中身を編集。

ubichupas.blogspot.com

⇧ 上記サイト様を参考にさせていただきました。

ちなみに、

glorificatio.org

qiita.com

⇧ 難読化が流行ってるのかは分かりませんが、「Church数」ってものは初めて知ったかも?

In mathematicsChurch encoding is a means of representing data and operators in the lambda calculus. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded data in the lambda calculus this way.

https://en.wikipedia.org/wiki/Church_encoding

⇧「λ(ラムダ)式」が関わってるってことみたいね。

susisu.hatenablog.com

関数 (ラムダ抽象) のみを用いて代数的データを表現 (encode) する方法としてよく知られたものとして, Church encoding と Scott encoding という 2 つの方法がある.

ラムダ計算での代数的データのエンコード的な話 - Object.create(null)

⇧ 上記サイト様によりますと、「Scott encoding」ってものも存在するそうな。

In computer scienceScott encoding is a way to represent (recursive) data types in the lambda calculusChurch encoding performs a similar function. The data and operators form a mathematical structure which is embedded in the lambda calculus.

Mogensen–Scott encoding - Wikipedia

⇧「Church encoding」と似た振る舞いをする関数ってことらしい。

まぁ、脱線しましたが、以下、「TypeScript」で一般的な「FizzBuzz」してみました。

// 変数
let num:number = 100;

// 関数を実行
fizzBuzzByStandard(num);
fizzBuzzByOneliner(num);
fizzBuzzByArray(num);

// 剰余
function fizzBuzzByStandard(num:number):void {
  let result:string = ""
  for (let index:number = 1; index <= num; index++) {
    if (index % 3 == 0 && index % 5 == 0) {
      result += "FizzBuzz";
    } else if (index % 3 == 0) {
      result += "Fizz";
    } else if (index % 5 == 0) {
      result += "Buzz";
    } else {
      
    }
    console.log(index + ": " + result);
    result = "";
  }
}

// 1行縛り
function fizzBuzzByOneliner(num:number):void {
  let result:string = ""
  for (let index:number = 1; index <= num; index++) {
    result =
    index % 3 == 0 && index % 5 == 0 ? "FizzBuzz" :
    index % 3 == 0 ? "Fizz" :
    index % 5 == 0 ? "Buzz" : ""
    console.log(index + ": " + result);
    result = "";
  }
}

// 分岐無し
function fizzBuzzByArray(num:number):void {
  let strArr:readonly String[] = ["FizzBuzz", "", "", "Fizz", ""
                                  ,"Buzz", "Fizz", "", "", "Fizz"
                                  ,"Buzz", "", "Fizz", "", ""];
  for (let index:number = 1; index <= num; index++) {
    console.log(index + ": " + strArr[index % 15]);
  }
}

コンパイルして、「JavaScript」ファイルを作成。「set」コマンドで一時的に「tsc」までのパスを通しておきました。(いま起動してるコマンドプロンプトでのみパスが有効になる。コマンドプロンプトを終了すればパスは無効)

f:id:ts0818:20211224220028p:plain

f:id:ts0818:20211224220157p:plain

JavaScript」ファイルは「Node.js」で実行できるようです。

f:id:ts0818:20211225133516p:plain

JavaScript」ファイルを確認してみる。

// 変数
var num = 100;
// 関数を実行
fizzBuzzByStandard(num);
fizzBuzzByOneliner(num);
fizzBuzzByArray(num);
// 剰余
function fizzBuzzByStandard(num) {
    var result = "";
    for (var index = 1; index <= num; index++) {
        if (index % 3 == 0 && index % 5 == 0) {
            result += "FizzBuzz";
        }
        else if (index % 3 == 0) {
            result += "Fizz";
        }
        else if (index % 5 == 0) {
            result += "Buzz";
        }
        else {
        }
        console.log(index + ": " + result);
        result = "";
    }
}
// 1行縛り
function fizzBuzzByOneliner(num) {
    var result = "";
    for (var index = 1; index <= num; index++) {
        result =
            index % 3 == 0 && index % 5 == 0 ? "FizzBuzz" :
                index % 3 == 0 ? "Fizz" :
                    index % 5 == 0 ? "Buzz" : "";
        console.log(index + ": " + result);
        result = "";
    }
}
// 分岐無し
function fizzBuzzByArray(num) {
    var strArr = ["FizzBuzz", "", "", "Fizz", "",
        "Buzz", "Fizz", "", "", "Fizz",
        "Buzz", "", "Fizz", "", ""];
    for (var index = 1; index <= num; index++) {
        console.log(index + ": " + strArr[index % 15]);
    }
}

ソースコードを見比べた感じ、「JavaScript」の場合、「TypeScript」で定義していた「型」は根こそぎ無くなるので、どんな「型」を扱っているのかを把握できるような変数名だったり関数名にするのが大事ってことですかね。

qiita.com

⇧ 上記サイト様によりますと、「TypeScript」では「セミコロン」を付けなくても良いらしく、混乱の元となっているようです...

モヤモヤ感が半端ない...

今回はこのへんで。