
严格模式
- 不允许使用为声明的变量
复制代码
1
2
3
4
5
6
7
8
9
10"use strict"; x = 1; // 报错 (x 未定义) x = 1; // 不报错 fn(); function fn() { "use strict"; y = 1; // 报错 (y 未定义) }
- 不允许删除变量或对象、函数
复制代码
1
2
3
4
5
6
7"use strict"; var x = 1; delete x; // 报错 function fn(p1, p2) {}; delete fn; // 报错
- 不允许变量重名
在非严格模式下,后面的变量会覆盖前面的变量。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12"use strict"; function fn(arg, arg) {}; // 报错 // 下面不会报错 var a = 1 function fn1() { var a = 2 console.log(a); } fn1();
- 不允许使用八进制
复制代码
1
2
3"use strict"; var x = 010; // 报错
- 不允许使用转义字符
复制代码
1
2
3"use strict"; var x = 010; // 报错
- 不允许对只读属性赋值
复制代码
1
2
3
4
5var obj = {}; Object.defineProperty(obj, "x", {value:0, writable:false}); obj.x = 1; // 报错
- 不允许对一个使用getter方法读取的属性进行赋值
复制代码
1
2
3
4
5"use strict"; var obj = {get x() {return 0} }; obj.x = 1; // 报错
- 不允许删除一个不允许删除的属性
复制代码
1
2
3"use strict"; delete Object.prototype; // 报错
- 变量名不能使用 "eval", "arguments" 字符串
复制代码
1
2
3
4"use strict"; var eval = 1; // 报错 var arguments = 1; // 报错
- 不能使用with语句
复制代码
1
2
3"use strict"; with (Math){x = cos(2)}; // 报错
- 在作用域 eval() 创建的变量不能被调用
复制代码
1
2
3
4"use strict"; eval ("var x = 1"); alert (x); // 报错
- 函数在浏览器全局环境中被简单调用,非严格模式下
this
指向window
;在use strict
指明严格模式的情况下就是undefined
复制代码
1
2
3
4
5
6
7
8
9
10"use strict"; function test() { console.log(this); } test(); // undefined
eval
eval()
是全局对象的一个函数属性, 参数是一个字符串表示的表达式,eval()
会对表达式进行求值。如果参数字符串表示一个或多个 JavaScript 语句,那么eval()
就会执行这些语句,如果eval()
的参数不是字符串,eval()
会将参数原封不动地返回
如:
复制代码
1
2
3
4
5// 参数不是字符串 eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象 // 参数为字符串 eval("2 + 2"); // returns 4
如果你间接的使用 eval()
,比如通过一个引用来调用它,而不是直接的调用 eval
。 从 ECMAScript 5 起,它工作在全局作用域下,而不是局部作用域中
复制代码
1
2
3
4
5
6
7
8
9function 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上例子有点问题, 同理,字符串函数也需要加 ()
包裹
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14function 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 性能测试
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38(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

仅仅多执行了一行代码,执行效率低了很多。
为什么eval这么慢?
JavaScript 引擎会在编译阶段进行数项的性能优化。其中有些优化依赖于能够根据代码的词法进行静态分析(LHS & RHS),并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。但如果引擎在代码中发现了 eval(..)
,它只能简单地假设关于标识符位置的判断都是无效的,因为无法在词法分析阶段明确知eval(..)
会接收到什么代码,这些代码会如何对作用域进行修改。浏览器被迫进行高代价的查找分析作用域中的代码,之前浏览器所有的优化可能都是无意义的。导致代码执行效率低下。
参考文档
- MDN文档Eval
最后
以上就是务实绿草最近收集整理的关于ie vue白屏eval无效字符_严格模式和Eval的全部内容,更多相关ie内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复