with 语句

 with 语句是在需要省略 .(点) 运算符左侧的操作对象时指定被省略的操作对象的语句。

 本语句的语法如下。

with(expression)
    语句或代码段


 指定的「语句或代码段」中,如果存在左侧被省略的 .(点) 运算符,则将以 with 语句 expresssion 中指定的对象作为该.(点) 运算符的左侧对象。


例:
    with(obj) .member = 1; // 和 obj.member = 1; 相同

    with(obj)
    {
        .member1 = 1; // 将 1 赋值给 obj.member1 
        .member2 = 2; // 将 1 赋值给 obj.member2 
        .member3++; // 让 obj.member3 自增 1
        .method(); // 调用 obj.method 
    }


 本语句在需要大量设定对象属性,或者连续调用对象的方法的时候,可以大幅减少需要键入的代码的数量。

 例如:


    var object = new Foo();
    object.setPos(0, 0);
    object.setSize(100, 100);
    object.name = "未命名";
    object.color = 0xffffffff;


 这样的脚本可以用以下的方式来编写。


    var object = new Foo();
    with(object)
    {
        .setPos(0, 0);
        .setSize(100, 100);
        .name = "未命名";
        .color = 0xffffffff;
    }


with 语句与对象

 with 调用语句所指定的 expression 将只在最初执行 with 的时候被执行求值,此后都只是对其结果进行饮用。

 例如说


this.dic = %[];
with(this.dic)
{
    .member = 1; // 将 1 赋值给 this.dic.member
    this.dic = 0; // 将 dic 修改成别的东西
    .member = 2; // 将 2 赋值给this.dic.member
}


 虽然this.dic在过程中变化了,但是第二次对 .member 的赋值操作依然被成功进行。这是因为 with 在最初执行的时候就对 this.dic 这个表达式进行了求值,之后只是使用求值结果所得到的对象,而并不是每一次都对 this.dic 这个表达式重新求值。

 由于求值操作只在最初的一次被执行,之后的操作都只是对对象进行引用,所以不必为了得到引用对象而经常执行相关代码,在有些情况下可以得到比较大的性能优化。

 上面的例子可以理解为生成了以下代码。


this.dic = %[];
{
    var 未命名的特殊本地变量 = this.dic;
    未命名的特殊本地变量.member = 1;
    this.dic = 0;
    未命名的特殊本地变量.member = 2;
}


 with 语句将会把对 expression 的表达式求值结果代入一个未命名的特殊本地变量,这个变量只有左侧被省略的 . (点) 运算符才能够访问。以后,所有左侧被省略的 . (点) 运算符都会被看作引用这个“未命名的特殊本地变量”。
 对 expression 求值的结果所保持的作用域,也可以看作和上文“未命名的特殊本地变量”的本地变量作用域相同。 ( 这也是 with 语句能够影响的作用域 )。

with 语句外的 . 运算符

 with 语句之外出现左侧被省略的 . (点) 运算符,则将被当作左侧引用了全局( global )对象。
 例如,在 with 语句外编写

.foo = 1;

 这样的语句,则该语句的效果和

global.foo = 1;

 相同。