JS 101 :「新しい」キーワードの実装


JavaScriptのクラスの本当の概念がないので、これらの古典的なキーワードのいくつかは本当にフードの下でやっているかを理解するのに役立ちます.
JavaScriptで“new”キーワードの簡易版を作成します.たとえば、新しいキーワードを使用して、オブジェクトをインスタンス化します.
const dog = new Dog()
しかし、次のようにします.
const sparky = newObject(Dog, 'Sparky', 3)
const spot = newObject(Dog, 'Spot', 6)

どのような“新しい”キーワードは
“new”キーワードを理解するには、コンストラクタ関数を理解することが重要です.JSのコンストラクタ関数は、初期化に責任がある通常のOLE関数です.例えば、
// the upper case function name is just a standard practice, not necessarily required
function Dog(petName, age) {
   this.petName = petName
   this.age = age
}
それで、ここでは、「新しい」キーワードが背景にあるステップです:
  • 空のオブジェクトを作成する
  • 空のオブジェクトのプロトタイプをコンストラクタ関数のプロトタイプに割り当てます
  • 新しいオブジェクトの"this "コンテキストを使用してコンストラクタ関数を実行します
  • コンストラクタがオブジェクトを返す場合は
  • 関数を定義することから始めましょうnewObject これは新しいキーワードに置き換えられます.
    /* 
       We will need the constructor function, and all of the constructor
       parameters. Using the handy spread operator here.
    */
    function newObject(constructor, ...params) {
     // we will fill this out in the following steps
    }
    

    ステップ1 :空のオブジェクトを作成する
    十分簡単.そうしましょう
    function newObject(constructor, ...params) {
     function d() {}
    }
    

    ステップ2 :空のオブジェクトのプロトタイプをコンストラクタ関数のプロトタイプに割り当てます
    少しトリッキーだけどObject 便利な関数setPrototypeOf . を使いましょう.
    function newObject(constructor, ...params) {
     function d() {}
     Object.setPrototypeOf(d, constructor.prototype)
    }
    
    これほど悪くない!

    ステップ3 :新しいオブジェクトの"この"コンテキストを使用してコンストラクタ関数を実行します
    Alright、これはおそらく新しいJavaScriptプログラマのための最も複雑な部分です.すべてのオブジェクトが呼ばれる関数がありますcall and apply . 彼らは特定の機能を実行するthis この関数のパラメータは渡されるものです.例えば、
    function Dog(petName) {
    
       this.petName = petName
    }
    
    /* 
       we pass "this", so the "this" in "this.petName" refers to the one 
       we passed in.  
    */
    Dog.call(this, 'Harold')
    
    /* 
       if we want to pass an array of parameters, we can use the multi- 
       parameter equivalent of the "call" function.
    */
    Dog.apply(this, ['Harold', 'James', 'Clark'])
    
    さて、今私たちはcall / apply , どちらがステップナンバー3を処理するために使用すると思いますか?コンストラクタ関数は任意の数のパラメータを持つことができます.
    レディ?はい、
    function newObject(constructor, ...params) {
     function d() {}
     Object.setPrototypeOf(d, constructor.prototype)
    // apply expects an array-like second parameter, which is why
    // we spread it in an array
     constructor.apply(d, [...params])
    }
    

    Step 4 :コンストラクタがオブジェクトを返す場合は、それを返します
    仕上げるnewObject 関数は、コンストラクタ関数がオブジェクトを返すかどうかを調べるために、迅速な条件付きチェックを追加します.
    function newObject(constructor, ...params) {
     function d() {}
     Object.setPrototypeOf(d, constructor.prototype)
     const obj = constructor.apply(d, [...params])
     if(typeof obj === 'object') return obj
     return d
    }
    
    注意null は技術的にオブジェクトなので、コンストラクタがNULLを返すと、インスタンス化関数で返されます.

    ステップ5:利益
    一緒にすべてを入れて、我々の機能を旋回させましょう!
    // our fancy new function
    function newObject(constructor, ...params) {
        function d() {}
      Object.setPrototypeOf(d, constructor.prototype)
      const obj = constructor.apply(d, [...params])
      if(typeof obj === 'object') return obj
      return d
    }
    
    // an example constructor function
    function Dog(petName, age) {
       this.petName = petName
       this.age = age
       this.bark = function() {
          console.log(`${this.petName} is ${this.age} years old`)
       }
    }
    
    const bill = newObject(Dog, 'Bill', 8)
    const sam = newObject(Dog, 'Sam', 2)
    
    dog.bark() // prints: Bill is 8 years old
    dog2.bark() // prints: Sam is 2 years old
    

    結論
    私たちは、新しいキーワードがどのように機能するかを見てきました.私たちは、私たちがしなければならないことがどれほど便利かを理解することができますconst dog = new Dog() 同じ結果を得るには

    楽しい事実!
    The new キーワードは、あなたがタイプするかどうかに関係なく与えられた機能を走らせますnew Dog() or new Dog , ですから、技術的には前者を行う必要はありません.しかし、皆さんの正気のためには、前者のオプションを使うだけでよいでしょう.