|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 |
|
7 /** |
|
8 File Name: 12.10-1.js |
|
9 ECMA Section: 12.10 The with statement |
|
10 Description: |
|
11 WithStatement : |
|
12 with ( Expression ) Statement |
|
13 |
|
14 The with statement adds a computed object to the front of the scope chain |
|
15 of the current execution context, then executes a statement with this |
|
16 augmented scope chain, then restores the scope chain. |
|
17 |
|
18 Semantics |
|
19 |
|
20 The production WithStatement : with ( Expression ) Statement is evaluated |
|
21 as follows: |
|
22 1. Evaluate Expression. |
|
23 2. Call GetValue(Result(1)). |
|
24 3. Call ToObject(Result(2)). |
|
25 4. Add Result(3) to the front of the scope chain. |
|
26 5. Evaluate Statement using the augmented scope chain from step 4. |
|
27 6. Remove Result(3) from the front of the scope chain. |
|
28 7. Return Result(5). |
|
29 |
|
30 Discussion |
|
31 Note that no matter how control leaves the embedded Statement, whether |
|
32 normally or by some form of abrupt completion, the scope chain is always |
|
33 restored to its former state. |
|
34 |
|
35 Author: christine@netscape.com |
|
36 Date: 12 november 1997 |
|
37 */ |
|
38 |
|
39 var SECTION = "12.10-1"; |
|
40 var VERSION = "ECMA_1"; |
|
41 startTest(); |
|
42 var TITLE = "The with statement"; |
|
43 |
|
44 writeHeaderToLog( SECTION + " "+ TITLE); |
|
45 |
|
46 |
|
47 // although the scope chain changes, the this value is immutable for a given |
|
48 // execution context. |
|
49 |
|
50 new TestCase( SECTION, |
|
51 "with( new Number() ) { this +'' }", |
|
52 GLOBAL, |
|
53 eval("with( new Number() ) { this +'' }") ); |
|
54 |
|
55 // the object's functions and properties should override those of the |
|
56 // global object. |
|
57 |
|
58 new TestCase( |
|
59 SECTION, |
|
60 "var MYOB = new WithObject(true); with (MYOB) { parseInt() }", |
|
61 true, |
|
62 eval("var MYOB = new WithObject(true); with (MYOB) { parseInt() }") ); |
|
63 |
|
64 new TestCase( |
|
65 SECTION, |
|
66 "var MYOB = new WithObject(false); with (MYOB) { NaN }", |
|
67 false, |
|
68 eval("var MYOB = new WithObject(false); with (MYOB) { NaN }") ); |
|
69 |
|
70 new TestCase( |
|
71 SECTION, |
|
72 "var MYOB = new WithObject(NaN); with (MYOB) { Infinity }", |
|
73 Number.NaN, |
|
74 eval("var MYOB = new WithObject(NaN); with (MYOB) { Infinity }") ); |
|
75 |
|
76 new TestCase( |
|
77 SECTION, |
|
78 "var MYOB = new WithObject(false); with (MYOB) { }; Infinity", |
|
79 Number.POSITIVE_INFINITY, |
|
80 eval("var MYOB = new WithObject(false); with (MYOB) { }; Infinity") ); |
|
81 |
|
82 |
|
83 new TestCase( |
|
84 SECTION, |
|
85 "var MYOB = new WithObject(0); with (MYOB) { delete Infinity; Infinity }", |
|
86 Number.POSITIVE_INFINITY, |
|
87 eval("var MYOB = new WithObject(0); with (MYOB) { delete Infinity; Infinity }") ); |
|
88 |
|
89 // let us leave the with block via a break. |
|
90 |
|
91 new TestCase( |
|
92 SECTION, |
|
93 "var MYOB = new WithObject(0); while (true) { with (MYOB) { Infinity; break; } } Infinity", |
|
94 Number.POSITIVE_INFINITY, |
|
95 eval("var MYOB = new WithObject(0); while (true) { with (MYOB) { Infinity; break; } } Infinity") ); |
|
96 |
|
97 |
|
98 test(); |
|
99 |
|
100 function WithObject( value ) { |
|
101 this.prop1 = 1; |
|
102 this.prop2 = new Boolean(true); |
|
103 this.prop3 = "a string"; |
|
104 this.value = value; |
|
105 |
|
106 // now we will override global functions |
|
107 |
|
108 this.parseInt = new Function( "return this.value" ); |
|
109 this.NaN = value; |
|
110 this.Infinity = value; |
|
111 this.unescape = new Function( "return this.value" ); |
|
112 this.escape = new Function( "return this.value" ); |
|
113 this.eval = new Function( "return this.value" ); |
|
114 this.parseFloat = new Function( "return this.value" ); |
|
115 this.isNaN = new Function( "return this.value" ); |
|
116 this.isFinite = new Function( "return this.value" ); |
|
117 } |