ie vue白屏eval无效字符_严格模式和Eval

ddf4052aac650824d9f6938843aa9ce4.png

严格模式

  • 不允许使用为声明的变量
"use strict";
x = 1;                // 报错 (x 未定义)
x = 1;       // 不报错
fn();

function fn() {
   "use strict";
    y = 1;   // 报错 (y 未定义)
}
  • 不允许删除变量或对象、函数
"use strict";
var x = 1;
delete x;                // 报错

function fn(p1, p2) {};
delete fn;                // 报错
  • 不允许变量重名

在非严格模式下,后面的变量会覆盖前面的变量。

"use strict";
function fn(arg, arg) {};   // 报错

// 下面不会报错
var a = 1
function fn1() {
  var a = 2
  console.log(a);
}

fn1();
  • 不允许使用八进制
"use strict";
var x = 010;             // 报错
  • 不允许使用转义字符
"use strict";
var x = 010;            // 报错
  • 不允许对只读属性赋值
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});

obj.x = 1;            // 报错
  • 不允许对一个使用getter方法读取的属性进行赋值
"use strict";
var obj = {get x() {return 0} };

obj.x = 1;            // 报错
  • 不允许删除一个不允许删除的属性
"use strict";
delete Object.prototype; // 报错
  • 变量名不能使用 "eval", "arguments" 字符串
"use strict";
var eval = 1;         // 报错
var arguments = 1;    // 报错
  • 不能使用with语句
"use strict";
with (Math){x = cos(2)}; // 报错
  • 在作用域 eval() 创建的变量不能被调用
"use strict";
eval ("var x = 1");
alert (x);               // 报错
  • 函数在浏览器全局环境中被简单调用,非严格模式下 this 指向 window;在 use strict 指明严格模式的情况下就是 undefined
"use strict";

function test() {
  console.log(this);
}

test();

// undefined

eval

eval() 是全局对象的一个函数属性, 参数是一个字符串表示的表达式, eval() 会对表达式进行求值。如果参数字符串表示一个或多个 JavaScript 语句,那么 eval() 就会执行这些语句,如果 eval() 的参数不是字符串, eval() 会将参数原封不动地返回

如:

// 参数不是字符串
eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象
// 参数为字符串
eval("2 + 2");             // returns 4

如果你间接的使用 eval(),比如通过一个引用来调用它,而不是直接的调用 eval。 从 ECMAScript 5 起,它工作在全局作用域下,而不是局部作用域中

function test() {
  var x = 2, y = 4;
  console.log(eval('x + y'));  // 直接调用,使用本地作用域,结果是 6

  var geval = eval; // 等价于在全局作用域调用
  console.log(geval('x + y')); // 间接调用,使用全局作用域,throws ReferenceError 因为`x`未定义
  (0, eval)('x + y'); // 另一个间接调用的例子, 同样报错
}

其他相关例子在 MDN 上也可以看到,不做深究。值得注意的是将字符串解析为json的时候得加 () ,MDN上例子有点问题, 同理,字符串函数也需要加 () 包裹

function looseJsonParse(obj){
    return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
  // 使用eval来解析JSON格式字符串的时候,会将{}解析为代码块,而不是对象的字面量,所有需要()
   "({a:(4-1), b:function(){}, c:new Date()})"
))


var fctStr1 = 'function a() {}'
var fctStr2 = '(function a() {})'
var fct1 = eval(fctStr1)  // 返回undefined
var fct2 = eval(fctStr2)  // 返回一个函数

Eval 性能测试

(function(){
  var i,t=new Date;
  for(i=0;i<1E9;i++);
  console.log("正常环境:"+(new Date-t));
})();

(function(){
  eval("");
  var i,t=new Date;
  for(i=0;i<1E9;i++);
  console.log("eval影响:"+(new Date-t));
})();

(function(){
  "use strict";
  eval("");
  var i,t=new Date;
  for(i=0;i<1E9;i++);
  console.log("严格模式eval影响:"+(new Date-t));
})();

(function(){
  (function(){
    "use strict";
    eval("");
  })();
  (function(){
    var i,t=new Date;
    for(i=0;i<1E9;i++);
    console.log("完全隔离的严格模式eval影响:"+(new Date-t));
  })();
})();

// 正常环境:573
// eval影响:2145
// 严格模式eval影响:2129
// 完全隔离的严格模式eval影响:574

f04c5aacab004850cecfafdf618a8ee4.png
执行结果

仅仅多执行了一行代码,执行效率低了很多。

为什么eval这么慢?

JavaScript 引擎会在编译阶段进行数项的性能优化。其中有些优化依赖于能够根据代码的词法进行静态分析(LHS & RHS),并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。但如果引擎在代码中发现了 eval(..) ,它只能简单地假设关于标识符位置的判断都是无效的,因为无法在词法分析阶段明确知eval(..) 会接收到什么代码,这些代码会如何对作用域进行修改。浏览器被迫进行高代价的查找分析作用域中的代码,之前浏览器所有的优化可能都是无意义的。导致代码执行效率低下。

参考文档

  • MDN文档Eval
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值