关于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 语句, 可以写为以下代码.


代码如下:

with(apple.banana.candy.dog.egg.fog.god.huh) {
c = 0;
doSomething(index);
}

看起来很美妙, 却存在致命的缺陷. 下面我们来进行一些小测试吧.

1. 在 with 语句内部通过内部变量修改数值


代码如下:

var root = {
branch: {
node: 1
}
};

with(root.branch) {
node = 0;
// 显示 0, 正确!
alert(node);
}
// 显示 0, 正确!
alert(root.branch.node);

2. 在 with 语句内部通过对象节点修改数值


代码如下:

var root = {
branch: {
node: 1
}
};

with(root.branch) {
root.branch.node = 0;
// 显示 0, 正确!
alert(node);
}
// 显示 0, 正确!
alert(root.branch.node);

经过测试 1 和测试 2, 乍看没什么问题, 但是... 请看测试 3.

3. 在 with 语句内部通过对象父节点修改数值


代码如下:

var root = {
branch: {
node: 1
}
};

with(root.branch) {
root.branch = {
node: 0
};
// 显示 1, 错误!
alert(node);
}
// 显示 0, 正确!
alert(root.branch.node);

由上面的测试 3 可知, with 语句内部的节点父节点修改后, 不会同步到节点本身. 也就是说, 不能保证内外数值的一致性. 这是可能成为项目里面隐藏性很高的 bug.
那我们该怎么办呢? 接受那很长的一串逐级访问, 还是另有他法?

方法是有的. 我们可以通过别名引用父节点的方式来调用节点对象, 如:


代码如下:

var root = {
branch: {
node: 1
}
};

var quote = root.branch;
quote.node = 0;
// 显示 0, 正确!
alert(root.branch.node);

我相信很少人会用 with 语句, 也不会有很多人知道这个关键字, 但我觉得这是个有问题的语句, 压根就不应该使用, 所以写个小文记录一下.

(0)

相关推荐

  • js string 转 int 注意的问题小结

    var str='1250' ; alert( Number(str) ); //得到1250 alert(parseInt(str)); //得到1250 var str1='00100'; alert( Number(str1) ); //得到100 alert(parseInt(str1)); //得到64 发现parseInt方法在format'00'开头的数字时会当作2进制转10进制的方法进行转换,所以建议string转int最好用Number方法

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

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

  • 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的替代方法与String中的正则方法详解

    with 语法 在代码中,要执行这么一个函数 function computeExpression(exp, scope) { try { with (scope) { return eval(exp); } } catch (e) { console.error('ERROR', e); } } 要求在scope 作用域中执行,什么意思??? 比如 scope = {a:10,b:5}; exp = a*b; 要求计算结果为15,这种情况,常规情况下要使用 with语法. 但是: js的解释器

  • js substring()字符串截取函数

    使用方法: 复制代码 代码如下: str.substring(start, end) "String Literal".substring(start, end) 其中"start"是指明要截取字符串的起始位置,该索引从0 开始起算."end"是指明要截取字符串的结束位置,该索引从0 开始起算. JavaScript中substring()函数方法将返回一个包含从start 到最后(不包含end )的子字符串的字符串. JavaScript中su

  • String字符串匹配javascript 正则表达式

    在JavaScript代码中使用正则表达式进行模式匹配经常会用到String对象和RegExp对象的一些方法,例如replace.match.search等方法,下面所述是对相关方法使用的总结,需要的朋友参考下. String对象中支持正则表达式有4种方法,分别是:search.replace.match.split str.search(regexp) 定义:search()方法将在字符串str中检索与表达式regexp相匹配的字串,并且返回第一个匹配字串的第一个字符的位置.如果没有找到任何匹

  • js中的string.format函数代码

    源于C#中的string.Format() 复制代码 代码如下: String.prototype.format = function(args) { if (arguments.length>0) { var result = this; if (arguments.length == 1 && typeof (args) == "object") { for (var key in args) { var reg=new RegExp ("({&qu

  • js的with语句使用方法

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

  • 理解javascript中的with关键字

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

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

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

随机推荐