Skip to content
2012 edited this page Jul 20, 2020 · 2 revisions

从入门以来,大家就一直说不要使用 eval 这邪恶的东西,然后我就信了(后面就没有去认真了解它),还是太年轻了;殊不知,这东西是非常好的东西,今天就来聊聊这“可恶”的东东;知己知彼,方能为我所用。

首先来了解一下,大家为啥这么反感 eval;

  • eval 作用域不明确
  • eval 接受并执行所传入的字符串,导致运行未知的代码,更重要的是,所传入的代码可以通过 eval 运行其他的脚本,导致受到攻击

参数

eval 只会对字符串进行解析执行并返回执行的结果,如果传入的参数不是字符串,那么不会做任何处理,原样返回; 例如:

var a1 = [1, 2, 3, 4];
var a2 = eval(a1); // non-string
a1 === a2;

var a3 = "2**3";
var a4 = eval(a3); // string
a4 === 8;

作用域

如果是直接调用 eval,作用域为 local;如果是间接调用,作用域为 global; 例如:

function test() {
  var x = 2,
    y = 4;
  console.log(eval("x + y")); // Direct call, uses local scope, result is 6
  var geval = eval; // equivalent to calling eval in the global scope
  console.log(geval("x + y")); // Indirect call, uses global scope, throws ReferenceError because `x` is undefined
  (0, eval)("x + y"); // another example of Indirect call
}

我还记得入门时对 eval 的使用仅限于解析 json 字符串转成对象,一定要加括号,不加就会报错;和JSON.parse解析报错的信息不一样;至今才知道,var obj = {a: 1}转换成字符串是这样"{"a": 1}";然后 eval 解析字符串时,会把字符串当做执行语句,当解析大括号({)时会被当做语句块;执行冒号(:)时就遇到语法错误。这和正常写代码{"a": 1}这样也会报错,要想解析成对象,需要加括号来表示里面不是一个语句块;

var obj = { a: 1 };
var str = JSON.stringify(obj);

eval("(" + str + ")") === { a: 1 };
// 等同于
JSON.parse(str);

JS

  1. 作用域
  2. 闭包
  3. 原型(链)
  4. 模块
  5. 位操作符
  6. 事件循环
  7. eval

CSS

  1. float
  2. BFC
  3. position
  4. flex
  5. grid

DOM

  1. DOM
  2. how browser works

Node.js

  1. Stream
  2. Timers
  3. Child Processes
  4. HTTP
  5. File System

react

  1. 生命周期
  2. setState
  3. hook

git

  1. git 基础命令
  2. git rebase 理解
  3. git bisect
  4. git commit
  5. git hook

设计模式

  1. 策略模式
  2. ...

TCP/IP 协议

  1. HTTP/1.x
  2. HTTP/2
  3. SSL/TLS
  4. TCP
  5. DNS
  6. HTTP Cache
  7. CORS
  8. http status code

linux(shell)知识点

  1. bashrc vs profile
  2. vim
  3. shell基本语法
  4. shell 知识误区
  5. shell命令
  6. 鸟哥的Linux私房菜:基础学习篇
  7. sudo vs su

Clone this wiki locally