Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

with

这篇翻译不完整。请帮忙从英语翻译这篇文章

不推薦使用with語句,因為可能造成bug或者性能損失。詳見"Description"的"Ambiguity Con"部分。

概要

with語句的作用是擴展作用域鏈(scope chain)。

語法

with (expression) {
  statement
}
expression
將expression添加到作用域鏈,以便在statement中計算值的時候使用。expression 外面需加括號。
statement
任何語句都行。如果不止一句,則需用block符號({ ... })將其括起來。

說明

JavaScript查找某個未使用命名空間的變量時,會通過作用域鏈來查找,作用域鏈是跟執行代碼的context或者包含這個變量的函數有關。'with'語句將某個對象添加的作用域鏈的頂部,如果在statement中有某個未使用命名空間的變量,跟作用域鏈中的某個屬性同名,則這個變量將指向這個屬性值。如果沒有同名的屬性,則將拋出ReferenceError異常。

Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

性能方面的利與弊

利:with語句可以在不造成性能損失的情況下,減少變量的長度。其造成的附加計算量很少。使用'with'可以減少不必要的指針路徑解析運算。需要注意的是,很多情況下,也可以不使用with語句,而是使用一個臨時變量來保存指針,來達到同樣的效果。

弊:with語句使得程序在查找變量值時,都是先在指定的對象中查找。所以那些本來不是這個對象的屬性的變量,查找起來將會很慢。如果是在對性能要求較高的場合,'with'下面的statement語句中的變量,只應該包含這個指定對象的屬性。

語義不明的弊端

弊端:with語句使得代碼不易閱讀,同時使得JavaScript編譯器不易在作用域鏈上查找某個變量,不易決定應該在哪個對象上來取值。請看下面的例子:

function f(x, o) {
  with (o) 
    print(x);
}

f被調用時,x有可能能取到值,也可能是undefined,如果能取到, 有可能是在o上取的值,也可能是函數的第一個參數x的值(如果o中沒有這個屬性的話)。如果你忘記在作為第二個參數的對象o中定義x這個屬性,程序並不會報錯,只是取到另一個值而已。

弊端:使用with語句的代碼,無法向前兼容,特別是在使用一些原生數據類型的時候。看下面的例子:

function f(foo, values) {
    with (foo) {
        console.log(values)
    }
}

如果是在ECMAScript 5環境調用f([1,2,3], obj),則with語句中變量values將指向函數的第二個參數values。但是,ECMAScript 6標準給Array.prototype添加了一個新屬性values,所有數組實例將繼承這個屬性。所以在ECMAScript 6環境中,with語句中變量values將指向[1,2,3].values

示例

Example: Using with

下面的with語句指定Math對象作為默認對象with語句裡面的變量,分別指向Math對象的PI 、cossin函數,不用在前面添加命名空間(Math.PI)

var a, x, y;
var r = 10;

with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}

技術規範

Specification Status Comment
ECMAScript 1st Edition. Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
with statement
Standard Now forbidden in strict mode.
ECMAScript 2015 (6th Edition, ECMA-262)
with statement
Standard  

瀏覽器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

另見

文档标签和贡献者

 此页面的贡献者: jonkee, SphinxKnight, front
 最后编辑者: jonkee,