JavaScript的strict模式与with关键字介绍


Posted in Javascript onFebruary 08, 2014

2009年12月,ECMAScript发布了ECMAScript 5,这距离上一个版本的ECMAScript 3标准发布已经整整十年了,其间JavaScript虽然大行于web编程,ECMAScript 4却最终因为利益相关的各大厂商和组织在此语言的复杂性(即是否增加大量特性以扩展ECMAScript的功能)上的分歧而夭折,使得ECMAScript新标准的制订大大落后于编程的实践。ECMAScript 5在目标上没有那么雄心勃勃,除去新增了对JSON的支持和反射的更全面的控制,一项重要改进就是引入“严格模式”(strict mode)。在此模式下,ECMAScript的语法变得更严格,使得原先许多常见的易致错的代码不再被允许,包括强制变量声明和不允许with语句等。采用这种模式很简单,只要在脚本文件或者函数的首行添加"use strict";这样一行字符串就可以了。

笔者后知,2010年还曾写了一篇小文讨论with关键字的缺陷,随附如下。
楔子

很久很久以前,神笔马良的家乡为了纪念他要将一条马路以他的名字命名。马良没有推辞,不过提出了四个字的意见。多年以后,一位外地人来到这里,在这条马路上拦住一个当地人问路。

请问这是神马路?

对,这是神马路。

你也不知道吗?

我就是这的人,怎么会不知道。

那这是神马路?

你知道了还问什么。

我就是不知道这是神马路。

那我不是已经告诉你这是神马路了吗?

你能不能再说一遍这是神马路?

……

过后,这个当地人想起当年神笔马良的意见,恍然大悟。马良说的是——勿用简称。

A Question

One day Tom said to Wang Er, his Chinese friend,“I have a dream. I want to show myself on CCTV.”The next day Tom broke into a neighbor shop. The police didn't take much time to identify and arrest Tom because he was captured very clearly by the shop's CCTV.

The question is when Tom said his dream, he is

A) ambitious B) not ambitious C)ambiguous D) unambiguous

The right answer is B) and C).
正文

以上两个古今中外的例子说明简写有时会引起歧义。这在Javascript中也存在。有时候要反复引用一个名字很长的变量是很麻烦的,比如:

objectWithLongName1.propty1=value1;

objectWithLongName1.propty2=value2;

objectWithLongName1.propty3=value3;

objectWithLongName1.method1();

但是一个清晰的名字对于程序的可读性又是很重要的。所以Javascript提供了with语句。上面的例子可以改写成:

with (objectWithLongName1){ propty1=value1; 
propty2=value2; 
propty3=value3; 
method1(); 
}

这样省去不少敲打键盘的功夫,而且程序的结构也变得更加清晰。但是这样的简写引入了歧义,我们如何知道大括号内的名称,哪些是objectWithLongName1的属性和方法,哪些是外部变量和函数。Javascript的解析规则是,先在objectWithLongName1上查找这些名称的属性,如果没有找到,则认为它们是外部变量。用代码说明就是这样:
if(objectWithLongName1.property1!==undefined){ if(objectWithLongName1.value1!==undefined){ 
objectWithLongName1.property1=objectWithLongName1.value1; //可能1 
}else{ 
objectWithLongName1.property1=value1;//可能2 
} 
}else{ 
if(objectWithLongName1.value1!==undefined){ 
property1=objectWithLongName1.value1; //可能3 
}else{ 
property1=value1;//可能4 
} 
}

我们希望的是这四种可能性之一,但是一不小心,程序执行的就会是另外一种可能。而且,这样的写法对于程序的读者来说也非常难解。另一方面,对于Javascript解释器,这种不确定性也影响了语言的性能。

其实只要一个小小的改进,就可以祛除这些缺陷。我们可以在省略了对象的属性前面加上点号,这样就在属性和外部变量之间加上了直观的区分,有不少其他语言就是这样做的。我们最初的例子会变成这样:

with (objectWithLongName1){ .propty1=value1; 
.propty2=value2; 
.propty3=value3; 
.method1(); 
}

在Javascript做这样的改进之前,两害相权取其轻,要尽量避免使用with语句。我们仍然可以采用一些变通的方法。
var o1= objectWithLongName1; o1.propty1=value1; 
o1.propty2=value2; 
o1.propty3=value3; 
o1.method1();

或者对于这样的情况:

objectWithLongName1.propty1= objectWithLongName2.propty1;

objectWithLongName1.propty2= objectWithLongName2.propty2;

……

objectWithLongName1.propty10= objectWithLongName2.propty10;

可以写成:

(function(o1, o2, pl){ pl.forEach(function(item){o1[item]=o2[item];}); 
})( objectWithLongName1,objectWithLongName2, [‘propty1', ‘propty2', … , ‘propty10']);
Javascript 相关文章推荐
PNG背景在不同浏览器下的应用
Jun 22 Javascript
JS操作数据库的实例代码
Oct 17 Javascript
js判断运行jsp页面的浏览器类型以及版本示例
Oct 30 Javascript
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
Dec 02 Javascript
分享20款美化网站的 jQuery Lightbox 灯箱插件
Oct 10 Javascript
js实现文本框宽度自适应文本宽度的方法
Aug 13 Javascript
JavaScript小技巧整理篇(非常全)
Jan 26 Javascript
JS奇技之利用scroll来监听resize详解
Jun 15 Javascript
jQueryMobile之窗体长内容的缺陷与解决方法实例分析
Sep 20 jQuery
利用JS hash制作单页Web应用的方法详解
Oct 10 Javascript
JS求1到任意数之间的所有质数的方法详解
May 20 Javascript
Node4-5静态资源服务器实战以及优化压缩文件实例内容
Aug 29 Javascript
jquery ajax 局部无刷新更新数据的实现案例
Feb 08 #Javascript
jquery ajax 局部刷新小案例
Feb 08 #Javascript
Jquery实现控件的隐藏和显示实例
Feb 08 #Javascript
二叉树的非递归后序遍历算法实例详解
Feb 07 #Javascript
Select标签下拉列表二级联动级联实例代码
Feb 07 #Javascript
javascript运行机制之this详细介绍
Feb 07 #Javascript
jQuery获取当前对象标签名称的方法
Feb 07 #Javascript
You might like
php 生成自动创建文件夹并上传文件的示例代码
2014/03/07 PHP
PHP获取网页标题的3种实现方法代码实例
2014/04/11 PHP
php定时执行任务设置详解
2015/02/06 PHP
php在linux环境中如何使用redis详解
2020/12/15 PHP
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
JS字符串截取函数实例
2013/12/27 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
2014/02/07 Javascript
jQuery 文本框得失焦点的简单实例
2014/02/19 Javascript
离开当前页面前使用js判断条件提示是否要离开页面
2014/05/02 Javascript
jQuery的几个我们必须了解的特点
2015/05/03 Javascript
js生成随机数的过程解析
2015/11/24 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
全面了解函数声明与函数表达式、变量提升
2016/08/09 Javascript
nodejs进阶(6)—连接MySQL数据库示例
2017/01/07 NodeJs
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
es6学习笔记之Async函数基本教程
2017/05/11 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
2018/11/05 Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
2019/02/18 Javascript
Vue实现验证码功能
2019/12/03 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
[05:06]TI4西雅图DOTA2前线报道 海涛密探LGD训练
2014/07/09 DOTA
Collatz 序列、逗号代码、字符图网格实例
2017/06/22 Python
Python基础之getpass模块详细介绍
2017/08/10 Python
动态规划之矩阵连乘问题Python实现方法
2017/11/27 Python
Python实现读取字符串按列分配后按行输出示例
2018/04/17 Python
对python 多线程中的守护线程与join的用法详解
2019/02/18 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
服务器端jupyter notebook映射到本地浏览器的操作
2020/04/14 Python
如何在vscode中安装python库的方法步骤
2021/01/06 Python
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
公开承诺书格式
2014/05/21 职场文书
协会周年庆活动方案
2014/08/26 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
幼儿园教学工作总结2015
2015/05/12 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
node.js如何自定义实现一个EventEmitter
2021/07/16 Javascript