為啥我要本身完成一個new語法糖?

為啥我要本身完成一個new語法糖?

為何要本身完成一個new語法糖呢?

由於之前關於JS里的new語法糖一直是理論明白,然則並親身嘗試完成過。

直到有一天,在頭條的口試中 我聊high了,摸着本身的良知說: 我能夠完成一個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和數目不定的參數。我們一定得曉得是製造哪一個組織函數的實例吧,所以最少須要一個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 )

能夠發明human1這個實例,跟我們用new語法製造出來的是一個結果。

小小的補充修正

為了讓newFn跟new的行為表現越發類似,須要做一點點修正完美。

我們曉得,組織函數平常是不寫return的。它偷偷自動給你return一個實例對象

然則假如,我們手動return呢? 2個狀況

  • return 了一個基礎數據類型,不會返回這個簡樸數據類型, 照舊幫你return一個實例對象
  • return 了一個對象,那末就返回你這個對象。不再幫你return實例對象

所以,為了完成一樣的結果,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
    }

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,對作者也是一種勉勵。

    原文作者:Ziwei
    原文地址: https://segmentfault.com/a/1190000014452865
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞