1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/ecma_3/Function/scope-001.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * Date: 28 May 2001 1.11 + * 1.12 + * SUMMARY: Functions are scoped statically, not dynamically 1.13 + * 1.14 + * See ECMA Section 10.1.4 Scope Chain and Identifier Resolution 1.15 + * (This section defines the scope chain of an execution context) 1.16 + * 1.17 + * See ECMA Section 12.10 The with Statement 1.18 + * 1.19 + * See ECMA Section 13 Function Definition 1.20 + * (This section defines the scope chain of a function object as that 1.21 + * of the running execution context when the function was declared) 1.22 + */ 1.23 +//----------------------------------------------------------------------------- 1.24 +var UBound = 0; 1.25 +var BUGNUMBER = '(none)'; 1.26 +var summary = 'Testing that functions are scoped statically, not dynamically'; 1.27 +var self = this; // capture a reference to the global object 1.28 +var status = ''; 1.29 +var statusitems = [ ]; 1.30 +var actual = ''; 1.31 +var actualvalues = [ ]; 1.32 +var expect= ''; 1.33 +var expectedvalues = [ ]; 1.34 + 1.35 +/* 1.36 + * In this section the expected value is 1, not 2. 1.37 + * 1.38 + * Why? f captures its scope chain from when it's declared, and imposes that chain 1.39 + * when it's executed. In other words, f's scope chain is from when it was compiled. 1.40 + * Since f is a top-level function, this is the global object only. Hence 'a' resolves to 1. 1.41 + */ 1.42 +status = 'Section A of test'; 1.43 +var a = 1; 1.44 +function f() 1.45 +{ 1.46 + return a; 1.47 +} 1.48 +var obj = {a:2}; 1.49 +with (obj) 1.50 +{ 1.51 + actual = f(); 1.52 +} 1.53 +expect = 1; 1.54 +addThis(); 1.55 + 1.56 + 1.57 +/* 1.58 + * In this section the expected value is 2, not 1. That is because here 1.59 + * f's associated scope chain now includes 'obj' before the global object. 1.60 + */ 1.61 +status = 'Section B of test'; 1.62 +var a = 1; 1.63 +var obj = {a:2}; 1.64 +with (obj) 1.65 +{ 1.66 + function f() 1.67 + { 1.68 + return a; 1.69 + } 1.70 + actual = f(); 1.71 +} 1.72 +expect = 2; 1.73 +addThis(); 1.74 + 1.75 + 1.76 +/* 1.77 + * Like Section B , except that we call f outside the with block. 1.78 + * By the principles explained above, we still expect 2 - 1.79 + */ 1.80 +status = 'Section C of test'; 1.81 +var a = 1; 1.82 +var obj = {a:2}; 1.83 +with (obj) 1.84 +{ 1.85 + function f() 1.86 + { 1.87 + return a; 1.88 + } 1.89 +} 1.90 +actual = f(); 1.91 +expect = 2; 1.92 +addThis(); 1.93 + 1.94 + 1.95 +/* 1.96 + * Like Section C, but with one more level of indirection - 1.97 + */ 1.98 +status = 'Section D of test'; 1.99 +var a = 1; 1.100 +var obj = {a:2, obj:{a:3}}; 1.101 +with (obj) 1.102 +{ 1.103 + with (obj) 1.104 + { 1.105 + function f() 1.106 + { 1.107 + return a; 1.108 + } 1.109 + } 1.110 +} 1.111 +actual = f(); 1.112 +expect = 3; 1.113 +addThis(); 1.114 + 1.115 + 1.116 +/* 1.117 + * Like Section C, but here we actually delete obj before calling f. 1.118 + * We still expect 2 - 1.119 + */ 1.120 +status = 'Section E of test'; 1.121 +var a = 1; 1.122 +var obj = {a:2}; 1.123 +with (obj) 1.124 +{ 1.125 + function f() 1.126 + { 1.127 + return a; 1.128 + } 1.129 +} 1.130 +delete obj; 1.131 +actual = f(); 1.132 +expect = 2; 1.133 +addThis(); 1.134 + 1.135 + 1.136 +/* 1.137 + * Like Section E. Here we redefine obj and call f under with (obj) - 1.138 + * We still expect 2 - 1.139 + */ 1.140 +status = 'Section F of test'; 1.141 +var a = 1; 1.142 +var obj = {a:2}; 1.143 +with (obj) 1.144 +{ 1.145 + function f() 1.146 + { 1.147 + return a; 1.148 + } 1.149 +} 1.150 +delete obj; 1.151 +var obj = {a:3}; 1.152 +with (obj) 1.153 +{ 1.154 + actual = f(); 1.155 +} 1.156 +expect = 2; // NOT 3 !!! 1.157 +addThis(); 1.158 + 1.159 + 1.160 +/* 1.161 + * Explicitly verify that f exists at global level, even though 1.162 + * it was defined under the with(obj) block - 1.163 + */ 1.164 +status = 'Section G of test'; 1.165 +var a = 1; 1.166 +var obj = {a:2}; 1.167 +with (obj) 1.168 +{ 1.169 + function f() 1.170 + { 1.171 + return a; 1.172 + } 1.173 +} 1.174 +actual = String([obj.hasOwnProperty('f'), self.hasOwnProperty('f')]); 1.175 +expect = String([false, true]); 1.176 +addThis(); 1.177 + 1.178 + 1.179 +/* 1.180 + * Explicitly verify that f exists at global level, even though 1.181 + * it was defined under the with(obj) block - 1.182 + */ 1.183 +status = 'Section H of test'; 1.184 +var a = 1; 1.185 +var obj = {a:2}; 1.186 +with (obj) 1.187 +{ 1.188 + function f() 1.189 + { 1.190 + return a; 1.191 + } 1.192 +} 1.193 +actual = String(['f' in obj, 'f' in self]); 1.194 +expect = String([false, true]); 1.195 +addThis(); 1.196 + 1.197 + 1.198 + 1.199 +//------------------------------------------------------------------------------------------------- 1.200 +test(); 1.201 +//------------------------------------------------------------------------------------------------- 1.202 + 1.203 + 1.204 +function addThis() 1.205 +{ 1.206 + statusitems[UBound] = status; 1.207 + actualvalues[UBound] = actual; 1.208 + expectedvalues[UBound] = expect; 1.209 + UBound++; 1.210 + resetTestVars(); 1.211 +} 1.212 + 1.213 + 1.214 +function resetTestVars() 1.215 +{ 1.216 + delete a; 1.217 + delete obj; 1.218 + delete f; 1.219 +} 1.220 + 1.221 + 1.222 +function test() 1.223 +{ 1.224 + enterFunc ('test'); 1.225 + printBugNumber(BUGNUMBER); 1.226 + printStatus (summary); 1.227 + 1.228 + for (var i = 0; i < UBound; i++) 1.229 + { 1.230 + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); 1.231 + } 1.232 + 1.233 + exitFunc ('test'); 1.234 +}