zoukankan      html  css  js  c++  java
  • 曾经的一道前端面试题反思

         第一次总是显得如此宝贵,别想歪了,这里是指面试。前端的处女面献给了阿里,当时没答上来的题目还历历在目,今晚突然就想到了这么一道面试题:低版本浏览器如何兼容JSON对象?

         这样的问题都没答出来,就知道自己当年有多弱了,简单说下思路吧:

    // 具体实现想看: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加上括号试试:

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

    什么?加上了一个括号就成功了,为什会这样?

    思路一:eval入手,查过ES5后,发现跟eval没关系,失败!

    思路二:只好str,里面最大的特征就是"{"、":"、"}"了,这次总算找到问题的关键了,下面就分析问题产生的原因:

    首先,{}在javascript中存在几种用处呢?

    • 对象: 用于创建对象 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较难理解外,其他章节下功夫还是可以吃透的。

  • 相关阅读:
    Maria 与Ann的故事
    引语
    Preface
    Chapter 1 Foundation
    Roman to Integer
    Integer to Roman
    Container with most water
    palindrome number
    String to Integer (atoi)
    Reverse Integer
  • 原文地址:https://www.cnblogs.com/bigbrother1984/p/4338669.html
Copyright © 2011-2022 走看看