整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript命名沖突不可避免?


          【CSDN 編者按】從1995年開始,本文作者Dr.Axel Rauschmayer就專門從事JavaScript和Web開發,已經有30多年了。2010年,他獲得慕尼黑大學信息學博士學位。自2011年以來,他一直在2ality.com寫博客,并寫了幾本關于JavaScript的書,比如《JavaScript for impatient programmers》、《Deep JavaScript: Theory and techniques》等。今天這篇文章就來自于他的博客,介紹了在JavaScript命名沖突時,現有代碼如何強制對提議的功能進行重命名。

          整理 | 章雨銘 責編 | 張紅月
          出品 | CSDN(ID:CSDNnews)

          不斷發展的JavaScript:不要破壞web!


          JavaScript的一個發展核心原則就是"不要破壞Web":在將新特性添加到語言中后,所有現有代碼都必須能夠繼續運行。

          這樣有一個壞處,就是不能從語言中刪除現有的quirks。但這樣做益處多多,比如舊的代碼可以繼續運行,而且升級到新的ECMAScript版本很簡便等等。

          在為新特征(如方法名稱)選擇名稱時,需要進行一個重要的測試,即在瀏覽器的nightly版本(早期預發布版本)中添加該特征,并檢查是否有任何網站出現錯誤。

          接下來將介紹過去案例中的的四個沖突源,當產生這四種沖突時,就必須重命名特征。


          沖突源1:向內置原型添加方法


          在JavaScript中,我們可以通過改變其原型來為內置值添加方法:

          • // Creating a new Array methodArray.prototype.myArrayMethod = function () { return this.join('-');};assert.equal( ['a', 'b', 'c'].myArrayMethod(), 'a-b-c');

            // Creating a new string methodString.prototype.myStringMethod = function () { return '?' + this + '!';};assert.equal( 'Hola'.myStringMethod(), '?Hola!');

            神奇的是,語言可以通過這種方式改變。這種運行時的修改被稱為猴子補丁(monkey patch)。

            什么是猴子補丁?

            如果我們給內置原型添加方法,我們就是在運行時修改一個軟件系統。這樣的修改被稱為猴子補丁。簡單來說,對其含義有兩種可能的解釋。

            這個叫法起源于Zope框架,人們在修正Zope的Bug的時候經常在程序后面追加更新部分,這些被稱作是“雜牌軍補丁(guerilla patch)”,后來guerilla就漸漸的寫成了gorllia((猩猩),再后來就寫了monkey(猴子),所以猴子補丁的叫法是這么莫名其妙的得來的。

            另一種說法是,它指的是搞亂(monkeying about)代碼。

            反對改變內置原型的原因

            對任何類型的全局命名,都會存在名稱沖突的風險。如果有解決沖突的機制,就能規避風險。例如:

            • 全局模塊是通過裸模塊指定器或URLs來識別的。前者之間的名稱沖突可以通過npm注冊表來解決。后者之間的名稱沖突可以通過域名注冊處來解決。

            • 可以通過將符號添加到JavaScript中,以避免方法之間的名稱沖突。例如,任何對象都可以通過添加一個鍵為.NET的方法而成為可迭代的。由于每個符號都是唯一的,所以這個鍵永遠不會與任何其他屬性鍵.Symbol.iterator發生沖突。

            然而,帶有字符串鍵的方法會導致名稱沖突:

            • 不同的庫可能會對他們添加到.Array.prototype的方法使用相同的名字。

            • 如果一個名字已經被某個庫使用了,那么這個名稱就不能用于命名JavaScript標準庫的一個新特性。

            具有諷刺意味的是,謹慎地添加一個方法可能會適得其反:

            • if (!Array.prototype.libraryMethod) { Array.prototype.libraryMethod = function () { /*...*/ };}

              我們會檢查一個方法是否已經存在。如果沒有,我們就添加它。

              如果我們要實現一個polyfill(模擬原生Web平臺功能),將新的JavaScript方法添加到不支持它的引擎中,那么這個技術就能發揮作用。(順便說一下,這是修改內置原型的一個合法用例。也許是唯一的一個)。

              然而,如果我們對一個普通庫的方法使用這種技術,然后JavaScript獲取具有相同名稱的方法,那么這兩種實現的工作方式就不一樣了,并且使用庫方法的所有代碼在使用內置方法時都會中斷。

              必須更改名稱的原型方法示例

              • ES6的方法最初是與JavaScript框架MooTools(錯誤報告.String.prototype.includes().contains()全局添加的方法相沖突。

              • ES2016的方法最初是與MooTools(錯誤報告 ).Array.prototype.includes().contains()添加的方法相沖突。

              • ES2019的方法最初是和MooTools(錯誤報告 博客文章).Array.prototype.flat().flatten()相沖突。

              修改內置原型并不總是糟糕的

              你可能會對MooTools的創建者粗心大意感到疑惑。但是,向內置原型添加方法并不總是糟糕的。在ES3(1999年12月)和ES5(2009年12月)之間,JavaScript是一種停滯不前的語言。MooTools和Prototype等框架改進了它。這些方法的缺點只有在JavaScript的標準庫再次增加之后才會凸顯出來。


              沖突源2:檢查一個屬性的存在

              ES2022的方法最初是.NET的。因為以下庫檢查屬性以確定對象是否是一個HTML集合(而不是一個數組),所以它必須被重新命名:Magic360YUI 2YUI 3.Array.prototype.at().item().item

              沖突源3:檢查全局變量是否存在

              自ES2020以來,我們可以通過globalThis訪問全局對象。Node.js一直使用該名稱來實現此目的。最初的計劃是為所有平臺標準化該名稱.global

              然而,以下模式經常被用來確定當前平臺:

              • if (typeof global !== 'undefined') { // We are not running on Node.js}

                如果瀏覽器也有一個名為.global的全局變量,這種模式(以及類似的模式)就會失效。因此,標準化的名稱被改為.globalglobalThis



                沖突源4:通過創建局部變量with語句
                JavaScript的聲明with語句

                長期以來,人們一直不鼓勵使用JavaScript的with語句,甚至在ES5中引入的嚴格模式中也被定為非法。在其他地方,嚴格模式在ECMAScript模塊中是活躍的。

                該語句將一個對象的屬性變成局部變量:with

                • cons t myObject = { ownProperty: 'yes',};

                  with (myObject) { // Own properties become local variables assert.equal( ownProperty, 'yes' );

                  // Inherited properties become local variables, too assert.equal( typeof toString, 'function' );}

                  由with語句引起的沖突

                  框架Ext.js使用的代碼與下面的片段有些相似點:

                  • function myFunc(values) { with (values) { console.log(values); // (A) }}myFunc([]); // (B)

                    當ES6方法被添加到JavaScript中時,如果用Array(B行)來調用它,它就會失效。該語句將Array的所有屬性變成了局部變量。其中一個是繼承的屬性。因此,A行中的語句已記錄,不再是參數(錯誤報告1錯誤報告2

                    Array.prototype.values()myFunc()withvalues.valuesArray.prototype.valuesvalue


                    Unscopables:防止with導致的沖突

                    公共符號Symbol.unscopables允許對象隱藏語句中的某些屬性。它只在標準庫中使用一次,對于Array.prototype:with

                    • assert.deepEqual( Array.prototype[Symbol.unscopables], { __proto__: , at: true, copyWithin: true, entries: true, fill: true, find: true, findIndex: true, flat: true, flatMap: true, includes: true, keys: true, values: true, });


                      結論

                      以上提出了JavaScript結構與現有代碼發生名稱沖突的四種方式:

                      • 向內置原型添加方法

                      • 檢查屬性是否存在

                      • 檢查全局變量是否存在

                      • 創建局部變量with

                      沖突的某些來源很難預測,但存在以下一些一般規則:

                      • 不要更改全局數據。

                      • 避免檢查是否存在全局數據。

                      • 請注意,內置值將來可能會獲得其他屬性(自己的或繼承的屬性)。

                      對于庫來說,為JavaScript值提供功能的最安全方法是通過函數。如果JavaScript得到一個pipe operator,我們也可以像方法一樣使用它們。

                      參考資料:https://2ality.com/2022/03/naming-conflicts.html

                      END

                      《新程序員001-004》全面上市,對話世界級大師,報道中國IT行業創新創造

          簽屬性命名規范

          下劃線連接符命名法“hello_world”

          中杠 連接符命名法“hello-world”

          駱駝式命名法“helloWorld”


            內容:content/container 導航:nav 側欄:sidebar    
            欄目:column 標志:logo 頁面主體:main   
            廣告:banner 熱點:hot 新聞:news
            下載:download 子導航:subnav 菜單:menu
            搜索:search 頁腳:footer 滾動:scroll
            版權:copyright 友情鏈接:friendlink 子菜單:submenu
            內容:content 標簽頁:tab 文章列表:list
            注冊:regsiter 提示信息:msg 小技巧:tips
            加入:joinus 欄目標題:title 指南:guild
            服務:service 狀態:status 投票:vote
             尾:footer 合作伙伴:partner 登錄條:loginbar
            頁面外圍控制整體布局寬度:wrapper 左右中:left right center   
            
            
          (二)注釋的寫法:
            /* Footer */
            內容區
            /* End Footer */
            
            
          (三)id(具有唯一性)的命名:
            
            
          (1)頁面結構
            容器: container 頁頭:header 內容:content/container
            頁面主體:main 頁尾:footer 導航:nav
            側欄:sidebar 欄目:column 左右中:left right center
            頁面外圍控制整體布局寬度:wrapper
            
          (2)導航
            導航:nav
            主導航:mainbav
            子導航:subnav
            頂導航:topnav
            邊導航:sidebar
            左導航:leftsidebar
            右導航:rightsidebar
            菜單:menu 子菜單:submenu 標題: title 摘要: summary
            
            
          (3)功能
            標志:logo
            廣告:banner
            登陸:login
            登錄條:loginbar
            注冊:regsiter
            搜索:search
            功能區:shop
            標題:title
            加入:joinus
            狀態:status
            按鈕:btn
            滾動:scroll
            標簽頁:tab
            文章列表:list
            提示信息:msg
            當前的: current
            小技巧:tips
            圖標: icon
            注釋:note
            指南:guild
            服務:service
            熱點:hot
            新聞:news
            下載:download
            投票:vote
            合作伙伴:partner
            友情鏈接:link
            版權:copyright
            
            
          (四)class的命名:
            (1)顏色:使用顏色的名稱或者16進制代碼,如
            .red { color: red; }
            .f60 { color: #f60; }
            .ff8600 { color: #ff8600; }
            (2)字體大小,直接使用"font+字體大小"作為名稱,如
            .font12px { font-size: 12px; }
            .font9pt {font-size: 9pt; }
            (3)對齊樣式,使用對齊目標的英文名稱,如
            .left { float:left; }
            .bottom { float:bottom; }
            (4)標題欄樣式,使用"類別+功能"的方式命名,如
            .barnews { }
            .barproduct { }
            
            
          注意事項:
            1.一律小寫;
            2.盡量用英文;
            3.不加中杠和下劃線;
          (我倒是經常加)
            4.盡量不縮寫,除非一看就明白的單詞.
          (偷懶經常縮寫)
            主要的 master.css 模塊 module.css 基本共用 base.css
            主題 themes.css 專欄 columns.css 打印 print.css
            文字 font.css 表單 forms.css 補丁 mend.css
            布局,版面 layout.css

          用table布局和表單元素編寫一個注冊頁面

          1)注冊頁面

          <!DOCTYPE html>
          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
              <title>注冊登錄頁面</title>
          </head>
          <body>
              <form action="http://www.bd.com/register.aspx" method="get">
                  <table cellpadding="5" cellspacing="0" width="380" height="300">
                      <tr>
                          <td>用戶名:</td>
                          <td><input name="txtName" /></td>
                      </tr>
                      <tr>
                          <td>密 碼:</td>
                          <td><input type="password" name="txtPwd" /></td>
                      </tr>
                      <tr>
                          <td>選擇省:</td>
                          <td>
                              <select name="SS">
                                  <option value="HN" selected="selected">河南</option>
                                  <option value="HB">河北</option>
                              </select>
                          </td>
                      </tr>
                      <tr>
                          <td>性 別:</td>
                          <td><input type="radio" name="rd" value="1" />男<input type="radio" name="rd" value="0" />女</td>
                      </tr>
                      <tr>
                          <td colspan="2">
                              <fieldset>
                                  <legend>興趣愛好</legend>
                                  <input name="interest" type="checkbox" value="ppq" />乒乓球
                                  <input name="interest" type="checkbox" checked="checked" value="ts" />跳水
                                  <input name="interest" type="checkbox" value="pq" />排球
                              </fieldset>
                          </td>
                      </tr>
                      <tr>
                          <td colspan="2" align="middle">
                              <h3>注冊免責協議</h3>
                              <textarea cols="50" rows="3" readonly="readonly">  **提醒您:在使用**搜索引擎(以下簡稱**)前,請您務必仔細閱讀并透徹理解本聲明。您可以選擇不使用**,但如果您使用**,您的使用行為將被視為對本聲明全部內容的認可。
                                      鑒于**以非人工檢索方式、根據您鍵入的關鍵字自動生成到第三方網頁的鏈接,除**注明之服務條款外,其他一切因使用**而可能遭致的意外、疏忽、侵權及其造成的損失(包括因下載被搜索鏈接到的第三方網站內容而感染電腦病毒),**對其概不負責,亦不承擔任何法律責任。
                                      任何通過使用**而搜索鏈接到的第三方網頁均系他人制作或提供,您可能從該第三方網頁上獲得資訊及享用服務,**對其合法性概不負責,亦不承擔任何法律責任。
                                      **搜索結果根據您鍵入的關鍵字自動搜索獲得并生成,不代表**贊成被搜索鏈接到的第三方網頁上的內容或立場。
                                      您應該對使用搜索引擎的結果自行承擔風險。**不做任何形式的保證:不保證搜索結果滿足您的要求,不保證搜索服務不中斷,不保證搜索結果的安全性、正確性、及時性、合法性。因網絡狀況、通訊線路、第三方網站等任何原因而導致您不能正常使用**,**不承擔任何法律責任。
                              </textarea>
                          </td>
                      </tr>
                      <tr>
                          <td colspan="2" align="middle">
                              <input type="submit" value="注冊" />      
                              <input type="reset" />
                          </td>
                      </tr>
                  </table>
              </form>
          </body>
          </html>

          action:指定提交到服務器的哪個程序處理,比如asp.net的一般處理程序等

          method:提交的方式1)post隱式提交,比較安全 2)get顯示提交如下圖所示

          select:selected="selected"與checkbox的checked="checked"表示默認選中項

          textarea:rows與cols表示此文本框內容要顯示的行數與列數

          注冊頁面;網址信息自己測試


          主站蜘蛛池模板: 色狠狠一区二区三区香蕉蜜桃 | 成人在线观看一区| 红桃AV一区二区三区在线无码AV| 亚洲一区二区三区深夜天堂| 色噜噜狠狠一区二区三区| 亚洲一区影音先锋色资源| 无码精品人妻一区| 国产韩国精品一区二区三区| 国产在线精品一区二区三区直播| 福利一区二区三区视频午夜观看| 久久精品国产AV一区二区三区| 成人乱码一区二区三区av| 无码av中文一区二区三区桃花岛 | 中文字幕精品一区二区2021年 | 国产福利无码一区在线| 在线播放一区二区| 无码免费一区二区三区免费播放| 亚洲国产高清在线一区二区三区 | 亚洲无线码在线一区观看| 国产丝袜无码一区二区视频| 性色AV一区二区三区天美传媒| 日本大香伊一区二区三区| 中文日韩字幕一区在线观看| 亚洲日本一区二区一本一道| 亚洲一区二区三区在线播放| 国产另类ts人妖一区二区三区| 日韩一区二区三区视频| 白丝爆浆18禁一区二区三区 | 久久久精品人妻一区亚美研究所 | 亚洲av成人一区二区三区 | 久久精品国产亚洲一区二区| 国产一区二区三区久久精品| 久久久综合亚洲色一区二区三区| 久久久久无码国产精品一区| 精品日韩亚洲AV无码一区二区三区| 精品国产AV一区二区三区| 精品亚洲av无码一区二区柚蜜| 福利一区二区视频| 国产乱码精品一区二区三区中文| 老熟妇仑乱视频一区二区| 国产一区二区三区乱码在线观看|