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

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']);

(0)

相关推荐

  • javascript简单事件处理和with用法介绍

    这一期介绍一些简单的事件处理: 1.鼠标点击 复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> New Document </title> <meta name="Gene

  • 理解javascript中的with关键字

    说起js中的with关键字,很多小伙伴们的第一印象可能就是with关键字的作用在于改变作用域,然后最关键的一点是不推荐使用with关键字.听到不推荐with关键字后,我们很多人都会忽略掉with关键字,认为不要去管它用它就可以了.但是有时候,我们在看一些代码或者面试题的时候,其中会有with关键字的相关问题,很多坑是你没接触过的,所以还是有必要说说with这一个关键字. 一.基本说明 在js高级程序设计中是这样描述with关键字的:with语句的作用是将代码的作用域设置到一个特定的作用域中,基本

  • js的with语句使用方法

    1)简要说明         with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性.要给对象创建新的属性,必须明确地引用该对象. 2)语法格式  with(object instance)  {          //代码块  }         有时候,我在一个程序代码中,多次需要使用某对象的属性或方法,照以前的写法,都是通过:对象.属性或者对象.方法这样的方式来分别获得该对象的属性和方法,着实有点麻烦,学习了with语句后,可以通过类似如下的方式来实现:  w

  • Javascript中With语句用法实例

    本文实例讲述了Javascript中With语句用法.分享给大家供大家参考.具体如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>With语句(类似于VB中的)</title>

  • 深入浅析JavaScript中with语句的理解

    JavaScript 有个 with 关键字, with 语句的原本用意是为逐级的对象访问提供命名空间式的速写方式. 也就是在指定的代码区域, 直接通过节点名称调用对象. with语句的作用是暂时改变作用域链.减少的重复输入. 其语法结构为: with(object){ //statements } 举一个实际例子吧: with(document.forms[]){ name.value = "lee king"; address.value = "Peking";

  • JavaScript严格模式禁用With语句的原因

    看了很多遍JavaScript严格模式,其中有说"禁用With语句",以前看到这都是骑马观花,一带而过,因为平时就很少用到这个语句,禁不禁用对自己关系都不是很大.今天禁不住想知道为何"严格模式"就容不下with语句呢? EcmaScript规范上说"with 语句用于设置代码在特定对象中的作用域",可以看出,With语句改变了作用域链. function Person(name,age,sex){ this.name = name; this.a

  • javascript中with()方法的语法格式及使用

    内容导读: 有了 With 语句,在存取对象属性和方法时就不用重复指定参考对象,在 With 语句块中,凡是 JavaScript 不识别的属性和方法都和该语句块指定的对象有关.With 语句的语法格式如下所示: With Object { Statements } 对象指明了当语句组中对象缺省时的参考对象,这里我们用较为熟悉的 Document 对象对 With 语句举例.例如 当使用与 Document 对象有关的 write( )或 writeln( )方法时,往往使用如下形式: docu

  • javascript之with的使用(阿里云、淘宝使用代码分析)

    记得还在懵懂学习JavaScript基础之时,坊间便有传言"with语句是低效率语句,若非必要,请不要使用该语句",同时, ECMAScript 5 的strict mode下是禁止使用with语句的,所以一直以来我对with语句一直没啥好感. 今天在知乎有个话题大概说的是"你觉得什么东西相当有B格"之类的,然后就有人贴了这段代码: with(document)with(body)with(insertBefore(createElement("scrip

  • 在js中使用"with"语句中跨frame的变量引用问题

    在脚本编程时使用with语句,可以大大的缩减使用多级对象引用代码行的长度,这是JScript提供给我们的一个Syntax Sugar.当然不使用with,使用临时变量也可以达到同样的效果.不过创建变量时起名确实不是一件很遐意的事,就连MASM高版本中也提供了一个@@(以及@F和@B)来处理临时标号的问题,看来大家都是比较懒得啦. 我也挺喜欢用with语句的,确实可以省不少的事情,而且可以让代码变得也清晰些,特别是在处理跨frame的变量引用时,更加显得方便.这不今天就因为贪图方便又撞到枪口上了,

  • 关于JavaScript的with 语句的使用方法

    用过 Java 和 .NET 的同学对包或命名空间的概念应该不会陌生, 正因为有这个概念, 使代码的简洁易读得到了保证. 不知 JavaScript 设计之初是如何定位 with 语句的, 个人觉得它们之间有一定的相似度. 如: 复制代码 代码如下: apple.banana.candy.dog.egg.fog.god.huh.index = 0; doSomething(apple.banana.candy.dog.egg.fog.god.huh.index); 利用 with 语句, 可以写

  • javascript下with 的简化代码写法

    with (object) statements 参数 object 新的默认对象. statements 一个或多个语句,object 是该语句的默认对象. 说明 with 语句通常用来缩短特定情形下必须写的代码量.在下面的例子中,请注意 Math 的重复使用: x = Math.cos(3 * Math.PI) + Math.sin(Math.LN10) y = Math.tan(14 * Math.E) 当使用 with 语句时,代码变得更短且更易读: 复制代码 代码如下: with (M

  • js批量设置样式的三种方法不推荐使用with

    一般我们都用css来批量设置样式,现在我们用js也可以批量设置样式: 总结三种方法如下 复制代码 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <style type="text/css"> #div1{

  • javaScript中with函数用法实例分析

    本文实例讲述了javaScript中with函数用法.分享给大家供大家参考.具体分析如下: javaScript 中的 with 函数 ,即所谓的with 语句,可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性,要给对象创建新的属性,必须明确地引用该对象. with 函数,为语句设定默认对象. with (object)   statements 参数: object 新的默认对象. statements 一个或多个语句,object 是该语句的默认对象. 说明: with

  • JavaScript学习小结之被嫌弃的eval函数和with语句实例详解

    前面的话 eval和with经常被嫌弃,好像它们的存在就是错误.在CSS中,表格被嫌弃,在网页中只是用表格来展示数据,而不是做布局,都可能被斥为不规范,矫枉过正.那关于eval和with到底是什么情况呢?本文将详细介绍eval()函数和with语句 eval 定义 eval()是一个全局函数,javascript通过eval()来解释运行由javascript源代码组成的字符串 var result = eval('3+2'); console.log(result,typeof result)

随机推荐