前端資料驅動的框架之下,我們不得不掌握的資料處理方法

笑在秋風中發表於2018-10-28

前端簡史

那是1989年的一個秋天,歐洲核子研究中心的物理學家Tim Berners-Lee發明了超文字標記語言...(此處省略數萬字)。

既然是簡史,那當然不能巴拉巴拉一堆的啦,下面我就嘗試著簡單聊一聊前端那點發展史,如圖

前端資料驅動的框架之下,我們不得不掌握的資料處理方法

在前端刀耕火種的年代,前端的同學開發專案的時候,就是使用原生JS結合瀏覽器提供的原生API,直接操作DOM,在原生API的晦澀難懂和各種瀏覽器的相容性問題中掙扎,突然Duang的一聲,jQuery應運而生,以其簡潔的API,出色的瀏覽器相容性迅速成為部署最為廣泛的JavaScript的庫,全球最大搞基網站,GitHub一直都在用jQuery,直到前幾個月才徹底放棄jQuery。

在原生JS和jQuery的時代,我們的開發是事件驅動的思維模式,流程如下:

前端資料驅動的框架之下,我們不得不掌握的資料處理方法

在事件驅動向資料驅動的過渡階段,MVC模式,也一度非常流行,ASP,JSP,ASP.NET等,這些技術直到現在仍有一些網站在採用,但這種每個需要和後端通訊的操作,瀏覽器都會重新接收到一段可能只是改變了部分資料的整段HTML,然後重新渲染的開發模式,也慢慢的在淡出人們的視野。

近幾年隨著MVVM框架的興起,我們終於擺脫了對DOM的操作,與服務端的通訊接收的只是改變的資料,此時,網站上所能看到的一切,它們不再是HTML、CSS,一切皆資料,網站的每一處細小的細節,都可以先定義好資料,然後由框架進行渲染,我們思維也轉變為資料驅動的模式,流程如下:

前端資料驅動的框架之下,我們不得不掌握的資料處理方法

前端經常需要處理的資料

  • 基本資料型別:String、Boolean、Number、undefined、null、Symbol(ES6)
  • 引用資料型別:object、Function、Array、RegExp等

在日常開發中我們經常需要處理的資料,無外乎上面的這些基本資料型別和引用資料型別,在這裡引用型別中的object指的是由大括號包含,在括號內部物件的屬性以鍵值對的形式如{name:'frontEnd'},JS中有一句很經典的話:“一切皆物件”,如果我們使用[引用資料型別] instanceof Object 會發現返回的都是true,

JavaScript中的所有物件都來自Object;所有物件從Object.prototype繼承方法和屬性,儘管它們可能被覆蓋。例如,其他建構函式的原型將覆蓋constructor屬性並提供自己的toString()方法。Object原型物件的更改將傳播到所有物件,除非受到這些更改的屬性和方法將沿原型鏈進一步覆蓋。(源自MDN)

如果你拿著這句話出去裝逼,說JS中一切皆物件,那你就會被啪啪的打臉,因為String、Boolean、Number、Symbol這些值型別就不是物件,既然不是物件,那我們平常操作字串的屬性和方法是怎麼來的呢?想知道嗎?想知道就往下看。

String型別和String物件

String型別用於表示由零或多個16位Unicode字元組成的字元序列,即字串。 String物件是 JavaScript 原生提供的三個包裝物件之一,用來生成字串物件。

  • 從一道面試題說起

各位童鞋,請看題:

var ranshaw = 'ranshaw',
    str1 = new String(ranshaw),
    str2 = String(ranshaw);
    
// 請確認以下判斷是否準確

str1 === ranshaw

str2 === ranshaw

typeof str1 === typeof str2
複製程式碼

如果你都判斷對了,那說明你已經越過了初級前端的門檻,如果沒有,推薦購買步步高打火機,那裡不會點哪裡

  • String物件

在上題中,我們對str做一些操作,如下圖:

前端資料驅動的框架之下,我們不得不掌握的資料處理方法

沒錯,str1是一個String物件,What!上面不是說String型別不是一個物件的嗎,嗯,String型別當然不是物件,是字元序列,new String()是將原始型別的字串'ranshaw',包裝成了一個物件,通過Chrome控制檯的列印結果我們能看到 str2顯示結果是一個字串,而str1顯示是一個物件並且有length屬性,_proto_屬性,通過_proto_屬性我們還能訪問到工作中常用的一些處理字串的方法,那麼問題來了,作為一個字串的str2也能訪問到String物件的屬性和方法,這是咋回事呢?

前端資料驅動的框架之下,我們不得不掌握的資料處理方法
這裡就得詳細說下“包裝物件”這個東西了,在一定條件下像String這種原始型別的值,會被包裝成一個物件或者說暫時變成一個物件,當字串呼叫String物件的屬性和方法的時候,這一操作就會發生,如當我們取str2的length屬性的時候,實際上就是將str2包裝成了一個物件如str1,然後在呼叫str2包裝物件的length屬性,並且這個物件在用完後就銷燬了,包裝物件是隻讀的所以字串無法新增新的屬性,是不是感覺字串好像也沒那麼簡單,有這感覺就對了,這種無知的飢餓感會將你逼上走向高手的路上,並且越走越遠。

資料的增刪查改

對資料的操作,不管是後端還是前端,最主要的都是增刪改查這四個操作,下面對資料操作的方法,我們都會從這四個方面進行歸類。

字串

通過上文中介紹過的包裝物件,我們知道字串並不能改變其值的,String物件下的方法基本都是返回一個新的字串,都沒有對原字串做更改,所以增刪改這三個操作並不存在,下文是將類似於增刪改的方法或操作歸為一類,方便整理和記憶。

var str1 = 'ran';
var str2 = 'shaw';

// 方式一 "+"號拼接
str1 + str2     // 'ranshaw'
// 方式二 模板字串
`${str1}${str2}` // 'ranshaw'
// 方式三 concat
str1.concat(str2) // 'ranshaw'
複製程式碼
var str = 'hello world'

// charAt  返回指定位置的字元,引數是從0開始編號的位置
str.charAt(1)    // 'e'

// [] 返回指定位置的字元,中括號的值從0開始
str[1]          // 'e'

// indexOf  返回要查詢字串第一次出現的位置,如果沒有就返回-1;引數1:字串,引數2:從該位置向後匹配
str.indexOf('o')  // 4
str.indexOf('o',5) // 7

// lastIndexOf 同indexOf,區別是lastIndexOf是從尾部開始匹配,引數2為從此位置向前匹配
str.lastIndexOf('o') // 7
str.lastIndexOf('o',4) // 4

// match 用於確定原字串是否匹配某個子字串,返回一個陣列,成員為匹配的第一個字串。如果沒有找到匹配,則返回null
str.match('ll') // ['ll']

// search 和match類似,返回值為匹配的第一個位置。如果沒有找到匹配,則返回-1
str.search('ll') // 2
複製程式碼
  • 刪和改
var str = 'hello world';

// slice 從原字串取出子字串並返回,不改變原字串。引數1:起始位置,引數2:結束位置(不包含)
str.slice(0,5)      // 'hello'

// substring 和slice類似
str.substring(0,5)  // 'hello'

//  substr 與slice和substring作用類似,但引數2為字串的長度
str.substr(0,5)    // 'hello'

// replace  替換匹配的子字串,一般情況下只替換第一個匹配(除非使用正則)
str.replace('o','k')  // 'hellk world'
str.replace(/o/g,'k') // 'hellk wkrld'

複製程式碼
  • 其他
var str = '\nhello world '
// trim 去除字串兩端的空格和製表符(\t、\v)、換行符(\n)和回車符(\r)
str.trim()  // 'hello world'

// split 按照給定規則分割字串,返回一個由分割出來的子字串組成的陣列
str.trim().split(' ') //  ["hello", "world"]
複製程式碼

參考資料

阮一峰大神的包裝物件

前端思維轉變--從事件驅動到資料驅動

相關文章