diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/statements/with | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/statements/with')
-rw-r--r-- | files/zh-cn/web/javascript/reference/statements/with/index.html | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/statements/with/index.html b/files/zh-cn/web/javascript/reference/statements/with/index.html new file mode 100644 index 0000000000..3244d9f28d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/with/index.html @@ -0,0 +1,131 @@ +--- +title: with +slug: Web/JavaScript/Reference/Statements/with +tags: + - Deprecated + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/with +--- +<div class="warning">不建议使用<code>with</code>语句,因为它可能是混淆错误和兼容性问题的根源。有关详细信息,请参阅下面“描述”一节中的“语意不明的弊端”部分。</div> + +<div>{{jsSidebar("Statements")}}</div> + +<div><strong>with语句 </strong>扩展一个语句的作用域链。</div> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox notranslate">with (expression) { + <em>statement</em> +} +</pre> + +<dl> + <dt><code>expression</code></dt> + <dd>将给定的表达式添加到在评估语句时使用的作用域链上。表达式周围的括号是必需的。</dd> + <dt><code>statement</code></dt> + <dd>任何语句。要执行多个语句,请使用一个<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/block">块</a>语句 ({ ... })对这些语句进行分组。</dd> +</dl> + +<h2 id="Description" name="Description">描述</h2> + +<p>JavaScript查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的context或者包含这个变量的函数有关。'with'语句将某个对象添加到作用域链的顶部,如果在statement中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。如果沒有同名的属性,则将拋出{{jsxref("ReferenceError")}}异常。</p> + +<div class="note">不推荐使用<code>with</code>,在 ECMAScript 5 <a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>中该标签已被禁止。推荐的替代方案是声明一个临时变量来承载你所需要的属性。</div> + +<h3 id="性能方面的利与弊">性能方面的利与弊</h3> + +<p><strong>利:</strong><code>with</code>语句可以在不造成性能损失的情況下,减少变量的长度。其造成的附加计算量很少。使用'with'可以减少不必要的指针路径解析运算。需要注意的是,很多情況下,也可以不使用with语句,而是使用一个临时变量来保存指针,来达到同样的效果。</p> + +<p><strong>弊:</strong><code>with</code>语句使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来将会很慢。如果是在对性能要求较高的场合,'with'下面的statement语句中的变量,只应该包含这个指定对象的属性。</p> + +<h3 id="语义不明的弊端">语义不明的弊端</h3> + +<p><strong>弊端:</strong><code>with</code>语句使得代码不易阅读,同时使得JavaScript编译器难以在作用域链上查找某个变量,难以决定应该在哪个对象上来取值。请看下面的例子:</p> + +<pre class="brush: js notranslate">function f(x, o) { + with (o) + print(x); +}</pre> + +<p><code>f</code>被调用时,<code>x</code>有可能能取到值,也可能是<code>undefined</code>,如果能取到, 有可能是在o上取的值,也可能是函数的第一个参数<code>x</code>的值(如果o中没有这个属性的话)。如果你忘记在作为第二个参数的对象o中定义<code>x</code>这个属性,程序并不会报错,只是取到另一个值而已。</p> + +<p><strong>弊端:</strong>使用<code>with</code>语句的代码,无法向前兼容,特別是在使用一些原生数据类型的时候。看下面的例子:</p> + +<div> +<pre class="brush:js notranslate">function f(foo, values) { + with (foo) { + console.log(values) + } +} +</pre> + +<p><font face="Open Sans, Arial, sans-serif">如果是在</font>ECMAScript 5环境调用<code>f([1,2,3], obj)</code>,则<code><font face="Open Sans, Arial, sans-serif">with</font></code>语句中变量<code>values</code>将指向函数的第二个参数<code>values</code>。但是,ECMAScript 6标准给<code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype">Array.prototype</a></code>添加了一个新属性<code>values</code>,所有数组实例将继承这个属性。所以在ECMAScript 6环境中,<code><font face="Open Sans, Arial, sans-serif">with</font></code>语句中变量<code>values</code>将指向<code>[1,2,3].values</code>。</p> +</div> + +<h2 id="Examples" name="Examples">示例</h2> + +<h3 id="Example_Using_with" name="Example:_Using_with">Example: Using <code>with</code></h3> + +<p>下面的<code>with</code>语句指定<code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math" title="JavaScript/Reference/Global_Objects/Math">Math</a></code>对象作为默认对象。<code>with</code>语句里面的变量,分別指向<code>Math</code>对象的<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI" title="JavaScript/Reference/Global_Objects/Math/PI"><code>PI</code></a> 、<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos" title="JavaScript/Reference/Global_Objects/Math/cos">cos</a><font face="Open Sans, Arial, sans-serif">和</font></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin" title="JavaScript/Reference/Global_Objects/Math/sin">sin</a></code>函数,不用在前面添加命名空间。后续所有引用都指向<code>Math</code>对象。</p> + +<pre class="brush:js notranslate">var a, x, y; +var r = 10; + +with (Math) { + a = PI * r * r; + x = r * cos(PI); + y = r * sin(PI / 2); +}</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-with-statement', 'with statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-with-statement', 'with statement')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12.10', 'with statement')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Now forbidden in strict mode.</td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-12.10', 'with statement')}}</td> + <td>{{Spec2('ES3')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-12.10', 'with statement')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + +<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div> + +<p>{{Compat("javascript.statements.with")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li>{{jsxref("Statements/block", "block")}}</li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict mode</a></li> + <li>{{jsxref("Symbol.unscopables")}}</li> + <li>{{jsxref("Array.@@unscopables", "Array.prototype[@@unscopables]")}}</li> +</ul> |