どうして私は自分でnew文法糖を実現しますか?

4649 ワード

どうして私は自分でnew文法糖を実現しますか?


どうして自分でnew文法糖を実現するのですか?
以前はJSのnew文法糖について理論的に理解していたが、自ら試みたことがあるからだ.
ある日、トップ記事の面接で盛り上がり、自分の良心に触れて「new文法糖を実現できる」と言った.
面接官:うん、じゃあ、一つ実現してください.
私:…他に何か話しましょうか.

手順1:newが何をしたかを観察します。


まずnewを勝手に使って、それから観察して、脳補して、想像して、最後にnewが何かをしたかもしれないと推測します!
    function Human(){
        this.type = 'human'
        this.age = 18
    }

    var human1 = new Human()
    console.log(h1)  // {type:'human',age:18}

指折り数えてみると、とりあえずどうしても、直感的にnewはこんなことをしたのだろう.
  • 空のオブジェクトを作成する
  • 空のオブジェクトの_proto__コンストラクション関数のprototypeを指し、thisはこのオブジェクト
  • を指す.
  • こっそりreturnこのオブジェクト
  • function Human(){
                // var obj = {}                                 
                // obj.__proto__ = Human.prototype           __proto__       prototype
                // this = obj                           obj   this
                this.type = 'human'
                this.age = 18
    
                // return this                              return    
            }
    
            var human1 = new Human()
            console.log(h1)  // {type:'human',age:18}
    

    手順2:インタフェースを設計する


    インタフェース向けのプログラミングですか.プログラムを設計して、最後にどんな形式で呼び出すか考えてみましょう.結局私達はJSの父ではありませんて、本当に文法を創造することができません.
    インスタンスオブジェクトを作成するために使用できる関数newFn()をカプセル化し、最終的には次のように使用します.
    次は擬似コードです
     function Human(){
            this.type = 'human'
            this.age = 18
        }
    
     // var human1 = new Human()       new ,   newFn()     
     
     function newFn(){
        ...      
     }
     
     var human1 = newFn(Human)   
    

    ステップ3:newFn()の実装


    ではnewFn()の入力と出力は何でしょうか.
  • パラメータ:Constructorと数不定のパラメータ.どのコンストラクション関数のインスタンスを作成するかを知る必要があるでしょう.そのため、少なくとも1つのConstructorが必要です.また、いくつかのパラメータ
  • をカスタマイズすることもできます.
  • は、obj、すなわち構造関数のインスタンス
  • を返す.
          function newFn() {
                const obj = {};
                const Constructor = [].shift.call(arguments)            //   arguments        Constructor ,    arguments     ,         
                obj.__proto__ = Constructor.prototype;                  //    obj    Constructor       
                Constructor.apply( obj, arguments )                     //    obj    Constructor    ,   obj  type   age
    
                return obj                                              //     
            }
            
            
          : shift()                   ,          。
    

    Example:newFnを使用してインスタンスを作成します(ブラウザのテスト用に入手できます)
    
            function newFn() {
                const obj = {};
                const Constructor = [].shift.call(arguments)
                obj.__proto__ = Constructor.prototype;
                Constructor.apply( obj, arguments )
                return obj
            }
    
    
            function Human() {
                this.type = 'human'
                this.age = 18
            }
    
            var human1 = newFn( Human )
    
            console.log( human1 )
    

    human 1という例は,new文法で作成したものと同じ効果であることが分かった.

    小さな補足修正


    newFnとnewの行動がより似ているように、少し修正して改善する必要があります.
    構造関数は一般的にreturnを書かないことを知っています.インスタンスオブジェクトを自動的にreturnします
    しかし、もし私たちが手動でreturnしたら?2つのケース
  • returnは、この単純なデータ型を返すことなく、インスタンスオブジェクト
  • をreturnします.
  • returnはオブジェクトを返します.それでは、このオブジェクトを返します.returnインスタンスオブジェクト
  • はもう手伝いません
    だから、同じ効果を実現するために、newFnは1行のコードを修正します.
    
        function newFn() {
            const obj = {};
            const Constructor = [].shift.call(arguments)
            obj.__proto__ = Constructor.prototype;
            const result = Constructor.apply( obj, arguments ) //             ,    return   ,    return    
    
            return typeof result === 'object' ? result : obj
        }
    
    

    Example:完全なnewFnを使用してインスタンスを作成します(ブラウザテスト用に入手できます)
            function newFn() {
                const obj = {};
                const Constructor = [].shift.call( arguments )
                obj.__proto__ = Constructor.prototype;
                const result = Constructor.apply( obj, arguments ) //             ,    return   ,    return    
    
                return typeof result === 'object' ? result : obj
            }
    
    
            function Human( name, age ) {
                this.type = 'human'
                this.age = 18
                return {
                    name: name,
                    age: age
                }
            }
    
            var human1 = newFn( Human, 'ziwei', '24' )
    
            console.log( human1 )
    
    

    詳細については、https://github.com/ziwei3749/...に参照してください.
    疑問や誤りが発見された場合は、対応するissuesで質問や誤り訂正を行うことができます.
    好きだったりヒントがあったりしたら、starを歓迎して、作者にも励ましです.