with
作用域只有全局作用域和函数作用域(块作用域暂时不提及), 使用with后有一个单独的作用域。不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源。
var message = "hello";
var obj = {
name: "malong",
message:"malong obj"
}
// 使用with 后会形成一个单独的作用域
with(obj) {
console.log(message) //会打印 malong obj
}
eval
eval是一个特殊的函数,它可以将传入的字符串当做JavaScript代码来运行。
var str = ' var msg = "test"; console.log("malong" + msg)'
eval(str)
- 不建议在开发中使用eval
- 可读性很差
- 存在安全问题,eval是一个字符串,在执行的过程中如果被恶意篡改,会造成安全问题
- eval的执行必须经过JS解释器,不能被JS引擎优化
严格模式 ues strict
严格模式很好理解,是一种具有限制性的JavaScript模式,从而使代码隐式的脱离了 ”懒散(sloppy)模式“。支持严格模式的浏览器在检测到代码中有严格模式时,会以更加严格的方式对代码进行检测和执行;
- 严格模式分类
- 全局严格
- 局部严格
- 严格模式的好处
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 严格模式对JavaScript语义进行了一些限制
- 严格模式通过抛出错误来消除一些原有的静默(silent)错误
- 严格模式让JS引擎在执行代码的时候得到更多的优化(不需要对特殊的代码进行处理)
- 严格模式禁用了在ECMAScript未来版本中可能会定义的一些语法
- 严格模式具体的一些限制
-
- 无法意外的创建全局变量
-
- 严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常
-
- 严格模式下试图删除不可删除的属性
-
- 严格模式不允许函数参数有相同的名称
-
- 不允许0的八进制语法
-
- 在严格模式下,不允许使用with
-
- 在严格模式下,eval不再为上层引用变量
-
- 严格模式下,this绑定不会默认转成对象
- 严格模式下,setTimeout中的this还是指向window,这跟浏览器有关,有想研究的可以看一下浏览器源码,文件很大。而且对于我们来说,setTimeout是怎么执行的我们也不知道,这种我们称为黑盒子,但是其实我的猜想是通过apply调用触发的函数的自执行。
-
"use strict"
// 1. 无法意外的创建全局变量 (通过 抛出错误 来消除一些原有的 静默(silent)错误)
//str = "strict";
//console.log(str); // 如果不使用严格模式 , 是不会报错的
// 2.严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常 (通过 抛出错误 来消除一些原有的 静默(silent)错误)
// true.name = "abc"
// NaN = 123
// var obj = {}
// Object.defineProperty(obj, "name", {
// configurable: false,
// writable: false,
// value: "why"
// })
// console.log(obj.name)
// obj.name = "kobe"
// 3. 严格模式不允许使用 0的八进制语法
// var num = 0123; // 要使用0o来表示八进制
// console.log(num)
// 4.严格模式试图删除不可删除的属性会报错
// var obj = {
// name: 'zhangsan'
// }
// Object.defineProperty(obj, 'name', {
// configurable: false,
// })
// delete obj.name
// console.log(obj)
// 5.严格模式不允许函数参数有相同的名称
// function test(x, y, x) {
// console.log(x, y) // 如果没有严格模式 会打印 30 20 30 前面的x会被覆盖
// }
// test(10, 20, 30)
// 6.严格模式下不能使用with
// var name = "zhangsan"
// var obj = { name: "zhangsan" }
// with (obj) {
// console.log(name)
// }
// 7. 在严格模式下,eval不再为上层引用变量
// var str = 'var msg = "test strict"; console.log(msg)';
// eval(str)
// console.log(msg) //报错 无法引用
// 8. 严格模式下,this绑定不会默认转成对象 会指向window
// 在严格模式下, 自执行函数(默认绑定)会指向undefined
// 有两个情况比较特殊 拿出来对比 指向window
// setTimeout(() => {
// console.log(this)
// }, 100)
// setTimeout(function () {
// console.log(this)
// }, 200)