日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

new操作符到底干了什么?

發布時間:2025/3/20 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 new操作符到底干了什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前幾天無意間發現了剛開始學JavaScript時在知乎寫的一些回答,有一個就是講new操作符到底干了什么。從現在的視角看我當時的回答雖然是正確的,但是在對原理的剖析和細節的理解上還相去甚遠。所以借此機會,就想重新梳理一下這一年多來對new操作符理解的變化與成長。

模擬new操作符

第一次去了解new操作符,是在看《JS高級程序設計(第三版)》這本書時,P145是這樣寫到的。

要創建Person的新實例,必須使用new操作符。以這種方式調用構造函數實際上會經歷以下4個步驟:

  • 創建一個新對象;
  • 將構造函數的作用域賦給新對象(因此this就指向了這個新對象);
  • 執行構造函數中的代碼(為這個新對象添加屬性);
  • 返回新對象;
  • 盡管書中是這樣描述,但是并沒有給出實踐的代碼,所以我就按照這個步驟自己去實踐模擬一個new操作符。代碼如下:

    var mockNew = function (constructor) {var o = {} // 創建一個新對象constructor.apply(o, Array.prototype.slice.call(arguments, 1)) // 賦作用域 執行代碼return o // 返回新對象 } 復制代碼

    然后我們用這個模擬new操作符的函數來創造一個對象試試。

    var Person = function (name, age) {this.name = namethis.age = age }Person.prototype.sayName = function () {console.log(this.name) }var person1 = mockNew(Person, 'MeloGuo', 22)console.log(person1.name) // 'MeloGuo' console.log(person1.age) // 22 person1.sayName() // Uncaught TypeError: person1.sayName is not a function 復制代碼

    看起來我的模擬函數雖然能訪問實例中的屬性,但是卻不能訪問sayName方法,而且當我使用instanceof操作符檢測時卻得到了這樣的結果。

    console.log(person1 instanceof Person) // false console.log(person1 instanceof Object) // true 復制代碼

    改進的模擬函數

    可見person1并不是Person的實例。當時的我還不知道問題出在哪里,直到學習到原型鏈時我才直到mockNew函數缺少了一個步驟,即綁定構造函數原型。所以person1實例是無法訪問到Person原型中的sayName方法,同時instanceof操作符的結果也為false。因為instanceof操作符是用來檢測一個對象在其原型鏈中是否存在一個構造函數的prototype屬性的,而person1的原型鏈中并不存在Person.prototype,所以返回值為false。因此,我們改造mockNew函數如下:

    var mockNew = function (constructor) {var o = {}o.__proto__ = constructor.prototype // 綁定構造函數原型,但是生產代碼中千萬別用.__proto__constructor.apply(o, Array.prototype.slice.call(arguments, 1))return o } 復制代碼

    這時我們再創建實例,然后使用instanceof操作符檢測一下,同時調用下sayName方法。

    var person1 = mockNew(Person, 'MeloGuo', 22)console.log(person1 instanceof Person) // true console.log(person1 instanceof Object) // true person1.sayName() // 'MeloGuo' 復制代碼

    這時看似mockNew函數已經完全模擬了new操作符了,但是當我們嘗試下面這種情況時,又出現了問題。

    function Person (name) {this.name = namereturn { age: 22 } }var person1 = new Person('MeloGuo') var person2 = mockNew(Person, 'MeloGuo')console.log(person1) // {age: 22} console.log(person2) // Person {name: "MeloGuo"} console.log(person1 instanceof Person) // false console.log(person2 instanceof Person) // true 復制代碼

    什么!!!用new操作符調用的Person構造函數并沒有按照預期返回帶有name屬性并且在Person.prototype上的對象,而是返回了我們手動return的帶有age屬性的對象,但是我們的mockNew函數是正常返回了。所以我們的mockNew函數中肯定又丟失了一些細節,為了弄清楚,只好硬著頭皮去讀ECMA-262規范了。看到規范中的steps后才恍然大悟了new操作符的整個執行流程。

    完善模擬函數

    簡單來說我們在返回對象前缺失了判斷返回值類型的步驟。

    • 如果構造函數的返回值是值類型,那么就丟棄掉,依然返回構造函數創建的實例。
    • 如果構造函數的返回值是引用類型,那么就返回這個引用類型,丟棄構造函數創建的實例。

    注:如果沒有顯示return,那么相當于隱式返回了undefined,則丟棄它。

    吸取了規范中的內容,并且加入ES6語法后,我們新的mockNew函數如下:

    function mockNew (constructor, ...args) {const isPrimitive = result => {// 如果result為值類型則返回true// 如果result為引用類型則返回false }const o = Object.create(constructor.prototype)const result = constructor.apply(o, args)return isPrimitive(result) ? o : result } 復制代碼

    這時的mockNew函數可以說是較好的模擬了new操作符的功能。

    總結

    其實new操作符就是一個語法糖。在傳統的面向類的語言中,“構造函數”是類中的一些特殊方法,使用new初始化類時會調用類中的構造函數。而JavaScript中的new其實是用來告訴函數,我要以“構造”的方式調用你了,從而向mockNew函數中的流程一樣,得到我們的實例。所以本質上來說JS是沒有所謂構造函數的,有的應該是構造調用。這樣的稱呼能讓我們更清楚認識JS中的new操作符。

    轉載于:https://juejin.im/post/5b4af862e51d4519984118d1

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的new操作符到底干了什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产视频精品一区二区三区 | 日本美女毛片 | 第五色婷婷 | 精品国产免费无码久久久 | 久久av一区二区三 | 香蕉视频网页 | 国产精品情侣自拍 | 久久久黄色片 | 丁香激情五月少妇 | 国产精品久久一区二区三区动 | 男人的天堂亚洲 | 日韩人妻一区二区三区蜜桃视频 | 一区二区在线国产 | 亚洲一二三四区 | 搞黄网站在线观看 | 久久久久久久黄色片 | 久久麻豆视频 | 99精品福利视频 | 色哟哟精品观看 | 欧美日韩另类在线 | 97视频总站| 一二三区精品视频 | 精品日韩| 毛片链接| 天天躁夜夜躁狠狠躁 | 大尺度做爰呻吟舌吻网站 | 欧美日韩在线影院 | 夜夜艹 | 麻豆视频二区 | 国产精品99精品无码视亚 | 欧美成人综合视频 | 成人黄色网址在线观看 | 国产乱人乱偷精品视频a人人澡 | 国产黄色网页 | 在线观看国产日韩 | 欧美一区精品 | 亚洲经典自拍 | 精品久久久久久久久久久 | 青青草成人影视 | 亚洲男人天堂2017 | 国产香蕉一区 | 亚洲一区二区蜜桃 | 全黄一级播放 | 九色视频网站 | 情侣在线视频 | 日本免费在线观看 | 日韩欧美三级在线 | 黄色录像a级片 | 国产av一区二区三区 | 黄色av不卡 | 用我的手指扰乱你 | 亚洲天堂v | 我要看一级黄色片 | 凸凹人妻人人澡人人添 | 日韩午夜精品视频 | 亚洲一区二区三区高清在线 | 曰批女人视频在线观看 | 先锋影音色 | 欧美重口另类 | 日本黄色三级网站 | 亚洲搞av | 亚洲第六页 | 青草视频在线看 | 有码一区二区 | 日韩欧美在线精品 | 操极品少妇 | 性色视频在线观看 | 91九色中文 | 神马三级我不卡 | 一级国产特黄bbbbb | 日韩在线一级片 | 免费观看久久久 | 精品少妇白浆小泬60P | 午夜天堂精品久久久久 | 韩国伦理电影免费在线 | 国产一区二区三区四区五区在线 | 床戏高潮做进去大尺度视频网站 | 亚洲国产激情 | 麻豆短视频在线观看 | 精品一区91 | 欧美香蕉 | 日本熟妇毛茸茸丰满 | 日本不卡一区二区三区视频 | 伊人伊网 | 麻豆一区产品精品蜜桃的特点 | 免费观看一区二区三区视频 | 在线爱情大片免费观看大全 | 三上悠亚久久精品 | 国产一区二区久久久 | 久久99在线 | 全黄一级播放 | 免费婷婷| 日日干夜夜爽 | 国产成人三级一区二区在线观看一 | 国产成人精品无码高潮 | 波多野吉衣视频在线观看 | 国产女人18毛片水真多1 | 天天爽夜夜春 | 制服丝袜av电影 |