在使用前端框架的同時,該如何提升自己原生JS的能力?

現在,前端有各種JS框架,如最火的三個:ng,vue,react。

平時,我們工作的時候,為了提高效率,肯定會選擇一個框架進行前端的開發。

這些框架都幫我們封裝好了很多的功能。原生JS基礎很重要。那麼我們平時都是用框架進行開發的話,該如何提高自己原生JS的能力?


手擼一個 underscore.js 語言機制和常用函數就能實戰一遍了,然後手擼一個 zepto.js DOM 相關的東西也能熟悉一發。


前端框架不止是js,更重要的還有設計思想和編程思維

而且最重要的是它不是一蹴而就的,是一個團隊迭代無數次從最初的設想然後一步步踩坑寫成的。

從最開始的操作dom時代(以jq為主)到現在的數據驅動時代(三大框架),我相信保持這樣的思維方式才會不斷讓自己得到提升:在用框架的時候多問問自己為什麼要這樣用?

我目前最熟悉的是NG,我對NG這個框架的理解是這樣的:

為什麼要組件化?為什麼要MV*分離?為什麼要數據驅動?為什麼要使用服務?我在使用它的時候總會有一連串的問題冒出來。

只知道用確不知道為什麼用用了有什麼好處有什麼壞處這大概就是我春招面試慘敗的原因吧。

就拿一個非常簡單的NG指令*ngIf來說,不去深究它,只知道它可以根據表達式的真假決定是否顯示一塊HTML內容的話,就太悲哀了。

去查閱相關資料後(包括但不限於書籍、官網文檔、NG的github、stackoverflow),我發現可以自定義一個myIf指令來實現ngIf的功能:

import {
Directive, SimpleChange, ViewContainerRef, TemplateRef, Input
} from "@angular/core";

@Directive({
selector: "[myIf]"
})
export class myIfDirective {

constructor(private container: ViewContainerRef,
private template: TemplateRef&) {
}

@Input("myIf")
expressionResult: boolean;

ngOnChanges(changes: { [property: string]: SimpleChange }) {
let change = changes["expressionResult"];
if (!change.isFirstChange() !change.currentValue) {
this.container.clear();
} else if (change.currentValue) {
this.container.createEmbeddedView(this.template);
}
}
}

這時又湧現出一大串問題:

  1. 為什麼要引入Directive?
  2. 為什麼myIf既要和selector還要和Input關係?
  3. ngOnChanges方法又是幹嗎的?
  4. ViewContainerRef和TemplateRef又是什麼鬼?為什麼構造函數里只有它們?
  5. 這樣做的好處和壞處是什麼?

這時繼續查閱相關資料,知道了

  1. Directive是自定義指令的時候必須使用的,順便還複習了一下裝飾者模式,它的作用就是動態地擴展一個對象的功能。
  2. selector是用來確定裝飾器目標的。Input可以讓NG讓數據從模板流向類,這樣myIf綁定的表達式就進入到這個類了。
  3. ngOnChanges方法是NG自帶的生命周期鉤子之一,當檢測到輸入的數據變化時就會執行,涉及到模板方法,ngIf的核心邏輯就是這個方法里實現的,SimpleChange是其中一種變化類型。
  4. ViewContainerRef是管理DOM元素的,它內部的一些方法可以幫助動態維護DOM元素。TemplateRef就是NG中獲取的DOM元素。在調用指令的時候和這個myIf綁定的HTML元素相關的ViewContainerRef和TemplateRef就被當成構造參數傳入了這個類。
  5. 這樣做就可以實現數據驅動了,前端們再也不用自己去操心dom了,只需要操心控制dom的數據就行了。那這樣做的缺點是什麼呢?那就是還有很多動態顯示組件的功能做不到,不過NG一直在完善相關指令。NG4.0+給ngIf加入了else邏輯。

可是接著又產生了更多的問題:為什麼要使用這些東西?還要涉及到如此多的設計模式?

......

好的,這個過程一直繼續下去的話,我不僅可以接觸大量TS(ES或者說JS)的知識,比如說類、繼承、函數(包括箭頭函數)、邏輯語句、運算符、優先順序、數據類型、非同步、模塊化、DOM等知識,還可以了解很多設計模式、架構風格、性能優化、編碼範式、注釋風格等等非js層面的東西。

js語言本身也在不斷發展的。當自己以後碰見問題時能夠快速想出解決方案的時候,用js還是ts甚至把甩給後端做都無所謂。

所以說到底啊,不要只把眼光局限於js上,要放在整個前端開發上甚至編程思維上,為了提升js能力而提升js能力往往是達不成想要的效果的。

古人有句話:求其上者得其中 求其中者得其下。


原生至少要做到熟悉會用,把MDN上的各種方法過一遍就差不多了。

說下關於框架使用的一些個人看法。

很多開發者使用框架開發存在兩種模式:

1、被框架的各種api限定,導致自身的開發能力受限於框架,甚至覺得自己寫的是假的JS。

2、站在框架設計者的角度看問題,思考為什麼這麼做,而不是框架讓我這麼做。

以react或者vue為例

比如this.a = "a",你可以想到這是setter,進而想到可以用Object.defineProperty來實現。

比如class A extends Component,可以看到開發者使用的比如setState或者大部分方法繼承自Component等等,進而慢慢理解react體系的API結構。

比如非同步處理的實現,看到nextTick,你可以想到非同步API,比如mutationObserver或者setTimeout。

框架或者原生JS都大同小異,多多的思考裡面的設計思想才是重要的。

就算是原生JS的indexOf等等方法,也是封裝了下一層而已。

這方面的例子,建議可以看看babel-polyfill的源碼core-js,相信能夠理解我要表達的意思。

總之,想要更進一步提高開發水平,思考問題的角度和高度可能更加重要。


說起來很簡單,重複看和做就可以了。

  1. 看書:紅寶書,犀牛書,你不知道的JS之類的
  2. 用不同的工具,增加自己的視野。
  3. 看源碼:React, Vue, Underscore.js
  4. 把這些工具、框架的某些功能做個輪子
  5. 看ECMAScript規範
  6. 寫文章記錄你學了什麼知識


看現在框架用到的功能,然後自己造一個簡化版


js,你要學會可以怎麼寫,但更重要的是學會不能怎麼寫。但用好ide和lint就夠了。

把更多的精力放在其它相關領域,如用戶體驗設計、架構/api設計、某些後端技術等。


現在有些公司的前端面試題就是用要你自己寫原生js方法實現es6的polyfill,我覺得是一個好方法


了解基礎,可以從w3cschool上學習一些基礎的JavaScript知識、語法,然後Mozilla開發文檔,這個比較全,把基礎知識鞏固紮實;看一些開源項目的源碼,比如underscore、jQuery,現從underscore.js開始,這個庫很小,代碼只有一兩千行,純粹的工具庫,但是代碼確是很經典的,在看的過程中,遇到不理解的可以網上查,一定要弄清楚;然後進階jQuery,在MVC、MVVM框架出現前,jQuery可是非常火的,這個代碼有1w多行,看起來比較累,也可能很難懂,網上有很多jQuery源碼剖析的書,一旦看懂了,將會提升一個檔次;最後在使用MVVM框架的時候,如果有時間,能研究下代碼自然是更好的,前提是要能看得懂,一步步來。


學js就跟學中文一樣。

小時候我們學中文要每天早上朗誦拼音,朗誦句子,初學js,也是一個個語法概念慢慢的記;

之後,我們不再背拼音,而是直接學習更加高深的中文語法知識、文言文等,我們的js學習也進入了高級知識的學習環節;

後來,我們畢業了 ,進入了工作單位,發現大家已經可以脫離書本講很多高深莫測或者帶著冷笑話的中文了,前端工程師們也不需要專門研究js語法,而是帶著你以前的基礎直接用框架來開發,你會發現其實不需要懂很多的js語法,但是有了框架這麼完善的工具,你用起來就跟每天講中文那麼溜。

其實只有一個道理,現在的前端已來到了工具化時代,網上隨處可見的框架、開源庫、開源項目,幾乎你想要實現的功能都可以通過 npm install xxx,然後 require("xxx")來實現,多麼的方便。

至於為什麼現在還有很多「小公司」的面試會考js的基礎知識,而忽視框架的重要性,主要還是因為他們程序員年齡偏大,沒有跟上時代罷了。

這是一個前端盛世,招聘熱榜第一!


不管是MV**框架,還是jQuery,我們在項目中使用它們,基本上只掌握了框架給我們提供的API的使用方法,而這並不能幫助我們提高JS的能力

拿jQuery舉例,如果在用到一定階段的時候希望在項目中將部分功能抽象成插件的時候

這時去閱讀jQuery的源碼,從源碼中不斷的深入每一個API,理解它們是如何實現的

讀源碼的過程很枯燥而且不容易,但是在學習的過程中自己的JS能力就慢慢的提高了


提高js原生能力無非就是看和寫,對於看的話,肯定是看優秀的書和源碼了,對於書主要分兩類:第一類是基礎類,肯定犀牛書,紅寶書,你所不知道的js,es6等;第二類主要講思想的:比如《JavaScript設計模式》,對於node肯定是《node深入淺出》等。對於源碼可以看看underscore,zepto,vue,react和koa等,不建議看jquery和angularjs。然後就是寫了,先模仿別人的代碼,然後形成自己的風格和思路。


通常我會建議學生花時間學好傳統JS(ES5),甚至不推薦太快用ES6,框架更是可以考慮推後。

但是很多人等不及,上來就框架,弄了很久好像懂了框架,但是不懂JS,到時候碰到問題還是要回過去理解JS。有耐心的人少,慢慢我也不想說了。

太早用框架一定佔用你學習JS語言的時間,框架有自己的概念體系,JS有自己的概念體系,在不同的層次上,雜糅起來未必不能學,但並不好。

你的問題我回答不了,我只想勸你花時間先理解JS,用傳統的JS來寫一些東西。然後你會發現雖然框架還是要學,但是會有機得多,如果用transpiler,你知道目標代碼大概是什麼,背後的道理是什麼,會更加成足在胸。


實名反對樓上一大片。

JS不用刻意提升。JavaScript核心本身很小,如果說提升其實就是很泛泛的編程技巧。專門提升原生JS的能力不如多學幾種語言,不然你再精通JS也不知道它哪裡設計的是錯的。

如果非要看點JS的一本蝴蝶書足矣,去掉第一張沒用的圖,去掉最後作者自吹的工具,把中間薄薄的幾十頁看明白就好。

特別是躲開背DOM BOM API的圈子,告訴你要學JS扔給你一本犀牛書一本紅寶書的都是誤人子弟。那點破玩意每次去MDN上先查就行了。

此外不要看W3School,很多人都推薦這個,說看完就畢業了的基本都是小白。看MDN就行,大部分常用的東西都有中文。

另外順路安利下,React和JS的相關性要比另外兩個框架大一點點,用好React就算用好JS了。JSX就是普通對象,你看搞個映射也要map成數組,而不是用封裝好的directive DSL。

---

補充下為什麼這麼說:現在你能找到的純教JS的書都是很多很多年以前的了,而只有框架的教程才有最新最多的。我們新入職以前不寫前端的同事有很多啃了很多JS書上項目就發現跟他學的東西完全不一樣……

看JS基礎不如開始用框架做東西好,現在JS框架基本都把Model或者VM獨立出來,讓你足夠的空間讓你耍JS。先用起來再學。

看以前的書很多東西不然是錯的不然是沒用的:

沒用的如:跟孔乙己一樣花幾十頁告訴你函數的4種調法學起來沒啥營養。

錯的如:告訴你不能用new,得用Object.create云云。


「為了更好地品味美食,我要不要去練習一下烹飪啊?」

——不需要。

雖然學習烹飪的確可以增進人對美食的了解,但是人家做東西給你吃真的不是為了讓你明白怎麼做飯的。想學烹飪是想學烹飪,和東西好不好吃無關。

如果說真的想把框架和「原生」聯繫到一起去,問有什麼東西可以學習,那就只能說可以去看看ng的設計模式,react的diff演算法之類的了……然而那種東西通常情況下就算是會了也不會有什麼鳥用的。

有價值一點的回答:

LoDash、RxJS、jQuery這三個庫,我覺得不需要去掌握什麼源代碼,只是會用各種API,就已經勝過扯淡無數了。


沒人說看書嗎?coding是實踐書籍是理論,實踐和理論互相印證進步是飛快的,而且經典技術書籍的知識是系統性的,比擼什麼源碼強多了。推薦幾本還記得的我入門時看的書:

紅寶書 zakas的:JavaScript高級程序設計

同樣是zakas大神的:編寫可維護的JavaScript

高性能JavaScript

高性能網站建棧指南

基於MVC的JavaScript Web富應用開發

JavaScript設計模式

你不知道的JavaScript

這些都是前些年的經典書,但是非常有價值。最近幾年沒有太關注前端技術書籍了。

阮老師的ES6教程也非常值得學習,雖然有些不夠準確的瑕疵,但瑕不掩瑜。


你看我是怎麼學原生 JS 的:

我用了兩個月的時間才理解 let


你把順序和因果弄反了,應該是先學好JS再去用框架


編程能力很重要,和框架沒有關係,和原生js也沒有什麼關係。編程能力上去了,什麼都好說。你總不能用全站用原生去開發吧。

用框架,熟悉了去研究別人的套路,怎麼封裝的,你編程能力上去了就能搞懂了,編程能力沒上去,才會糾結這些東西,總之一句話,還是代碼量沒達到,關鍵詞,編程能力!慢慢來。

感謝那些造框架的輪子哥們!!!


學校學的.net,做網站,於是自學css,然後直接上手的jquery。開始工作是做的.net,兼顧js(那時候的前端就是切圖的,有一些效果隨便找點插件),當時還寫了個jquery分頁插件(後來轉行前端面試還被誇獎過幾次)。

過了一段時間感覺自己有一些瓶頸了,那時候也經常看電子書,例如js高級編程什麼的,發現了原來我學習的順序錯了,於是努力學習原生js,真的是越學越覺得自己知道的太少了!!!

最近的項目時間要求一個月,之前開會沒叫我們,最後拿到設計稿第二天就得開發,我們臨時決定用react,當時我沒看過react,也就知道個mvvm是幹什麼的,然後不小心搜到一個叫dva的開發框架,瞎看了一天直接搭項目了,期間雖然也有很多坑加班,不過都解決了。我應該感謝我過關的js基本功哈哈。我現在看es6很省勁。

還是建議初學者或者沒怎麼研究過js的同學不要急需用框架直接上手,多看js基礎,研究研究底層的js,不然你到時候寫出的代碼就是一團糟。比如setTimeout你了解的透徹嗎,用過內聯函數嗎,new對象時所發生的能說的清嗎,能用閉包來解決一些問題嗎等等。


有了一年工作經驗的人,我覺得應該多學習下設計模式,以前一個騰訊面試官說,代碼之間無非就是抽像,解耦。

有時候就是覺得別人代碼寫的漂亮,bug少,穩定,需求變動隨便改改就可以了。伸縮性好,差距就在這裡。


推薦閱讀:

2016 年的今天,Web 前端框架是否已經同質化?
2017 年,前端的發展是否趨於平緩?

TAG:前端開發 | JavaScript | React | Angular? | Vuejs |