曾經的一道前端面試題反思

     第一次老是顯得如此寶貴,別想歪了,這裏是指面試。前端的處女面獻給了阿里,當時沒答上來的題目還歷歷在目,今晚忽然就想到了這麼一道面試題:低版本瀏覽器如何兼容JSON對象?javascript

     這樣的問題都沒答出來,就知道本身當年有多弱了,簡單說下思路吧:html

// 具體實現想看:douglascrockford : https://github.com/douglascrockford/JSON-js

JSON.parse的思路:

1. eval(str)

2.(new Function('return ' + str))()

      然而當經過示例來操做下呢?前端

var str = '{"name": "cnblogs"}'

method 1: eval(str) // SyntaxError: Unexpected token :

method 2: (new Function('return ' + str))() // {name: "cnblogs"}

問題就來了,爲何執行eval(str)就報錯了呢?若是咱們對str加上括號試試:java

eval("(" + str + ")")   // {name: "cnblogs"}

什麼?加上了一個括號就成功了,爲什會這樣?git

思路一:eval入手,查過ES5後,發現跟eval不要緊,失敗!github

思路二:只好str,裏面最大的特徵就是"{"、":"、"}"了,此次總算找到問題的關鍵了,下面就分析問題產生的緣由:面試

首先,{}在javascript中存在幾種用處呢?express

  • 對象: 用於建立對象 var obj = {...}
  • 代碼塊(code block): if () {...}

下面就在develop tool測試下:瀏覽器

{name: 'cnblogs'}
// 'cnblogs' ? 什麼,竟然返回一個字符轉,而不是一個對象,說明此處的"{}"是code block,前面的'name'是標記(label statement)

//而這種狀況下呢:
var obj = {name: 'cnblogs'}
obj
//  返回: Object {name: "cnblogs"}, 說明此時"{}"被當成了對象來解析

那爲何會存在兩種不一樣的解析方式?測試

  1. {}用於開頭時: 會被當成code block來解析
  2. "="是複製運算符,左右邊必須是表達式,具體詳看ES5,這樣右邊會被當成表達式來進行解析,最終解析成對象

      到這裏就柳暗花明了吧?eval(str)會將裏面"{}"當成code block來解析,而str中存在":",且"name"帶上了雙引號,說明不是label,「name」、「cnblog」均會被當成statement來解析,那麼中間的":"就會爆出"Unexpected token :",因此要解決該問題,只須要使js解析器將str裏面的內容當成對象來eval就能夠了。方法不單單上面提到的添加"()",還有其餘方式,例如:藉助於","

eval('0,' + str)

    

      立志往前端方向發展的同窗,把ES5規範好好讀讀吧,內容很少,可是會讓你對js有深入的理解,除了lexical execution較難理解外,其餘章節下功夫仍是能夠吃透的。

相關文章
相關標籤/搜索