with
拥有作用域,会先从传入的变量中查找,一般不用在开发中,因为会混淆错误和兼容性问题的根源。
eval
是一个全局函数,可以将传入的字符串转为JS代码来运行。
- 代码可读性差
- 存在安全隐患
- 执行必须经过JS解释器,不能被JS引擎优化
var codes = "var message = 'hello';console.log(message);"
eval(codes)
strict
严格模式的概念
在非严格模式下不报错的语句,开启严格模式就会报错
-
严格模式是一种具有限制性的JavaScript模式,从而使代码隐式的脱离了“懒散(sloppy)模式”;
-
支持严格模式的浏览器在检测到代码中有严格模式时,会以更加严格的方式对代码进行检测和执行; 严格模式对正常的JS语义的进行一些限制
-
会抛出错误来消除一些原有的静默错误;
-
会让JS引擎在执行代码时可以进行更多的优化;
-
在ECMAScript未来版本中可能会定义的一些语法;
开启严格模式
可以给单个JS文件开启严格模式:
"use strict";
也支持对某个函数开启严格模式:
function foo(){
"use strict";
}
常见限制
- 禁止意外创建全局变量
// "use strict"
message = "hello" // 未定义
console.log(message)
function foo(){
age = 20
}
foo()
console.log(age) // 意外在函数内创建全局变量
- 不允许函数有相同的参数名称
// "use strict"
function foo(x,y,x){
console.log(x,y,x)
}
foo(10,20,30)
- 静默错误 console
// "use strict"
true.name = "abc"
NaN = 123
var obj = {}
Object.defineProperty(obj,"name",{
writable: false,
value: "why"
})
console.log(obj.name)
obj.name = "yyy"
- 不允许使用原先的八进制格式
// "use strict"
var num = 0123 // 八进制(但0o123是允许的)
// var num2 = 0x123 // 十六进制
// var num3 = 0b100 // 二进制
console.log(num,num2,num3)
- with语句不允许使用
- eval函数不会向上引用变量了
var codes = "'use strict';var message = 'hello';console.log(message);"
eval(codes)
console.log(message) // 开启严格模式后message就不会被引用
- eval函数不会向上引用变量了
// "use strict"
// 在严格模式下,自执行函数(认绑定)会指向 undefined
// 之前编写的代码中,自执行函数我们门是没有使用过this直接去引用 window
function foo(){
console.log(this)
}
foo()
var obj = {
name:"why",
foo: foo
}
obj.foo()
var bar = obj.foo
bar()
setTimeout(()=>{
console.log(this)
},1000)
// 在非严格模式和严格模式下绑定的都是windows
setTimeout(function(){
console.log(this)
},1000)