js/src/tests/ecma_3/Function/scope-002.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 * Date: 28 May 2001
michael@0 8 *
michael@0 9 * SUMMARY: Functions are scoped statically, not dynamically
michael@0 10 *
michael@0 11 * See ECMA Section 10.1.4 Scope Chain and Identifier Resolution
michael@0 12 * (This section defines the scope chain of an execution context)
michael@0 13 *
michael@0 14 * See ECMA Section 12.10 The with Statement
michael@0 15 *
michael@0 16 * See ECMA Section 13 Function Definition
michael@0 17 * (This section defines the scope chain of a function object as that
michael@0 18 * of the running execution context when the function was declared)
michael@0 19 *
michael@0 20 * Like scope-001.js, but using assignment var f = function expression
michael@0 21 * instead of a function declaration: function f() {} etc.
michael@0 22 */
michael@0 23 //-----------------------------------------------------------------------------
michael@0 24 var UBound = 0;
michael@0 25 var BUGNUMBER = '(none)';
michael@0 26 var summary = 'Testing that functions are scoped statically, not dynamically';
michael@0 27 var self = this; // capture a reference to the global object
michael@0 28 var status = '';
michael@0 29 var statusitems = [ ];
michael@0 30 var actual = '';
michael@0 31 var actualvalues = [ ];
michael@0 32 var expect= '';
michael@0 33 var expectedvalues = [ ];
michael@0 34
michael@0 35
michael@0 36 /*
michael@0 37 * In this section the expected value is 1, not 2.
michael@0 38 *
michael@0 39 * Why? f captures its scope chain from when it's declared, and imposes that chain
michael@0 40 * when it's executed. In other words, f's scope chain is from when it was compiled.
michael@0 41 * Since f is a top-level function, this is the global object only. Hence 'a' resolves to 1.
michael@0 42 */
michael@0 43 status = 'Section A of test';
michael@0 44 var a = 1;
michael@0 45 var f = function () {return a;};
michael@0 46 var obj = {a:2};
michael@0 47 with (obj)
michael@0 48 {
michael@0 49 actual = f();
michael@0 50 }
michael@0 51 expect = 1;
michael@0 52 addThis();
michael@0 53
michael@0 54
michael@0 55 /*
michael@0 56 * In this section the expected value is 2, not 1. That is because here
michael@0 57 * f's associated scope chain now includes 'obj' before the global object.
michael@0 58 */
michael@0 59 status = 'Section B of test';
michael@0 60 var a = 1;
michael@0 61 var obj = {a:2};
michael@0 62 with (obj)
michael@0 63 {
michael@0 64 var f = function () {return a;};
michael@0 65 actual = f();
michael@0 66 }
michael@0 67 expect = 2;
michael@0 68 addThis();
michael@0 69
michael@0 70
michael@0 71 /*
michael@0 72 * Like Section B , except that we call f outside the with block.
michael@0 73 * By the principles explained above, we still expect 2 -
michael@0 74 */
michael@0 75 status = 'Section C of test';
michael@0 76 var a = 1;
michael@0 77 var obj = {a:2};
michael@0 78 with (obj)
michael@0 79 {
michael@0 80 var f = function () {return a;};
michael@0 81 }
michael@0 82 actual = f();
michael@0 83 expect = 2;
michael@0 84 addThis();
michael@0 85
michael@0 86
michael@0 87 /*
michael@0 88 * Like Section C, but with one more level of indirection -
michael@0 89 */
michael@0 90 status = 'Section D of test';
michael@0 91 var a = 1;
michael@0 92 var obj = {a:2, obj:{a:3}};
michael@0 93 with (obj)
michael@0 94 {
michael@0 95 with (obj)
michael@0 96 {
michael@0 97 var f = function () {return a;};
michael@0 98 }
michael@0 99 }
michael@0 100 actual = f();
michael@0 101 expect = 3;
michael@0 102 addThis();
michael@0 103
michael@0 104
michael@0 105 /*
michael@0 106 * Like Section C, but here we actually delete obj before calling f.
michael@0 107 * We still expect 2 -
michael@0 108 */
michael@0 109 status = 'Section E of test';
michael@0 110 var a = 1;
michael@0 111 var obj = {a:2};
michael@0 112 with (obj)
michael@0 113 {
michael@0 114 var f = function () {return a;};
michael@0 115 }
michael@0 116 delete obj;
michael@0 117 actual = f();
michael@0 118 expect = 2;
michael@0 119 addThis();
michael@0 120
michael@0 121
michael@0 122 /*
michael@0 123 * Like Section E. Here we redefine obj and call f under with (obj) -
michael@0 124 * We still expect 2 -
michael@0 125 */
michael@0 126 status = 'Section F of test';
michael@0 127 var a = 1;
michael@0 128 var obj = {a:2};
michael@0 129 with (obj)
michael@0 130 {
michael@0 131 var f = function () {return a;};
michael@0 132 }
michael@0 133 delete obj;
michael@0 134 var obj = {a:3};
michael@0 135 with (obj)
michael@0 136 {
michael@0 137 actual = f();
michael@0 138 }
michael@0 139 expect = 2; // NOT 3 !!!
michael@0 140 addThis();
michael@0 141
michael@0 142
michael@0 143 /*
michael@0 144 * Explicitly verify that f exists at global level, even though
michael@0 145 * it was defined under the with(obj) block -
michael@0 146 */
michael@0 147 status = 'Section G of test';
michael@0 148 var a = 1;
michael@0 149 var obj = {a:2};
michael@0 150 with (obj)
michael@0 151 {
michael@0 152 var f = function () {return a;};
michael@0 153 }
michael@0 154 actual = String([obj.hasOwnProperty('f'), self.hasOwnProperty('f')]);
michael@0 155 expect = String([false, true]);
michael@0 156 addThis();
michael@0 157
michael@0 158
michael@0 159 /*
michael@0 160 * Explicitly verify that f exists at global level, even though
michael@0 161 * it was defined under the with(obj) block -
michael@0 162 */
michael@0 163 status = 'Section H of test';
michael@0 164 var a = 1;
michael@0 165 var obj = {a:2};
michael@0 166 with (obj)
michael@0 167 {
michael@0 168 var f = function () {return a;};
michael@0 169 }
michael@0 170 actual = String(['f' in obj, 'f' in self]);
michael@0 171 expect = String([false, true]);
michael@0 172 addThis();
michael@0 173
michael@0 174
michael@0 175
michael@0 176 //-------------------------------------------------------------------------------------------------
michael@0 177 test();
michael@0 178 //-------------------------------------------------------------------------------------------------
michael@0 179
michael@0 180
michael@0 181 function addThis()
michael@0 182 {
michael@0 183 statusitems[UBound] = status;
michael@0 184 actualvalues[UBound] = actual;
michael@0 185 expectedvalues[UBound] = expect;
michael@0 186 UBound++;
michael@0 187 resetTestVars();
michael@0 188 }
michael@0 189
michael@0 190
michael@0 191 function resetTestVars()
michael@0 192 {
michael@0 193 delete a;
michael@0 194 delete obj;
michael@0 195 delete f;
michael@0 196 }
michael@0 197
michael@0 198
michael@0 199 function test()
michael@0 200 {
michael@0 201 enterFunc ('test');
michael@0 202 printBugNumber(BUGNUMBER);
michael@0 203 printStatus (summary);
michael@0 204
michael@0 205 for (var i = 0; i < UBound; i++)
michael@0 206 {
michael@0 207 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
michael@0 208 }
michael@0 209
michael@0 210 exitFunc ('test');
michael@0 211 }

mercurial