JavaScript严格模式禁用With语句的原因
本文解析JavaScript严格模式禁用With语句的根本原因。With语句会动态改变作用域链,导致变量属性在编译阶段无法确定,必须在运行时才能解析。这与严格模式要求在编译期进行变量定义检查的机制发生冲突,因此严格模式直接禁止该语句以避免歧义。
严格模式对With语句的限制
在研读JavaScript严格模式时,常会注意到“禁用With语句”这一规定。由于日常开发中较少使用此语句,其是否被禁用对代码影响不大,因此往往被忽略。然而,不禁让人好奇:为何严格模式对With语句如此排斥?
根据EcmaScript规范,With语句的作用是设置代码在特定对象中的作用域。这表明With语句会改变原有的作用域链结构。
With语句的作用域机制
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
(function(){
var title = '申请人:';
var zhangsan = new Person('张三',20,'男');
var str = '';
with(zhangsan){
str = title+name+',年龄'+age+'岁,'+sex+'性'+',职位'+job;
}
console.log(str);
})();
执行上述代码时,会抛出Uncaught ReferenceError: job is not defined错误。
若将上述With语句块修改为以下形式:
str = title+zhangsan.name+',年龄'+zhangsan.age+'岁,'+zhangsan.sex+'性'+',职位'+zhangsan.job;
此时代码不再报错,输出str的结果为:申请人:张三,年龄20岁,男性,职位undefined。
在With语句块内部,所有变量在执行时都会优先在zhangsan对象中查找其属性。
编译期与运行时的冲突
脚本运行包含编译和执行两个阶段。在编译阶段,无法确定zhangsan变量所指向的对象具体包含哪些属性,只有在运行时才能确认zhangsan是Person类的实例。因此,编译器无法在编译时判定With块内的变量究竟是zhangsan的属性,还是上一层作用域链中的变量。
这种动态解析机制与严格模式要求在编译期检查变量是否已定义的规则相冲突。由于严格模式不允许这种不确定性存在,因此禁止With语句的使用也就顺理成章了。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
