文首發自「慕課網」,想了解更多IT干貨內容,程序員圈內熱聞,歡迎關注!
JavaScript 是一種弱類型的語言,且函數是一等公民,因此在代碼的組織上非常靈活,有非常多的方法可以實現代碼的復用。
“函數是一等公民”的意思,即函數和其他的類型一樣,并沒有什么特殊。因此在 JavaScript 中,函數可以和其他類型的數據一樣,被當成值返回、被當成參數傳遞、被不同的變量賦值/引用等。
具體到代碼復用方面,在 JavaScript 中被使用最廣泛的就是類和 Mixin。
類,即 Class,在 Java 等語言中,類是最基本的概念,所有的代碼都要基于類來編寫。對類一個最直觀的理解是“它是對象的藍本,對象的形狀由類的定義來決定”。因此,只要我們將需要復用的代碼封裝到類中,然后在不同的場合都使用這個類的實例,就可以在各種不同的場合來復用這些相同的代碼。
如果我們希望復用一部分代碼,但是又希望不同場合的對象形狀是不同的,則可能需要使用類的繼承:將需要復用的代碼放到基類中,將不同的部分放入不同的子類中,然后不同場合視需要使用不同子類的實例,但這些實例仍然可以共享基類的方法和成員,從而實現代碼復用。
class Animal{
constructor() {
this.head=1;
}
eat() {
}
}
class Cat extends Animal{
constructor() {
super();
this.legs=4;
}
makeSound() {
console.log('miao');
}
}
在這個例子中,我們定義了一個類Animal,它頭(head)的數量為1,并且有eat()方法。接下來有一個Cat類繼承自Animal類,它加上了自定義的成員legs和makeSound(),并且從基類Animal中繼承了head和eat(),因此它既可以使用自定義的成員,也可以利用基類的成員,這便是繼承復用代碼的方式。
在 ES6 之前,JavaScript 中是沒有正統的“類”的概念的,這也是 JavaScript 飽受誤解的一個重要來源:習慣了使用“類”來組織代碼的開發者來到了 JavaScript 的世界后,發現他們熟悉的概念和模式都不見了,因此覺得這門語言本身是有非常大的缺陷甚至是“玩具語言”。
但是因為 JavaScript 在設計之初有參考一些 Java 的概念,加上它非常靈活,懂這門語言的開發者仍然可以使用一些方法來模擬類,從而將經典的基于類的概念和模式引入 JavaScript 中。這些方法中使用最廣泛的就是“構造函數”加“基于原型的繼承”。
上面的例子用構造函數和基于原型的繼承,寫起來類似這樣:
function Animal(){
this.head=1;
}
Animal.prototype.eat=function() {
};
function Cat(){
this.legs=4;
}
Cat.prototype=new Animal();
Cat.prototype.makeSound=function() {
console.log('miao');
};
ES6 正式為 JavaScript 加上了“類”的概念,但它在概念和性質上與基于原型的類模擬相差不多,在日常使用的場景下,基本上可以認為它們是相同的。
而有時候為了代碼的靈活或者兼容,開發者仍然會使用 ES6 之前的類的寫法,Vue 源代碼中亦是如此。為了避免無謂的爭論,后文中將不區分 ES6 的類和 ES5 基于原型的模擬類,而統稱為“類”。
Mixin 在一些中文文檔中也被稱為“混入”或者“混元”,是另一種實現代碼復用的方式。在具體的原理上,類主要通過“繼承”來復用代碼,而 Mixin 則主要是通過“組合”。
Mixin 的具體做法是:定義一些單獨的方法,然后在某一些時機(例如初始化),動態地修改當前使用的對象,將這些方法掛載到對象上去,從而實現不同對象中都可以使用同一個方法。這種行為充分地復用了 JavaScript 語言的動態性,在運行時修改對象,從而改變對象的行為,實現代碼復用。
例如在 Vue 的構造函數定義中,就使用了一系列的 mixin 來擴展 Vue 類型的方法,以initMixin()為例:
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init=function (options?: Object) {
}
}
當initMixin()被調用時,就會在傳入的Vue變量(Vue 構造函數)的原型上添加_init()方法。
Vue 中大量使用了類似上面示例的 Mixin,從而使得功能代碼可以分散在不同的代碼文件中,從而保持代碼結構簡單。
繼承和 Mixin 都能很好地達到代碼復用的目的,但它們也有各自的優缺點。
當繼承使用過多時,容易出現一些問題,例如繼承層數過多、大量覆蓋父類實現等,使用不當時會導致代碼難以維護。關于這一點,可以參考更多的資料,例如被廣泛流傳的“組合優于繼承”的說法,在此不再贅述。
Mixin 也有一些缺點,例如代碼組織過于靈活,很容易導致代碼間的互相引用混亂,從而影響可維護性。
因此在實際使用中,選擇使用繼承還是使用 Mixin 來組織代碼并不是一個有明確答案的問題,需要根據實際情況來進行取舍。Vue 中大量使用了 Mixin 來組織代碼。
了解類和 Mixin 有助于我們從宏觀上去構架代碼,從而使文件組織更合理,代碼結構更可讀。而具體到 Vue 源碼上,則能幫助我們撥開 Vue 源碼結構上的迷霧,使我們在閱讀 Vue 源碼時不被與類和 Mixin 有關的代碼干擾,從而更好地理解 Vue 的代碼組織形式和各個部分的實現原理。
歡迎關注「慕課網」,發現更多IT圈優質內容,分享干貨知識,幫助你成為更好的程序員!
日,位于北京海淀區四季青鎮的Wehouse小區業主沈強(化名)向新京報記者反映,“我們小區別墅區里的舊違建沒有完全拆除,近期還增添了一些新違建。我們被違建問題困擾多年,一直得不到解決。”
對此,四季青城管隊一位負責人回應記者說,“Wehouse小區的別墅區共有100多棟樓,每棟樓大概3戶,加起來共有300多戶,其中約有95%的住戶存在不同程度的違建問題。目前,涉及違建的相關問題還在處理當中。”
違法住戶鉆空子,仍在建設新違建
今年9月29日,北京市人民政府第86次常務會議審議通過修訂后的《北京市禁止違法建設若干規定》(以下簡稱“295號令”),于11月15日起正式施行。隨著295號令的正式實施,推動了北京市違法建設執法體制更加優化,執法行為更加依法規范,助力實現違法建設新增“零增長”目標。
“但是近期,我們小區增添了新違建,急需治理。” Wehouse小區業主沈強對新京報記者說,“有些住戶正在建設違建,城管部門來了就停工,城管部門走了就繼續建。”
12月8日,新京報記者趕到了位于海淀區常青園路與通匯路交會處的Wehouse小區進行實地走訪。當天,新京報記者從小區北門進入,看到一輛吊車正在施工作業,周圍并無明顯防護設施。
2020年12月8日,在Wehouse小區里,一住戶家正在施工。
新京報記者注意到,這輛吊車正在對小區46號樓附近的房屋進行施工,附近多棟建筑已被黑色網格物圍住,透過這些圍擋可以看到內部有工人正在施工,不時還有工人將圍擋外的沙石材料運進圍擋內。當記者詢問現場多位工人正在進行何種施工時,得到工人們的回應皆為“不清楚”或“不知道”。
那么,Wehouse小區這些正在施工的樓棟是否具備合法施工手續?新京報記者就此問題向小區屬地的海淀區四季青鎮政府及四季青城管部門進行反映,隨后,幾名城管工作人員來到現場,叫停了上述正在施工的工程。
“這些建筑確實是存在違法建設的情況。我們之前叫停過,也讓這些住戶及時拆除,其他相關問題還在處理當中。”四季青城管隊趙姓負責人如是說。
10多年舊違建被“翻新”,變成5層“月子中心”
同日,新京報記者在Wehouse小區走訪發現,小區里的居民建筑基本都是別墅樣式,大部分居民建筑都已經經過了改建或者加蓋。有些居民家將類似陽臺的部位加蓋了一層或一部分;有些居民家加蓋了約兩層的建筑;有些居民在門前的空地上從下往上建起了與原有住宅混為一體的樓體。
“除了新增違建以外,Wehouse小區里還有舊違建尚未拆除。我們被違建問題困擾多年,一直得不到解決。” 沈強如是說。
實際上,早在2019年5月13日,北京市規劃和自然資源委員會、北京市城管綜合行政執法局聯合發布《關于立即處置在施違法建設的實施意見(試行)》,貫徹市委市政府對違法建設“零容忍”、實現動態“零增長”的重要舉措。
2019年5月21日,有多位Wehouse小區業主曾向新京報記者反映,該小區里的違建難以拆除。2019年5月23日下午,新京報記者曾在Wehouse小區看到,小區4-1、4-2別墅在圍擋內被緊鑼密鼓地改造,地下部分區域已經被挖開,僅有幾根柱子支撐著地上建筑。(詳見https://www.bjnews.com.cn/detail/155870462214221.html)
彼時,四季青鎮政府辦公室工作人員向新京報記者表示,“2018年12月,四季青鎮執法隊對Wehouse小區巡查發現該處存在新生違建行為,執法隊對該處新生違建責令停工,暫扣電鎬等施工工具。截至2019年5月23日,執法隊張貼約談通知書和整改通知書10余次,暫扣電鎬、發電機、沖擊鉆等施工工具30余件。”
然而,時至今日,4號樓的違建問題仍沒有得到完全解決。小區業主朱晨(化名)介紹說,“去年,已經有居民向相關部門舉報4號樓的違建問題,曾經受到多方關注。可是,現在4號樓的違建沒有被拆除干凈,4號樓經過‘加蓋翻新’,變成了地上5層的宏偉建筑,地下部分也被進行了較大規模的改造,現在已經開起了‘月子中心’。”
2019年5月,Wehouse小區4號樓正在施工。
Wehouse小區4號樓經過加蓋翻新,變成了地上5層的建筑。
本周,新京報記者在Wehouse小區4號樓附近探訪時發現,與2019年5月相比,4號樓發生了很大改變,這棟灰白色的多層建筑無論從占地規模、高度還是整體風格氣勢已經明顯超過小區其他居民家房子。從4號樓一層地面往上數,有5層窗戶,類似一棟5層獨棟建筑,現在已經基本裝修完畢,透過玻璃門,可以看到內部的電子屏顯示的字樣為“月子中心”,并已經有工作人員在辦公。
對此,四季青城管隊趙姓負責人稱,“Wehouse小區4號樓的違建基本都是十多年前建的,去年拆過一部分,目前還有一部分在處理階段。”
對于Wehouse小區形成如此大面積的違建,小區多位居民認為小區物業公司負有一定責任。“如此大面積的違法建設,肯定有一些大型機械和大型車輛參與施工,施工人員的進出、施工材料的輸入、建筑垃圾的運出等都不可能悄悄完成。”小區居民朱晨告訴新京報記者,小區居民進行裝修等活動都需要向物業公司報備,加蓋違建也絕非一朝一夕就能完成,物業公司不可能不知情,所以,物業公司沒有盡到及時制止和上報的職責。此外,物業公司也未能對加蓋違建的車輛和人員進行限制。”
針對居民所述物業公司問題,新京報記者多次與小區物業服務商北京博安物業服務有限公司聯系,該公司張姓負責人表示,“我們就此問題向有關部門舉報過、也制止過。”當記者問及相關施工車輛如何進入小區時,這名張姓負責人表示,“我們公司有人專門對接,我不能回答。”
對于物業公司的此種說法,多名業主表示:“Wehouse小區違建問題已經持續存在了很多年,業主的背景也不盡相同,單靠物業公司治理起到的作用很有限,主要還要靠政府相關部門協同下大力度,方能有效治理。”
政府部門:不是不想拆,是有難度
對于Wehouse小區違建問題的處理進展,新京報記者多次與四季青城管隊進行聯系。四季青城管隊相關負責人回復記者時表示,“Wehouse小區住戶地上樓層的規劃基本都是2層到3.5層,超過的層數基本都是違法建筑。我們沒有個別業主所說的選擇性執法。由于管理的區域比較大,且Wehouse小區違建面積又比較大,涉及將近300戶,處理起來有些難度,需要一步一步去處理。目前,我們已經將部分涉及違建的房子產權凍結,接下來能做到的只能是發現違建行為及時叫停,等待上級領導的下一步安排。”
對于Wehouse小區4號樓的違建問題,上述四季青城管隊相關負責人稱,“按照正規規劃,4號樓前面是2層、局部是3層。大概從2006年開始,4號樓的違建開始施工,當年基本建成,但是沒有裝修。其間,城管隊對4號樓進行過治理,拆過一部分,但直至現在,4號樓的違建問題尚未徹底處理,仍有相關問題在處理當中。”
隨后,新京報記者就此事又聯系到了海淀區四季青鎮人民政府。一位程姓副鎮長回復記者稱,“關于個別業主所說的城管涉嫌‘選擇性執法’問題,我將會去核查。關于違建問題的處理,我們將在依法依規的基礎上發現一起處理一起,已經形成的違建,也要由城管隊去依法依規處理,今后絕對不能允許違建新增。”
當地一位政府內部人士向記者透露,“目前,相關部門不是不想拆此違建,而是拆起來有難度,背后牽扯的人員眾多,僅靠一個城管隊太難了,要多部門協作起來才能真正治理好這些違建。” 近一年來,隨著北京城市疏解工作的推進和繼續提升城市環境的需要,相關部門加大對違建的拆除力度,勢在必行。新京報記者將繼續跟蹤報道此事。
新京報記者 張建 攝影 張建
編輯 武新 校對 劉越
郵箱zhangjian@bjnews.com.cn
來源:新京報
已知如下數組: var arr=[ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 編寫一個程序將數組扁平化去并除其中重復部分數據,最終得到一個升序且不重復的數組
組實例的 flat(),flatMap()
數組的成員有時還是數組,Array.prototype.flat()用于將嵌套的數組“拉平”,變成一維的數組。該方法返回一個新數組,對原數據沒有影響。
上面代碼中,原數組的成員里面有一個數組,flat()方法將子數組的成員取出來,添加在原來的位置。
flat()默認只會“拉平”一層,如果想要“拉平”多層的嵌套數組,可以將flat()方法的參數寫成一個整數,表示想要拉平的層數,默認為1。
上面代碼中,flat()的參數為2,表示要“拉平”兩層的嵌套數組。
如果不管有多少層嵌套,都要轉成一維數組,可以用Infinity關鍵字作為參數。
如果原數組有空位,flat()方法會跳過空位
flatMap()方法對原數組的每個成員執行一個函數(相當于執行Array.prototype.map()),然后對返回值組成的數組執行flat()方法。該方法返回一個新數組,不改變原數組。
flatMap()方法的參數是一個遍歷函數,該函數可以接受三個參數,分別是當前數組成員、當前數組成員的位置(從零開始)、原數組。
然后,我們來看看文章開始的那道題目如何優雅的求解
如果你還有好的方法,歡迎在下面留言,我會補充上去,供大家學習參考
參考文章:
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/8
*請認真填寫需求信息,我們會在24小時內與您取得聯系。