Internet Develppment
      互聯(lián)網(wǎng)開發(fā)& 推廣服務(wù)提供商

      我們擅長商業(yè)策略與用戶體驗(yàn)的完美結(jié)合。

      歡迎瀏覽我們的案例。

      首頁 > 新聞中心 > 新聞動(dòng)態(tài) > 正文

      JavaScript命名沖突不可避免?沖突源有哪些

      發(fā)布時(shí)間:2022-03-17 09:16:24來源:博客園

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

        不斷發(fā)展的 JavaScript:不要破壞 web!

        JavaScript 的一個(gè)發(fā)展核心原則就是"不要破壞 Web":在將新特性添加到語言中后,所有現(xiàn)有代碼都必須能夠繼續(xù)運(yùn)行。

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

        在為新特征(如方法名稱)選擇名稱時(shí),需要進(jìn)行一個(gè)重要的測試,即在瀏覽器的 nightly 版本(早期預(yù)發(fā)布版本)中添加該特征,并檢查是否有任何網(wǎng)站出現(xiàn)錯(cuò)誤。

        接下來將介紹過去案例中的的四個(gè)沖突源,當(dāng)產(chǎn)生這四種沖突時(shí),就必須重命名特征。

        沖突源1:向內(nèi)置原型添加方法

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

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

        什么是猴子補(bǔ)丁?

        如果我們給內(nèi)置原型添加方法,我們就是在運(yùn)行時(shí)修改一個(gè)軟件系統(tǒng)。這樣的修改被稱為猴子補(bǔ)丁。簡單來說,對(duì)其含義有兩種可能的解釋。

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

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

        反對(duì)改變內(nèi)置原型的原因

        對(duì)任何類型的全局命名,都會(huì)存在名稱沖突的風(fēng)險(xiǎn)。如果有解決沖突的機(jī)制,就能規(guī)避風(fēng)險(xiǎn)。例如:

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

        可以通過將符號(hào)添加到 JavaScript 中,以避免方法之間的名稱沖突。例如,任何對(duì)象都可以通過添加一個(gè)鍵為 .NET 的方法而成為可迭代的。由于每個(gè)符號(hào)都是唯一的,所以這個(gè)鍵永遠(yuǎn)不會(huì)與任何其他屬性鍵 .Symbol.iterator 發(fā)生沖突。

        然而,帶有字符串鍵的方法會(huì)導(dǎo)致名稱沖突:

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

        如果一個(gè)名字已經(jīng)被某個(gè)庫使用了,那么這個(gè)名稱就不能用于命名 JavaScript 標(biāo)準(zhǔn)庫的一個(gè)新特性。

        具有諷刺意味的是,謹(jǐn)慎地添加一個(gè)方法可能會(huì)適得其反:

        我們會(huì)檢查一個(gè)方法是否已經(jīng)存在。如果沒有,我們就添加它。

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

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

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

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

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

        ES2019 的方法最初是和 MooTools.Array.prototype.flat () .flatten ()相沖突。

        修改內(nèi)置原型并不總是糟糕的

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

        沖突源2:檢查一個(gè)屬性的存在

        ES2022 的方法最初是 .NET 的。因?yàn)橐韵聨鞕z查屬性以確定對(duì)象是否是一個(gè) HTML 集合(而不是一個(gè)數(shù)組),所以它必須被重新命名:Magic360、YUI 2、YUI 3.Array.prototype.at () .item () .item

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

        自 ES2020 以來,我們可以通過 globalThis 訪問全局對(duì)象。Node.js 一直使用該名稱來實(shí)現(xiàn)此目的。最初的計(jì)劃是為所有平臺(tái)標(biāo)準(zhǔn)化該名稱 .global

        然而,以下模式經(jīng)常被用來確定當(dāng)前平臺(tái):

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

        沖突源4:通過創(chuàng)建局部變量 with 語句

        JavaScript 的聲明 with 語句

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

        該語句將一個(gè)對(duì)象的屬性變成局部變量:with

        由 with 語句引起的沖突

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

        當(dāng) ES6 方法被添加到 JavaScript 中時(shí),如果用 Array(B行)來調(diào)用它,它就會(huì)失效。該語句將 Array 的所有屬性變成了局部變量。其中一個(gè)是繼承的屬性。因此,A行中的語句已記錄,不再是參數(shù)

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

        Unscopables:防止 with 導(dǎo)致的沖突

        公共符號(hào)Symbol.unscopables 允許對(duì)象隱藏語句中的某些屬性。它只在標(biāo)準(zhǔn)庫中使用一次,對(duì)于 Array.prototype:with

        結(jié)論

        以上提出了 JavaScript 結(jié)構(gòu)與現(xiàn)有代碼發(fā)生名稱沖突的四種方式:

        向內(nèi)置原型添加方法

        檢查屬性是否存在

        檢查全局變量是否存在

        創(chuàng)建局部變量 with

        沖突的某些來源很難預(yù)測,但存在以下一些一般規(guī)則:

        不要更改全局?jǐn)?shù)據(jù)。

        避免檢查是否存在全局?jǐn)?shù)據(jù)。

        請(qǐng)注意,內(nèi)置值將來可能會(huì)獲得其他屬性(自己的或繼承的屬性)。

        對(duì)于庫來說,為 JavaScript 值提供功能的最安全方法是通過函數(shù)。如果 JavaScript 得到一個(gè) pipe operator,我們也可以像方法一樣使用它們。
        (邯鄲微信平臺(tái)

      最新資訊
      ? 2018 河北碼上網(wǎng)絡(luò)科技有限公司 版權(quán)所有 冀ICP備18021892號(hào)-1   
      ? 2018 河北碼上科技有限公司 版權(quán)所有.
      主站蜘蛛池模板: 国产午夜精品一区二区三区小说| 动漫精品专区一区二区三区不卡| 中日韩一区二区三区| 无码精品久久一区二区三区| 亚洲午夜福利AV一区二区无码| 五十路熟女人妻一区二区| 精品无码一区在线观看| 亚洲av无码一区二区三区在线播放| 亚洲视频在线观看一区| 99精品国产高清一区二区麻豆 | 亚洲AV无码一区二区三区牲色| 亚洲免费一区二区| 国产午夜精品一区二区三区| 内射一区二区精品视频在线观看| 国产一区二区精品久久岳√| 97se色综合一区二区二区| 日韩免费视频一区二区| 无码精品一区二区三区免费视频 | 狠狠色综合一区二区| 国精产品999一区二区三区有限| 日韩经典精品无码一区| 另类一区二区三区| 制服丝袜一区二区三区| 国产一区二区视频在线播放| 久久综合一区二区无码| 国产观看精品一区二区三区| 精品国产乱子伦一区二区三区| 亚洲av无码一区二区三区乱子伦 | 精品一区二区三区自拍图片区| 美女福利视频一区| 久久精品国产一区二区三| 久久久精品人妻一区亚美研究所 | 国产精品综合AV一区二区国产馆| 91精品一区二区三区久久久久| 高清精品一区二区三区一区| 国产精品一区在线麻豆| 日本一区中文字幕日本一二三区视频| 一区二区视频传媒有限公司| 中文字幕精品亚洲无线码一区 | 免费一本色道久久一区| 亚洲第一区视频在线观看|