KT会
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # KT#0013-yoshiki JavaScript++ ## 内容 JavaScript についてなんとなく疑問に思ったことを調べてまとめてみる ## 前提 **JavaScript** である。Javascript ではない。 ## バージョン管理ツール Node.js 自体のバージョン管理ツールで nodebrew とか nodevn とか nvm とかあって違いがよくわからんかったので調べてみた。 地味にいろいろある。 - [tj/n (n)](https://github.com/tj/n) - [nvm](https://github.com/nvm-sh/nvm) - [nodenv](https://github.com/nodenv/nodenv) - [nodebrew](https://github.com/hokaccha/nodebrew) マジでどれも良さそう。 `tj/n` or `nvm` が開発が盛んで良さげな気がする。 anyenv というバージョン管理ツールまとめて管理ツールが `nodenv` をサポートしているから、自分は `nodenv` を使っている。 ## yarn と npm どっちも Node.js のパッケージ管理ツール。 ぶっちゃけ違いがわからんかったので調べた。 なんとなく想像がつくが、npm の方が古い (リリース 2010 年)。yarn は 2016 年に Facebook によりリリースされた。2020/7 に yarn 2 なるものがリリースされたらしい。ただ、コミュニティで叩かれまくっており現在は利用非推奨。 人気をみると yarn の勢いが強め。 https://www.npmtrends.com/npm-vs-yarn 大きな違いはロックファイル (プロジェクト内で利用される依存関係の正確なバージョンを示したファイル)。yarn は yarn.lock で npm は package-lock.json。ロックファイルが微妙に違うので yarn と npm を同じプロジェクトで混ぜて使うと、バージョンがぐちゃぐちゃになるかもしれないので非推奨。 yarn の方がパフォーマンスが良いらしい ### 検証 適当な EC2 インスタンスを検証環境とする ``` AMI: ami-0992fc94ca0f1415a (Amazon Linux 2) インスタンスタイプ: t2.medium 対象のプロジェクト: 山田育英会の applicant ``` npm ``` [ec2-user@ip-172-31-45-42 ~]$ npm --version 7.5.4 [ec2-user@ip-172-31-45-42 applicant]$ time npm install real 0m49.814s user 0m52.098s sys 0m4.560s ``` yarn ``` [ec2-user@ip-172-31-33-109 applicant]$ yarn --version 1.22.10 [ec2-user@ip-172-31-33-109 applicant]$ time yarn install real 0m44.116s user 0m37.361s sys 0m11.069s ``` 確かに微妙に早い 昔は yarn の方がセキュリティ的によいと言われていた。npm にはパッケージの脆弱性を気にせずインストールしていたらしい。最近は npm にも脆弱なパッケージをインストールする際に警告がでるので、あまり変わらん。 yarn の登場によって npm が開発頑張りまくって、yarn の性能にほぼ追いついているらしい。 なので、もはやどっちを採用するかは好み。 ## 名前 元の名前は Mocha その後に LiveScript という名前になった。JavaScript の開発者である Brendan Eich の雇い主が当時流行っていた Java に似せるよう命令して JavaScript になった。 JavaScript という名前自体は Netscape という当時 JS を提供していた会社の持ち物。それを Mozila foundation が引き継いで、ECMAScript になっている。なので、本来は JavaScript という名前すら正しい呼び名じゃない。 (シャーペンとかホッチキスみたいな感じ) ES5 対応とかの ES は ECMASCript。ES は大体毎年更新される。 ## var 使うなってなんで? **fuck point 1.** 再宣言可能 var で宣言すると、同じ変数名で再度代入できる ```js > var a = 1; undefined > var a = 2; undefined > let b = 1; undefined > let b = 2 Uncaught SyntaxError: Identifier 'b' has already been declared ``` **fuck point 2.** スコープなんじゃそりゃ スコープが直感的じゃない ``` > var a = 1 undefined > if (true) { var a = 2; console.log(a); } 2 undefined > console.log(a); 2 ``` わかりにくいけど、関数毎のスコープになっている。関数に属していないとグローバルスコープになる。 なんとなく、ブロック単位のスコープでしょと思うと嫌な目にあう。 ``` > var a = 1; undefined > f = () => { var a = 2; console.log(a); } > console.log(a); 1 undefined > f() 2 ``` ## JS の型 基本的にプリミティブ型とオブジェクト型に大別されると思って良い。 ### プリミティブ型 - Boolean 型 - Number 型 - BigInt 型 (使う機会少ない、対応環境が少ないので) - String 型 - Symbol 型 - Null 型 (つまりただの null) - Undefined 型 (他の言語と異なり null と明確に区別してる) Boolean は false, 0, NaN(Not a Number), '', null, undefined を falthy と判定する。 それ以外は truthy となる。 **[疑問]** いやいや、プリミティブとは言いつつも文字列 (String 型) には length が使えるし、数字には toString 関数があるやんけ、何がプリミティブじゃい、オブジェクトやないか。 **[回答]** 本当にプリミティブ型は用意されているものの、実際にアクセスすると対応するラッパーオブジェクトに変換されている。 ```js > testA = 'aaa'; > testB = new String('aaa'); > testA.length; 3 > testB.length; 3 > testA === testB; false > testA === testB.valueOf(); true ``` まぁこれのおかげで、何も意識しなくても便利な関数が利用できている訳だし、厳密性を犠牲にして便利になっているという感じ。 ### オブジェクト型 プリミティブ型以外w。ちなみに JSON で知られる連想配列とか map は狭義のオブジェクト。 これらの狭義のオブジェクトは広義のオブジェクト型を元に作成されている。 ## JavaScript のクラスとプロトタイプベースのオブジェクト指向 厳密にはクラスじゃなくて関数。 ```js > class A { constructor(name){ this.name = name; } } undefined > typeof A 'function' ``` オブジェクト指向にはクラスベースとプロトタイプベースがある。クラスベースでは宣言したクラスは実体をもたない。プロトタイプベースは宣言したクラスが、実態のあるオブジェクトをプロトタイプとして次のオブジェクトが継承される。コンストラクタ関数が、このプロトタイプを元に新しいインスタンスを返す関数なので、クラス A はタイプが関数となる。 上記のクラス宣言は以下の記述と同義。 (class 構文は以下のような書き方が面倒だから省略して書ける記法って感じ、こういうの *シンタックスシュガー* って言うらしい) ```js function A(name) { this.name = name; return this; } ``` プロトタイプベースだと後からクラスにメンバ変数、メソッド増やしたりできる。 ```js > class A { constructor(name){ this.name = name; } } undefined > let instanceA = new A('instanceA'); // ← この時点では methodA という関数は定義されていない undefined > A.prototype.methodA = function() {console.log(`I am ${this.name}`)}; // ← 関数 A が生成するプロトタイプに methodA を追加 [Function (anonymous)] > instanceA.methodA(); // ← instanceA の継承元プロトタイプに加えた変更が反映されている I am instanceA ``` ## オブジェクトのコピー JavaScript やっててあるあるな問題 ```js let original = {a: 1, b: 2, c: 3}; let copy = original; original.a = 100; console.log(copy); // { a: 100, b: 2, c: 3 } ``` `Object.assign()` 関数を使うと一応回避できるように見える。`Object.assign()` は第一引数のオブジェクトに、第二引数のオブジェクトのプロパティを割り当てていく関数。 ```js let original = {a: 1, b: 2, c: 3}; const copy = Object.assign({}, original); original.a = 100; console.log(copy); // { a: 1, b: 2, c: 3 } console.log(original); // { a: 100, b: 2, c: 3 } ``` スプレッド構文を使ってもできる ```js let original = { a: 1, b: 2, c: 3 }; const copy = {... original}; original.a = 100; console.log(copy) //{ a: 1, b: 2, c: 3 } ``` これでいけると思ったら悲しいことになる ```js let original = { a: 1, b: {b1: 2, b2: 3}, c: 4 }; const copy = {...original}; original.b.b1 = 200; console.log(copy); // { a: 1, b: { b1: 200, b2: 3 }, c: 4 } ``` コピーが 1 階層しかされない、こういうのシャローコピーって言うらしい 一回、`JSON.stringify()` で文字列にしてパースしなおすという荒技がある。 (ただ、これですら Date オブジェクトとかは綺麗に変更されなくて困る) ```js let original = {a: 1, b: {b1: 2, b2: 3}, c: 4}; const copy = JSON.parse(JSON.stringify(original)); original.b.b1 = 200; console.log(copy); // { a: 1, b: { b1: 2, b2: 3 }, c: 4 } ``` この辺は外部ライブラリに頼るしかない ## this 大体以下のパターンしかない ### 1. new 演算子をつけてコンストラクタ関数を呼び出した時 → 新規作成されたオブジェクト 先の話と関連があるが、new 演算子をつけるとその関数のプロトタイプオブジェクトをコピーしてオブジェクトを作って、それを関数に this として渡している 関数が this で終わってなかったら勝手に `return this` をしている ``` > const dump = function () { console.log('`this` is', this); }; > const obj = new dump(); `this` is dump {} > obj dump {} > dump.prototype dump {} ``` obj と dump.prototype は同一のオブジェクト型になっていることがわかる 前述の通り別に Class 定義してなくても new できる ### 2. メソッド内で実行された時 → その所属するオブジェクト ```js > const foo = { name: 'Foo Object', dump() { console.log(this); }, }; > foo.dump(); { name: 'Foo Object', dump: [Function: dump] } ``` dump 関数は foo 配下にいるので this すると foo オブジェクトがそのまま返ってくる ### 非 strict モード時 1・2以外の関数 → グローバルオブジェクト キングオブゴミ仕様 何もしてない時にも this は存在し続けている ```js > this <ref *1> Object [global] { global: [Circular *1], clearInterval: [Function: clearInterval], clearTimeout: [Function: clearTimeout], setInterval: [Function: setInterval], setTimeout: [Function: setTimeout] { [Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)] }, queueMicrotask: [Function: queueMicrotask], clearImmediate: [Function: clearImmediate], setImmediate: [Function: setImmediate] { [Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)] } } ``` node だと global オブジェクト、ブラウザ環境だと window オブジェクトを指す ### strict モード時 → undefined 実質 `'use strict'` って何って説明 strict モードないだと以下のような動きになる *実行環境がないのでイメージ用のサンプルコード、実際に以下のコードを実行できる環境はほとんどない* ```js > class A { constructor(name){ this.name = name; } } > A('test'); > this <ref *1> Object [global] { global: [Circular *1], clearInterval: [Function: clearInterval], clearTimeout: [Function: clearTimeout], setInterval: [Function: setInterval], … name: 'test' ``` new は実行した関数にプロトタイプをコピーしたオブジェクトを this として渡して最後に this を返してくれる処理 new つけずに実行すると、this は global オブジェクトなので、`this.name = name` は global オブジェクトに name を追加する処理になる 気づかない間に global 汚染をしちゃう そこで、今は strict モードが用意されており、こういう処理が止められる ```js > A('test'); Uncaught TypeError: Class constructor A cannot be invoked without 'new' ``` よくある this 何を指しとるんじゃ問題はみんな JS に精通していると思うので省略 ## 細かい便利記法 ### オブジェクト型の中に関数入れるやつ オブジェクトの中に関数を入れるやつ ```js const foo = { bar: 'bar', baz: function () { console.log('I am foo') } } ``` こんな感じで簡単に書ける ```js const foo = { bar: 'bar', baz() { console.log('I am foo') } } ``` ### オブジェクト内のキー名の変数展開 オブジェクト内部のキー名に [<変数>] とすることで、キー名がその変数になってくれる ```js Type ".help" for more information. > const keyName = 'bar'; > const obj1 = { foo: 256, [keyName]: 4096, baz: 'test' }; > obj1 { foo: 256, bar: 4096, baz: 'test' } ``` ### ショートハンド {<変数名>} とすることで、{"<変数名>": <値>} のオブジェクトが作れる ```js > const foo = 111; > const obj2 = { foo }; > obj2 { foo: 111 } ``` ### 分割代入 オブジェクトから、{<キー名1>, <キー名2>} = <オブジェクト変数> とすることで、そのキー名を変数として値を取り出せる ```js > const obj = { name: 'yoshiki', age: 25 }; > const { name, age } = obj; > name 'yoshiki' > age 25 ``` ### スプレッド構文 `...<オブジェクト変数>` とすることで、そのプロパティを展開する 同一オブジェクトに同じキー名があると上書きしてくれる ```js > const obj1 = { a:1, b:2, c:3, d:4 }; > const obj2 = { ...obj1, d: 99, e: 55 }; > obj2 { a: 1, b: 2, c: 3, d: 99, e: 55 } ``` 以下みたいな使い方で、id だけ抜粋した userWithoudId 変数を作ることもできる ```js > const user = { id: 1, name: 'yoshiki', email: 'yoshiki@amazon.com', age: 25 }; > const {id, ...userWithoudId} = user; > id 1 > userWithoudId; { name: 'yoshiki', email: 'yoshiki@amazon.com', age: 25 } ``` ### Nullish Coalescing ?? と書くことで、左側が `null` なら、右側が評価されるやつ ```js > a = 1; > b = null null > new_a = a ?? 'a is null'; 1 > new_b = b ?? 'b is null'; 'b is null' ``` OR 演算子でかけることもあるけど、 `null` を評価するならこっちの方がスマートにかけそう ### Optional Chaining `?.` と書くことで、オブジェクトの上位階層が null でも途中で undefined だったら例外なく処理が完了する ```js > const obj = {}; > obj.a > obj.a.b; Uncaught TypeError: Cannot read property 'b' of undefined > obj.a?.b; undefined ``` ## まとめ なんでキモがられているのかなんとなくわかった気がした いろいろ更新されて便利な記法が増えていっている、これからも頑張ってほしい TypeScript も勉強していきたい

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully