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