JavaScriptエッセンス

11215 ワード

データ型


JavaScriptは弱い言語ですが、タイプがないわけではありません.JavaScriptは次の7つの異なるタイプの値を識別できます.

基本データ型

  • Boolean
  • Number
  • String
  • null
  • undefined
  • Symbol

  • Object

  • Array
  • RegExp
  • Date
  • Math
  • ...
  • typeofを使用してデータ型を判断し、オペレータは文字列を返すことができますが、返されるすべての結果が予想に合致するわけではありません.
    typeof false // "boolean"
    typeof .2 // "number"
    typeof NaN // "number"
    typeof '' // "string"
    typeof undefined // "undefined"
    typeof Symbol() // "symbol"
    
    typeof new Date() // "object"
    typeof [] // "object"
    
    typeof alert // "function"
    
    typeof null // "object"
    typeof not_defined_var // "undefined"
    

    変数#ヘンスウ#


    アプリケーションでは、変数を使用して値の名前を付けます.変数の名前はidentifiersと呼ばれます

    宣言

  • 使用キーワードvar:関数役割ドメイン
  • 使用キーワードlet:ブロックスコープ
  • 直接使用:グローバル役割ドメイン
  • var global_var = 1;
    
    function fn () {
      var fn_var = 2;
      
      if(fn_var > 10){
        let block_var = 3;
        global_var2 = 4;
      }
    }
    

    変数のデフォルト値はundefinedです.constキーワードは、同じブロック役割ドメインである可変変数を宣言することができる.不変の理解の対象への理解には注意が必要である
    const num = 1;
    const obj = {
      prop: 'value'
    };
    
    num = 2; // Uncaught TypeError: Assignment to constant variable.
    obj['prop'] = 'value2';
    
    obj = []; // Uncaught TypeError: Assignment to constant variable.
    

    変数の移動


    JavaScriptでは、後で宣言する変数を参照できますが、異を起こさない概念を変数宣言昇格(hoisting)と呼びます.
    console.log(a); // undefined
    
    var a = 2;
    

    に等しい
    var a;
    
    console.log(a);
    
    a = 2;
    

    関数#カンスウ#


    1つの関数は、外部コードによって呼び出される(または関数自体が再帰的に呼び出される) である.

    関数の定義

  • 関数宣言
  • 関数式
  • Functionコンストラクタ
  • 矢印関数
  • function fn(){}
    
    var fn = function(){}
    
    var fn = new Function(arg1, arg2, ... argN, funcBody)
    
    var fn = (param) => {}
    

    arguments

  • arguments:現在の実行関数に渡すパラメータを含む配列に類似するオブジェクト
  • arguments.length:関数に渡されるパラメータの数
  • arguments.caller:現在の実行関数を呼び出す関数
  • arguments.callee:現在実行中の関数
  • function foo() {
      return arguments;
    }
    foo(1, 2, 3); // Arguments[3] 
    // { "0": 1, "1": 2, "2": 3 }
    

    rest

    function foo(...args) {
      return args;
    }
    foo(1, 2, 3); // Array[3]
    // [1, 2, 3]
    
    function fn(a, b, ...args){
      return args;
    }
    
    fn(1, 2, 3, 4, 5); // Array[3]  
    // [3, 4, 5]
    

    default


    関数のパラメータは、定義時にデフォルト値を約定できます.
    function fn (a = 2, b = 3) {
      return a + b;
    }
    
    
    fn(2, 3); // 5
    
    fn(2); // 5
    
    fn(); // 5
    

    オブジェクト


    JavaScriptのオブジェクトは可変 (keyed collections)です.

    オブジェクトの定義

  • 字面量
  • 構造関数
  • var obj = {
      prop: 'value',
      fn: function(){}
    };
    
    var date = new Date();
    

    コンストラクタ


    コンストラクション関数と通常の関数には違いはありません.newのキーワード呼び出しを使用するとコンストラクション関数になり、コンストラクション関数を使用するとオブジェクトをインスタンス化できます.
    関数の戻り値には2つの可能性があります.
  • 明示的な呼び出しreturnは、returnの後式の評価
  • を返す.
  • 呼び出していないreturnundefinedを返し、
  • を返す.
    function People(name, age) {
      this.name = name;
      this.age = age;
    }
    
    var people = new People('Byron', 26);
    

    コンストラクション関数の戻り値
  • 戻り値
  • なし
  • 単純データ型
  • オブジェクトタイプ
  • 最初の2つのケースコンストラクション関数は、コンストラクションオブジェクトのインスタンスを返します.インスタンス化オブジェクトは、この特性を利用しています.
    第3の構造関数は通常の関数と一致し,return後の式の結果を返す

    prototype

  • 各関数にはprototypeのオブジェクト属性があり、オブジェクト内にはconstructorの属性があり、デフォルトでは関数自体
  • を指す.
  • 各オブジェクトには、親タイプの__proto__
  • に属するprototypeのプロパティがあります.
    function Person(name) {
      this.name = name;
    }
    
    Person.prototype.print = function () {
      console.log(this.name);
    };
    
    var p1 = new Person('Byron');
    var p2 = new Person('Casper');
    
    p1.print();
    p2.print();
    

    thisと役割ドメイン


    役割ドメインは通俗的に理解できる
  • 私は誰ですか
  • 私はどれらの馬の子があります
  • その中で私が誰だかの答えはthisです.
    馬仔は私の局所変数です

    このシーン


    一般関数
  • 厳格モード:undefined
  • 非厳格モード:グローバルオブジェクト
  • Node: global
  • ブラウザ:window

  • コンストラクタコンストラクタ:オブジェクトのインスタンスおぶじぇくとのれい
    ≪オブジェクト・メソッド|Object Method|oem_src≫:オブジェクト自体

    call & apply

  • fn.call(context, arg1, arg2, …, argn)
  • fn.apply(context, args)
  • function isNumber(obj) {
      return Object.prototype.toString.call(obj) === '[object Number]';
    }
    

    Function.prototype.bind

    bindは、bindパラメータの役割ドメインを持つ新しい関数を返します.
    function fn() {
      this.i = 0;
    
      setInterval(function () {
        console.log(this.i++);
      }.bind(this), 500)
    }
    
    fn();
    

    () => {}


    矢印関数はES 6が提供する新しい特性であり、簡潔な関数式であり、文法的役割ドメインとthis値を有する.
    function fn() {
      this.i = 0;
    
      setInterval(() => {
        console.log(this.i++);
      }, 500)
    }
    
    fn();
    

    継承


    JavaScriptのシーンでは、2つのターゲットが継承されます.子は親を取得する必要があります.
  • オブジェクトのプロパティ
  • オブジェクトのメソッド
  • function inherits(child, parent) {
      var _proptotype = Object.create(parent.prototype);
      _proptotype.constructor = child.prototype.constructor;
      child.prototype = _proptotype;
    }
    
    function People(name, age) {
      this.name = name;
      this.age = age;
    }
    
    People.prototype.getName = function () {
      return this.name;
    }
    
    function English(name, age, language) {
      People.call(this, name, age);
      this.language = language;
    }
    
    inherits(English, People);
    
    English.prototype.introduce = function () {
      console.log('Hi, I am ' + this.getName());
      console.log('I speak ' + this.language);
    }
    
    function Chinese(name, age, language) {
      People.call(this, name, age);
      this.language = language;
    }
    
    inherits(Chinese, People);
    
    Chinese.prototype.introduce = function () {
      console.log('  ,  ' + this.getName());
      console.log('  ' + this.language);
    }
    
    var en = new English('Byron', 26, 'English');
    var cn = new Chinese('   ', 27, '  ');
    
    en.introduce();
    cn.introduce();
    

    ES 6 classと継承

    "use strict";
    
    class People{
      constructor(name, age){
        this.name = name;
        this.age = age;
      }
    
      getName(){
        return this.name;
      }
    }
    
    class English extends People{
      constructor(name, age, language){
        super(name, age);
        this.language = language;
      }
    
      introduce(){
        console.log('Hi, I am ' + this.getName());
        console.log('I speak ' + this.language);
      }
    }
    
    let en = new English('Byron', 26, 'English');
    
    en.introduce();
    

    構文


    label statement

    loop:
        for (var i = 0; i < 10; i++) {
          for (var j = 0; j < 5; j++) {
            console.log(j);
            if (j === 1) {
              break loop;
            }
          }
        }
    
    console.log(i);
    

    文と式

    var x = { a:1 };
    
    { a:1 }
    
    { a:1, b:2 }
    

    即時実行関数

    ( function() {}() );
    ( function() {} )();
    [ function() {}() ];
    
    ~ function() {}();
    ! function() {}();
    + function() {}();
    - function() {}();
    
    delete function() {}();
    typeof function() {}();
    void function() {}();
    new function() {}();
    new function() {};
    
    var f = function() {}();
    
    1, function() {}();
    1 ^ function() {}();
    1 > function() {}();
    

    高次関数


    高次関数は、関数をパラメータとするか、戻り値を関数とする関数です.

    コールバック関数

    [1, 2, 3, 4].forEach(function(item){
      console.log(item);
    });
    

    クローズドパッケージ


    クローズドパッケージは2つの部分から構成されています
  • 関数
  • 環境:関数作成時の役割ドメイン内のローカル変数
  • function makeCounter(init) {
      var init = init || 0;
    
      return function(){
        return ++init;
      }
    }
    
    var counter = makeCounter(10);
    
    console.log(counter());
    console.log(counter());
    

    典型的なエラー

    for (var i = 0; i < doms.length; i++) {
      doms.eq(i).on('click', function (ev) {
        console.log(i);
      });
    }
    

    for (var i = 0; i < doms.length; i++) {
      (function (i) {
        doms.eq(i).on('click', function (ev) {
          console.log(i);
        });
      })(i);
    }
    

    ふかっせいかんすう

    function eventBinderGenerator() {
      if (window.addEventListener) {
        return function (element, type, handler) {
          element.addEventListener(type, hanlder, false);
        }
      } else {
        return function (element, type, handler) {
          element.attachEvent('on' + type, handler.bind(element, window.event));
        }
      }
    }
    
    var addEvent = eventBinderGenerator();
    

    コリー化


    部分パラメータを使用して関数を生成できる方法
    function isType(type) {
      return function(obj){
        return Object.prototype.toString.call(obj) === '[object '+ type +']';
      }
    }
    
    var isNumber = isType('Number');
    
    console.log(isNumber(1));
    console.log(isNumber('s'));
    
    var isArray = isType('Array');
    
    console.log(isArray(1));
    console.log(isArray([1, 2, 3]));
    
    function f(n) {
      return n * n;
    }
    
    function g(n) {
      return n * 2;
    }
    
    console.log(f(g(5)));
    
    function pipe(f, g) {
      return function () {
        return f.call(null, g.apply(null, arguments));
      }
    }
    
    var fn = pipe(f, g);
    
    console.log(fn(5));
    

    テール再帰

  • の最後の呼び出しは、ある関数の最後のステップが別の関数
  • を呼び出すことを意味する.
  • 関数呼び出し自体を再帰
  • と呼ぶ.
  • テールコール自体をテール再帰
  • と呼ぶ.
    再帰的に「スタックオーバーフロー」エラーが発生しやすい(stack overflow)
    function factorial(n) {
      if (n === 1) return 1;
      return n * factorial(n - 1);
    }
    
    factorial(5) // 120
    

    ただし、最後の再帰的には、呼び出しレコードが1つしか存在しないため、スタックオーバーフローエラーは発生しません.
    function factorial(n, total) {
      if (n === 1) return total;
      return factorial(n - 1, n * total);
    }
    
    factorial(5, 1) // 120
    

    コリー減少パラメータ
    function currying(fn, n) {
      return function (m) {
        return fn.call(this, m, n);
      };
    }
    
    function tailFactorial(n, total) {
      if (n === 1) return total;
      return tailFactorial(n - 1, n * total);
    }
    
    const factorial = currying(tailFactorial, 1);
    
    factorial(5) // 120
    

    アンチコリー化

    Function.prototype.uncurry = function () {
      return this.call.bind(this);
    };
    

    Push汎用化
    var push = Array.prototype.push.uncurry();
    
    var arr = [];
    
    push(arr, 1);
    push(arr, 2);
    push(arr, 3);
    
    console.log(arr);