diff options
Diffstat (limited to 'files/zh-cn/web/javascript/reference/operators')
80 files changed, 11527 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html new file mode 100644 index 0000000000..9469f0f0b7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html @@ -0,0 +1,74 @@ +--- +title: 加法赋值 (+=) +slug: Web/JavaScript/Reference/Operators/Addition_assignment +tags: + - += +translation_of: Web/JavaScript/Reference/Operators/Addition_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>加法赋值操作符 (<code>+=</code>) 将右操作数的值添加到变量,并将结果分配给该变量。两个操作数的类型确定加法赋值运算符的行为。加法或串联是可能的。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-addition-assignment.html")}}</div> + +<div></div> + + + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x += y +<strong>Meaning:</strong> x = x + y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_addition_assignment">Using addition assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variables +// foo = 'foo' +// bar = 5 +// baz = true + +// Number + Number -> addition +bar += 2 // 7 + +// Boolean + Number -> addition +baz += 1 // 2 + +// Boolean + Boolean -> addition +baz += false // 1 + +// Number + String -> concatenation +bar += 'foo' // "5foo" + +// String + Boolean -> concatenation +foo += false // "foofalse" + +// String + String -> concatenation +foo += 'bar' // "foobar"</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.addition_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html b/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html new file mode 100644 index 0000000000..d7fc5da786 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html @@ -0,0 +1,301 @@ +--- +title: 算术运算符 +slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +tags: + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>算术运算符</strong>以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法(-),乘法(*)和除法(/)。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}</div> + + + +<h2 id="加法">加法 (+)</h2> + +<p>加法运算符的作用是数值求和,或者字符串拼接。</p> + +<h3 id="语法">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x + y +</pre> + +<h3 id="示例">示例</h3> + +<pre class="brush: js notranslate">// Number + Number -> 数字相加 +1 + 2 // 3 + +// Boolean + Number -> 数字相加 +true + 1 // 2 + +// Boolean + Boolean -> 数字相加 +false + false // 0 + +// Number + String -> 字符串连接 +5 + "foo" // "5foo" + +// String + Boolean -> 字符串连接 +"foo" + false // "foofalse" + +// String + String -> 字符串连接 +"foo" + "bar" // "foobar" +</pre> + +<h2 id="减法_-">减法 (-)</h2> + +<p>减法运算符使两个操作数相减,结果是它们的差值。</p> + +<h3 id="语法_2">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x - y +</pre> + +<h3 id="示例_2">示例</h3> + +<pre class="brush: js notranslate">5 - 3 // 2 +3 - 5 // -2 +"foo" - 3 // NaN</pre> + +<h2 id="除法">除法 (/)</h2> + +<p>除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。</p> + +<h3 id="语法_3">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x / y +</pre> + +<h3 id="示例_3">示例</h3> + +<pre class="brush: js notranslate">1 / 2 // 在 JavaScript 中返回 0.5 +1 / 2 // 在 Java 中返回 0 +// (不需要数字是明确的浮点数) + +1.0 / 2.0 // 在 JavaScript 或 Java 中都返回 0.5 + +2.0 / 0 // 在 JavaScript 中返回 Infinity +2.0 / 0.0 // 同样返回 Infinity +2.0 / -0.0 // 在 JavaScript 中返回 -Infinity</pre> + +<h2 id="乘法_*">乘法 (*)</h2> + +<p>乘法运算符的结果是操作数的乘积。</p> + +<h3 id="语法_4">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x * y +</pre> + +<h3 id="示例_4">示例</h3> + +<pre class="brush: js notranslate">2 * 2 // 4 +-2 * 2 // -4 +Infinity * 0 // NaN +Infinity * Infinity // Infinity +"foo" * 2 // NaN +</pre> + +<h2 id="求余">求余 (%)</h2> + +<p>求余运算符返回第一个操作数对第二个操作数的模,即 <code>var1</code> 对 <code>var2</code> 取模,其中 <code>var1</code> 和 <code>var2</code> 是变量。取模功能就是 <code>var1</code> 除以 <code>var2</code> 的整型余数。</p> + +<h3 id="语法_5">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> var1 % var2 +</pre> + +<h3 id="示例_5">示例</h3> + +<pre class="brush: js notranslate">12 % 5 // 2 +-1 % 2 // -1 +NaN % 2 // NaN +1 % 2 // 1 +2 % 3 // 2 +-4 % 2 // -0 +5.5 % 2 // 1.5 +</pre> + +<h2 id="幂_**">幂 (**)</h2> + +<p>幂运算符返回第一个操作数做底数,第二个操作数做指数的乘方。即,<code>var1</code><sup><code>var2</code></sup>,其中 <code>var1</code> 和 <code>var2</code> 是其两个操作数。幂运算符是右结合的。<code>a ** b ** c</code> 等同于 <code>a ** (b ** c)</code>。</p> + +<h3 id="语法_6">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> var1 ** var2 +</pre> + +<h3 id="注解">注解</h3> + +<p>包括 PHP 或 Python 等的大多数语言中,都包含幂运算符(一般来说符号是 ^ 或者 **)。这些语言中的幂运算符有着比其他的单目运算符(如一元 + 或一元 - )更高的优先级。但是作为例外,在 Bash 中,** 运算符被设计为比单目运算符优先级更低。在最新的 JavaScript(ES2016) 中,禁止使用带歧义的幂运算表达式。比如,底数前不能紧跟一元运算符(<code>+/-/~/!/delete/void/typeof</code>)。</p> + +<pre class="brush: js notranslate">-2 ** 2; +// 在 Bash 中等于 4 ,而在其他语言中一般等于 -4 +// 在 JavaScript 中是错误的,因为这会有歧义 + +-(2 ** 2); +// -4 在 JavaScript 中能够明显体现出作者的意图</pre> + +<h3 id="示例_6">示例</h3> + +<pre class="brush: js notranslate">2 ** 3 // 8 +3 ** 2 // 9 +3 ** 2.5 // 15.588457268119896 +10 ** -1 // 0.1 +NaN ** 2 // NaN + +2 ** 3 ** 2 // 512 +2 ** (3 ** 2) // 512 +(2 ** 3) ** 2 // 64 +</pre> + +<p>如果要反转求幂表达式结果的符号,你可以采用这样的方式:</p> + +<pre class="brush: js notranslate">-(2 ** 2) // -4</pre> + +<p>强制求幂表达式的基数为负数:</p> + +<pre class="brush: js notranslate">(-2) ** 2 // 4</pre> + +<h2 id="递增">递增 (++)</h2> + +<p>递增运算符为其操作数增加1,返回一个数值。</p> + +<ul> + <li>如果使用后置(postfix),即运算符位于操作数的后面(如 x++),那么将会在递增前返回数值。</li> + <li>如果使用前置(prefix),即运算符位于操作数的前面(如 ++x),那么将会在递增后返回数值。</li> +</ul> + +<h3 id="语法_7">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x++ 或者 ++x +</pre> + +<h3 id="示例_7">示例</h3> + +<pre class="brush: js notranslate">// 后置 +var x = 3; +y = x++; +// y = 3, x = 4 + +// 前置 +var a = 2; +b = ++a; +// a = 3, b = 3 +</pre> + +<h2 id="递减_--">递减 (--)</h2> + +<p>递减运算符将其操作数减去1,并返回一个数值。</p> + +<ul> + <li>如果后置使用(如 x--),则在递减前返回数值。</li> + <li>如果前置使用(如 --x),则在递减后返回数值。</li> +</ul> + +<h3 id="语法_8">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> x-- or --x +</pre> + +<h3 id="示例_8">示例</h3> + +<pre class="brush: js notranslate">// 后置 +var x = 3; +y = x--; // y = 3, x = 2 + +// 前置 +var a = 2; +b = --a; // a = 1, b = 1 +</pre> + +<h2 id="一元负号_-">一元负号 (-)</h2> + +<p>一元负号运算符位于操作数前面,并转换操作数的符号。</p> + +<h3 id="语法_9">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> -x +</pre> + +<h3 id="示例_9">示例</h3> + +<pre class="brush: js notranslate">var x = 3; +y = -x; // y = -3, x = 3 +</pre> + +<h2 id="一元正号">一元正号 (+)</h2> + +<p>一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。 尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值 <code>true</code>,<code>false</code> <code>和</code> <code>null</code>。小数和十六进制格式字符串也可以转换成数值。负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NaN">NaN</a>。</p> + +<h3 id="语法_10">语法</h3> + +<pre class="syntaxbox notranslate"><strong>运算符:</strong> +x +</pre> + +<h3 id="示例_10">示例</h3> + +<pre class="brush: js notranslate">+3 // 3 ++"3" // 3 ++true // 1 ++false // 0 ++null // 0 ++function(val){ return val;} //NaN</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('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.3')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.6">Additive operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.5">Multiplicative operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.3">Postfix expressions</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.4">Unary operators</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-additive-operators">Additive operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-multiplicative-operators">Multiplicative operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-postfix-expressions">Postfix expressions</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-unary-operators">Unary operators</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2016', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2016')}}</td> + <td>Added <a href="https://github.com/rwaldron/exponentiation-operator">Exponentiation operator</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2017', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2017')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-additive-operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div class="hidden"> +<p>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.</p> +</div> + +<p>{{Compat("javascript.operators.arithmetic")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment_Operators">赋值运算符</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html new file mode 100644 index 0000000000..8bdfa28db2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html @@ -0,0 +1,157 @@ +--- +title: 数组推导式 +slug: Web/JavaScript/Reference/Operators/Array_comprehensions +tags: + - JavaScript + - Non-standard + - 参考 + - 运算符 +translation_of: Archive/Web/JavaScript/Array_comprehensions +--- +<div class="warning"> +<p><strong>非标准。不要使用!</strong><br> + 数组推导是非标准的。以后应该用 {{jsxref("Array.prototype.map")}},{{jsxref("Array.prototype.filter")}},{{jsxref("Functions/Arrow_functions", "箭头函数", "", 1)}}和{{jsxref("Operators/Spread_operator", "展开语法", "", 1)}}.。</p> +</div> + +<p>{{jsSidebar("Operators")}} </p> + +<p><strong>数组推导式</strong>是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">[for (x of iterable) x] +[for (x of iterable) if (condition) x] +[for (x of iterable) for (y of iterable) x + y] +</pre> + +<h2 id="描述">描述</h2> + +<p>在数组推导式内部,可以使用下面两种子语句:</p> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of">for...of</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/if...else">if</a></li> +</ul> + +<p>每个 <code>for-of</code> 语句都放在与其配对的 <code>if</code> 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。</p> + +<h2 id="示例">示例</h2> + +<h3 id="基本的数组推导式写法">基本的数组推导式写法</h3> + +<pre class="brush:js">[for (i of [ 1, 2, 3 ]) i*i ]; +// [ 1, 4, 9 ] + +var abc = [ "A", "B", "C" ]; +[for (letters of abc) letters.toLowerCase()]; +// [ "a", "b", "c" ]</pre> + +<h3 id="带有_if_语句的数组推导式">带有 if 语句的数组推导式</h3> + +<pre class="brush: js">var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ]; + +[for (year of years) if (year > 2000) year]; +// [ 2006, 2010, 2014 ] + +[for (year of years) if (year > 2000) if(year < 2010) year]; +// [ 2006], 和下面的写法等效: + +[for (year of years) if (year > 2000 && year < 2010) year]; +// [ 2006] +</pre> + +<h3 id="用数组推导式比用数组的_map、filter_方法更简洁">用数组推导式比用数组的 <code>map</code>、<code>filter</code> 方法更简洁</h3> + +<p>对比数组的 {{jsxref("Array.map", "map")}} 和 {{jsxref("Array.filter", "filter")}} 方法:</p> + +<pre class="brush: js">var numbers = [ 1, 2, 3 ]; + +numbers.map(function (i) { return i * i }); +[for (i of numbers) i*i ]; +// 返回值都是 [ 1, 4, 9 ] + +numbers.filter(function (i) { return i < 3 }); +[for (i of numbers) if (i < 3) i]; +// 返回值都是 [ 1, 2 ] +</pre> + +<h3 id="带有两个数组的数组推导式">带有两个数组的数组推导式</h3> + +<p>用两个 <code>for-of</code> 语句迭代两个不同的数组:</p> + +<pre class="brush: js">var numbers = [ 1, 2, 3 ]; +var letters = [ "a", "b", "c" ]; + +var cross = [for (i of numbers) for (j of letters) i+j]; +// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ] + +var grid = [for (i of numbers) [for (j of letters) i+j]]; +// [ +// ["1a", "1b", "1c"], +// ["2a", "2b", "2c"], +// ["3a", "3b", "3c"] +// ] + +[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j] +// ["2b", "2c", "3b", "3c"],和下面的写法<strong>等效</strong>: + +[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j] +// ["2b", "2c", "3b", "3c"] + +[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]] +// [["2b", "2c"], ["3b", "3c"]],和下面的写法<strong>不等效</strong>: + +[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]] +// [[], ["2b", "2c"], ["3b", "3c"]] +</pre> + +<h2 id="规范">规范</h2> + +<p>最初起草在ECMAScript 6草案中,但在第27版(2014年8月)中被移除。 请参阅ES 6的旧修订版的规范语义。</p> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div class="hidden"><span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>本页的浏览器兼容性表都是基于结构化数据,如果你想更新数据.可以查看</span> <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> <span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>并且请给我们发送合并请求</span>.</div> + +<p>{{Compat("javascript.operators.array_comprehensions")}}</p> + +<h2 id="同旧版的JS1.7JS1.8数组推导的不同之处">同旧版的JS1.7/JS1.8数组推导的不同之处</h2> + +<p> </p> + +<div class="warning">JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 ({{bug(1220564)}}).</div> + +<p><strong>旧版数组推导语法 (请不要再使用了!):</strong></p> + +<pre class="brush: js example-bad">[X for (Y in Z)] +[X for each (Y in Z)] +[X for (Y of Z)] +</pre> + +<p>不同点:</p> + +<ul> + <li>ESNext数组推导为每个"for"创建了一个作用域而取代了整个作用域. + <ul> + <li>Old: <code>[()=>x for (x of [0, 1, 2])][1]() // 2</code></li> + <li>New: <code>[for (x of [0, 1, 2]) ()=>x][1]() // 1, each iteration creates a fresh binding for x. </code></li> + </ul> + </li> + <li>ESNext 同"for"进行赋值而取代了旧的赋值表达式. + <ul> + <li>Old: <code>[i * 2 for (i of numbers)]</code></li> + <li>New: <code>[for (i of numbers) i * 2]</code></li> + </ul> + </li> + <li>ESNext数组推导可由多个if和for组成</li> + <li>ESNext数组推导只和<code>{{jsxref("Statements/for...of", "for...of")}}</code>迭代才有效,而不会同 <code>{{jsxref("Statements/for...in", "for...in")}}</code> 迭代.</li> +</ul> + +<p>点击查看 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1220564#c42">Bug 1220564, comment 42</a> 并提出建设性建议.</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of"><code>for...of</code></a></li> + <li>{{jsxref("Operators/Generator_comprehensions", "生成器推导式", "" ,1)}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/assignment/index.html b/files/zh-cn/web/javascript/reference/operators/assignment/index.html new file mode 100644 index 0000000000..eba07d8890 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/assignment/index.html @@ -0,0 +1,62 @@ +--- +title: 赋值运算符(=) +slug: Web/JavaScript/Reference/Operators/Assignment +tags: + - JavaScript + - 参考 + - 操作者 + - 语言特性 + - 赋值运算符 +translation_of: Web/JavaScript/Reference/Operators/Assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><span>简单赋值操作符(=)用于为变量赋值。赋值表达式本身的值为其完成后被赋值的变量的值。为了给多个变量赋一个值,可以链式使用赋值操作符。</span></p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x = y +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="简单赋值和链式赋值">简单赋值和链式赋值</h3> + +<pre class="brush: js notranslate">// 假设已经存在以下变量 +// x = 5 +// y = 10 +// z = 25 + +x = y // x 为 10 +x = y = z // x, y 都为 25</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器支持">浏览器支持</h2> + + + +<p>{{Compat("javascript.operators.assignment")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html b/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html new file mode 100644 index 0000000000..5d500538b4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html @@ -0,0 +1,412 @@ +--- +title: 赋值运算符 +slug: Web/JavaScript/Reference/Operators/Assignment_Operators +tags: + - JavaScript + - 运算符 +translation_of: Web/JavaScript/Reference/Operators#Assignment_operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>赋值运算符(<strong>assignment operator</strong>)基于右值(right operand)的值,给左值(left operand)赋值。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}</div> + +<p class="hidden">本文的交互示例的源代码存储在GithHub仓库。如果你愿意贡献更多交互示例,请克隆仓库 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 并提交 pull request.</p> + +<h2 id="概述">概述</h2> + +<p>基本的赋值运算符是等号(<code>=</code>),该运算符把它右边的运算值赋给左边。即,<code>x = y</code> 把 <code>y</code> 的值赋给 <code>x</code>。 其他的赋值运算符通常是标准运算符的简写形式,如下面的定义与示例。 </p> + +<table class="standard-table"> + <tbody> + <tr> + <th>名称</th> + <th>简写形式</th> + <th>含义</th> + </tr> + <tr> + <td><a href="#Assignment">赋值(Assignment)</a></td> + <td><code>x = y</code></td> + <td><code>x = y</code></td> + </tr> + <tr> + <td><a href="#Addition_assignment">加赋值(Addition assignment)</a></td> + <td><code>x += y</code></td> + <td><code>x = x + y</code></td> + </tr> + <tr> + <td><a href="#Subtraction_assignment">减赋值(Subtraction assignment)</a></td> + <td><code>x -= y</code></td> + <td><code>x = x - y</code></td> + </tr> + <tr> + <td><a href="#Multiplication_assignment">乘赋值(Multiplication assigment)</a></td> + <td><code>x *= y</code></td> + <td><code>x = x * y</code></td> + </tr> + <tr> + <td><a href="#Division_assignment">除赋值(Division assignment)</a></td> + <td><code>x /= y</code></td> + <td><code>x = x / y</code></td> + </tr> + <tr> + <td><a href="#Remainder_assignment">模赋值(Remainder assignment)</a></td> + <td><code>x %= y</code></td> + <td><code>x = x % y</code></td> + </tr> + <tr> + <td><a href="#Exponentiation_assignment">指数赋值(Exponentiation assignment)</a></td> + <td><code>x **= y</code></td> + <td><code>x = x ** y</code></td> + </tr> + <tr> + <td><a href="#Left_shift_assignment">左移赋值(Left shift assignment)</a></td> + <td><code>x <<= y</code></td> + <td><code>x = x << y</code></td> + </tr> + <tr> + <td><a href="#Right_shift_assignment">右移赋值(Right shift assignment)</a></td> + <td><code>x >>= y</code></td> + <td><code>x = x >> y</code></td> + </tr> + <tr> + <td><a href="#Unsigned_right_shift_assignment">无符号右移赋值(Unsigned right shift assignment)</a></td> + <td><code>x >>>= y</code></td> + <td><code>x = x >>> y</code></td> + </tr> + <tr> + <td><a href="#Bitwise_AND_assignment">按位与赋值(Bitwise AND assignment)</a></td> + <td><code>x &= y</code></td> + <td><code>x = x & y</code></td> + </tr> + <tr> + <td><a href="#Bitwise_XOR_assignment">按位异或赋值(Bitwise XOR assignment)</a></td> + <td><code>x ^= y</code></td> + <td><code>x = x ^ y</code></td> + </tr> + <tr> + <td><a href="#Bitwise_OR_assignment">按位或赋值(Bitwise OR assignment)</a></td> + <td><code>x |= y</code></td> + <td><code>x = x | y</code></td> + </tr> + </tbody> +</table> + +<h2 id="赋值"><a name="Assignment">赋值</a></h2> + +<p>简单的赋值运算符,把一个值赋给一个变量。为了把一个值赋给多个变量,可以以链式使用赋值运算符。参考下例:</p> + +<h4 id="语法">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x = y +</pre> + +<h4 id="示例">示例</h4> + +<pre class="brush: js">// Assuming the following variables +// x = 5 +// y = 10 +// z = 25 + +x = y // x is 10 +x = y = z // x, y and z are all 25 +</pre> + +<h3 id="加赋值(Addition_assignment)"><a name="Addition_assignment">加赋值(Addition assignment)</a></h3> + +<p>加赋值运算符把一个右值与一个变量相加,然后把相加的结果赋给该变量。两个操作数的类型决定了加赋值运算符的行为。算术相加或字符串连接都有可能。更多细节参考 {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}}。</p> + +<h4 id="语法_2">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x += y +<strong>Meaning:</strong> x = x + y +</pre> + +<h4 id="示例_2">示例</h4> + +<pre class="brush: js">// 定义下列变量 +// foo = 'foo' +// bar = 5 +// baz = true + + +// Number + Number -> addition +bar += 2 // 7 + +// Boolean + Number -> addition +baz += 1 // 2 + +// Boolean + Boolean -> addition +baz += false // 1 + +// Number + String -> concatenation +bar += 'foo' // "5foo" + +// String + Boolean -> concatenation +foo += false // "foofalse" + +// String + String -> concatenation +foo += 'bar' // "foobar" +</pre> + +<h3 id="减赋值(Subtraction_assignment)"><a name="Subtraction_assignment">减赋值(Subtraction assignment)</a></h3> + +<p>减赋值运算符使一个变量减去右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} 。</p> + +<h4 id="语法_3">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x -= y +<strong>Meaning:</strong> x = x - y +</pre> + +<h4 id="示例_3">示例</h4> + +<pre class="brush: js">// 假定已定义了下面的变量 +// bar = 5 + +bar -= 2 // 3 +bar -= "foo" // NaN +</pre> + +<h3 id="乘赋值(Multiplication_assignment)"><a name="Multiplication_assignment">乘赋值(Multiplication assignment)</a></h3> + +<p>乘赋值运算符使一个变量乘以右值,然后把相成的结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}}。</p> + +<h4 id="语法_4">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x *= y +<strong>Meaning:</strong> x = x * y +</pre> + +<h4 id="示例_4">示例</h4> + +<pre class="brush: js">// 假定已定义了下面的变量 +// bar = 5 + +bar *= 2 // 10 +bar *= 'foo' // NaN +</pre> + +<h3 id="除赋值(Division_assignment)"><a name="Division_assignment">除赋值(Division assignment)</a></h3> + +<p>除赋值运算符使一个变量除以右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}}。</p> + +<h4 id="语法_5">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x /= y +<strong>Meaning:</strong> x = x / y +</pre> + +<h4 id="示例_5">示例</h4> + +<pre class="brush: js">// 假定已定义了下面的变量 +// bar = 5 + +bar /= 2 // 2.5 +bar /= "foo" // NaN +bar /= 0 // Infinity +</pre> + +<h3 id="模赋值(Remainder_assignment)"><a name="Remainder_assignment">模赋值(Remainder assignment)</a></h3> + +<p>模赋值运算符使一个变量除以右值,然后把余数赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}}。</p> + +<h4 id="语法_6">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x %= y +<strong>Meaning:</strong> x = x % y +</pre> + +<h4 id="示例_6">示例</h4> + +<pre class="brush: js">// Assuming the following variable +// bar = 5 + +bar %= 2 // 1 +bar %= 'foo' // NaN +bar %= 0 // NaN +</pre> + +<h3 id="指数赋值(Exponentiation_assignment)"><a id="Exponentiation_assignment" name="Exponentiation_assignment">指数赋值(Exponentiation assignment)</a></h3> + +<p>指数赋值运算符使一个变量为底数、以右值为指数的指数运算(乘方)结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "算术运算符", "#Exponentiation", 1)}}。</p> + +<h4 id="语法_7">语法</h4> + +<pre class="syntaxbox"><strong>语法:</strong> x **= y +<strong>含义:</strong> x = x ** y +</pre> + +<h4 id="示例_7">示例</h4> + +<pre class="brush: js">// Assuming the following variable +// bar = 5 + +bar **= 2 // 25 +bar **= 'foo' // NaN</pre> + +<h3 id="左移赋值(Left_shift_assignment)"><a name="Left_shift_assignment">左移赋值(Left shift assignment)</a></h3> + +<p>左移赋值运算符使变量向左移动指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}。</p> + +<h4 id="语法_8">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x <<= y +<strong>Meaning:</strong> x = x << y +</pre> + +<h4 id="示例_8">示例</h4> + +<pre class="brush: js">var bar = 5; // (00000000000000000000000000000101) +bar <<= 2; // 20 (00000000000000000000000000010100) +</pre> + +<h3 id="右移赋值(Right_shift_assignment)"><a name="Right_shift_assignment">右移赋值(Right shift assignment)</a></h3> + +<p>右移赋值运算符使变量向右移指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}。</p> + +<h4 id="语法_9">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x >>= y +<strong>Meaning:</strong> x = x >> y +</pre> + +<h4 id="示例_9">示例</h4> + +<pre class="brush: js">var bar = 5; // (00000000000000000000000000000101) +bar >>= 2; // 1 (00000000000000000000000000000001) + +var bar = -5; // (-00000000000000000000000000000101) +bar >>= 2; // -2 (-00000000000000000000000000000010) +</pre> + +<h3 id="无符号右移赋值(Unsigned_right_shift_assignment)"><a name="Unsigned_right_shift_assignment">无符号右移赋值(Unsigned right shift assignment)</a></h3> + +<p>无符号右移赋值运算符向右移动指定数量的比特位,然后把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}。</p> + +<h4 id="语法_10">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x >>>= y +<strong>Meaning:</strong> x = x >>> y +</pre> + +<h4 id="示例_10">示例</h4> + +<pre class="brush: js">var bar = 5; // (00000000000000000000000000000101) +bar >>>= 2; // 1 (00000000000000000000000000000001) + +var bar = -5; // (-00000000000000000000000000000101) +bar >>>= 2; // 1073741822 (00111111111111111111111111111110)</pre> + +<h3 id="按位与赋值(Bitwise_AND_assignment)"><a name="Bitwise_AND_assignment">按位与赋值(Bitwise AND assignment)</a></h3> + +<p>按位与赋值运算符使用两个操作值的二进制表示,执行按位与运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}。</p> + +<h4 id="语法_11">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x &= y +<strong>Meaning:</strong> x = x & y +</pre> + +<h4 id="示例_11">示例</h4> + +<pre class="brush: js">var bar = 5; +// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +bar &= 2; // 0 +</pre> + +<h3 id="按位异或赋值(Bitwise_XOR_assignment)"><a name="Bitwise_XOR_assignment">按位异或赋值(Bitwise XOR assignment)</a></h3> + +<p>按位异或赋值运算符使用两个操作值的二进制表示,执行二进制异或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}。</p> + +<h4 id="语法_12">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x ^= y +<strong>Meaning:</strong> x = x ^ y +</pre> + +<h4 id="示例_12">示例</h4> + +<pre class="brush: js">var bar = 5; +bar ^= 2; // 7 +// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +// ----------------------------------- +// 7: 00000000000000000000000000000111 +</pre> + +<h3 id="按位或赋值(Bitwise_OR_assignment)"><a name="Bitwise_OR_assignment">按位或赋值(Bitwise OR assignment)</a></h3> + +<p>按位或赋值运算符使用两个操作值的二进制表示,执行按位或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}。</p> + +<h4 id="语法_13">语法</h4> + +<pre class="syntaxbox"><strong>Operator:</strong> x |= y +<strong>Meaning:</strong> x = x | y +</pre> + +<h4 id="示例_13">示例</h4> + +<pre class="brush: js">var bar = 5; +bar |= 2; // 7 +// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +// ----------------------------------- +// 7: 00000000000000000000000000000111 +</pre> + +<h2 id="示例_14">示例</h2> + +<h3 id="带有赋值运算符的左值(Left_operand)">带有赋值运算符的左值(Left operand)</h3> + +<p>在某些不常见的情况下,赋值运算符(如<code> x += y</code>)并不等同于表达式( <code>x = x + y</code>)。当一个赋值运算符的左值包含有一个赋值运算符时,左值只会被求值一次。例如:</p> + +<pre class="brush: js">a[i++] += 5 // i 执行一次求值 +a[i++] = a[i++] + 5 // i 执行两次求值 +</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-assignment-operators', 'Assignment operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-assignment-operators', 'Assignment operators')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.13', 'Assignment operators')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.13', 'Assignment operators')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div class="hidden">该兼容表是由结构化数据生成。如果你愿意贡献数据,请克隆仓库 <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 并提交 pull request.</div> + +<p>{{Compat("javascript.operators.assignment")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators">算术运算符</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/async允许声明一个函数为一个包含异步操作的函数/index.html b/files/zh-cn/web/javascript/reference/operators/async允许声明一个函数为一个包含异步操作的函数/index.html new file mode 100644 index 0000000000..eebfd13ca2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/async允许声明一个函数为一个包含异步操作的函数/index.html @@ -0,0 +1,98 @@ +--- +title: async function expression +slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 +tags: + - JavaScript + - 函数 + - 基本表达式 + - 实验性内容 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/async_function +--- +<div>{{jsSidebar("Operators")}}</div> + +<div> </div> + +<p><strong><code>async function</code></strong> 关键字用来在表达式中定义异步函数。当然,你也可以用 {{jsxref('Statements/async_function', '异步函数语句')}} 来定义。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">async function [<em>name</em>]([<em>param1</em>[, <em>param2[</em>, ..., <em>paramN</em>]]]) { <em>statements </em>}</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>name</code></dt> + <dd>此异步函数的名称,可省略。如果省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。</dd> + <dt><code>paramN</code></dt> + <dd>传入函数的形参名称。</dd> + <dt><code>statements</code></dt> + <dd>组成函数体的语句。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>异步函数表达式与 {{jsxref('Statements/async_function', '异步函数语句')}} 非常相似,语法也基本相同。它们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。另外,异步函数表达式还可以用在 {{Glossary("IIFE")}} (立即执行函数表达式,Immediately Invoked Function Expression) 中,更多信息见 {{jsxref('Reference/Functions', '函数')}}。</p> + +<h2 id="示例">示例</h2> + +<h3 id="一个简单例子">一个简单例子</h3> + +<pre class="brush: js">function resolveAfter2Seconds(x) { + return new Promise(resolve => { + setTimeout(() => { + resolve(x); + }, 2000); + }); +}; + +// async function expression assigned to a variable +var add1 = async function(x) { + var a = await resolveAfter2Seconds(20); + var b = await resolveAfter2Seconds(30); + return x + a + b; +} + +add1(10).then(v => { + console.log(v); // 4 秒后打印 60 +}); + +(async function(x) { // async function expression used as an IIFE + var p_a = resolveAfter2Seconds(20); + var p_b = resolveAfter2Seconds(30); + return x + await p_a + await p_b; +})(10).then(v => { + console.log(v); // 2 秒后打印 60 +}); +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>ES2017 中的初始定义</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div>{{Compat("javascript.operators.async_function_expression")}}</div> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li>{{jsxref("Statements/async_function", "异步函数语句")}}</li> + <li>{{jsxref("AsyncFunction")}} 对象</li> + <li>{{jsxref("Operators/await", "await 操作符")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/await/index.html b/files/zh-cn/web/javascript/reference/operators/await/index.html new file mode 100644 index 0000000000..fe95e7ddf2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/await/index.html @@ -0,0 +1,158 @@ +--- +title: await +slug: Web/JavaScript/Reference/Operators/await +tags: + - JavaScript + - Promise + - await + - 实验性 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/await +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><code>await</code> 操作符用于等待一个{{jsxref("Promise")}} 对象。它只能在异步函数 {{jsxref("Statements/async_function", "async function")}} 中使用。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">[<font face="Consolas, Liberation Mono, Courier, monospace">返回值</font>] = await <font face="Consolas, Liberation Mono, Courier, monospace">表达式</font>;</pre> + +<dl> + <dt><font face="Consolas, Liberation Mono, Courier, monospace">表达式</font></dt> + <dd>一个 {{jsxref("Promise")}} 对象或者任何要等待的值。</dd> + <dt><font face="Consolas, Liberation Mono, Courier, monospace">返回值</font></dt> + <dd> + <p>返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。</p> + </dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>await 表达式会暂停当前 {{jsxref("Statements/async_function", "async function")}} 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 {{jsxref("Statements/async_function", "async function")}}。</p> + +<p>若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。</p> + +<p>另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。</p> + +<h2 id="例子">例子</h2> + +<p>如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。</p> + +<pre class="brush: js notranslate">function resolveAfter2Seconds(x) { + return new Promise(resolve => { + setTimeout(() => { + resolve(x); + }, 2000); + }); +} + +async function f1() { + var x = await resolveAfter2Seconds(10); + console.log(x); // 10 +} +f1(); + +</pre> + +<p>如果该值不是一个 Promise,await 会把该值转换为已正常处理的Promise,然后等待其处理结果。</p> + +<pre class="brush: js notranslate">async function f2() { + var y = await 20; + console.log(y); // 20 +} +f2(); +</pre> + +<p>如果 Promise 处理异常,则异常值被抛出。</p> + +<pre class="brush: js notranslate">async function f3() { + try { + var z = await Promise.reject(30); + } catch (e) { + console.log(e); // 30 + } +} +f3();</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('Async Function', '#async-function-definitions', 'async function')}}</td> + <td>{{Spec2('Async Function')}}</td> + <td>提案</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Edge</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>基本支持</td> + <td>{{CompatChrome(55)}}</td> + <td>{{CompatGeckoDesktop("52.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatOpera(42)}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td> 基本支持</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoMobile("52.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatOpera(42)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatChrome(55)}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="查看更多">查看更多</h2> + +<ul> + <li>{{jsxref("Statements/async_function", "async 函数")}}</li> + <li>{{jsxref("Operators/async_function", "async 函数表达式")}}</li> + <li>{{jsxref("AsyncFunction")}} object</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html new file mode 100644 index 0000000000..5c92f0196c --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: 按位与赋值(&=) +slug: Web/JavaScript/Reference/Operators/Bitwise_AND_assignment +tags: + - JavaScript + - 按位与赋值运算 + - 操作符运算 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<div>按位与赋值运算符(&=)表示两个操作数的二进制,对它们进行按位AND运算并将结果分配给变量。</div> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-and-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x &= y +<strong>Meaning:</strong> x = x & y +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="按位与赋值运算">按位与赋值运算</h3> + +<pre class="brush: js notranslate">let a = 5; +// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +a &= 2; // 0</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.bitwise_and_assignment")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND">Bitwise AND operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html new file mode 100644 index 0000000000..d0dfd8ca78 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html @@ -0,0 +1,100 @@ +--- +title: 按位非 (~) +slug: Web/JavaScript/Reference/Operators/Bitwise_NOT +tags: + - JavaScript + - 位操作符 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_NOT +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>按位非运算符(~),反转操作数的位。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-not.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>~a</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>操作数被转换为32位二进制表示(0和1)。超过32位的数字将丢弃其最高有效位。如下例子中,超过32位的整数转换为32位整数:</p> + +<pre class="brush: js notranslate">Before: 11100110111110100000000000000110000000000001 +After: 10100000000000000110000000000001</pre> + +<p>第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。</p> + +<p>将运算符应用于每对位,然后按位构造结果。</p> + +<p>非运算的真值表:</p> + +<table class="standard-table"> + <thead> + <tr> + <th class="header" scope="col">a</th> + <th class="header" scope="col">NOT a</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + </tr> + </tbody> +</table> + +<pre class="brush: js notranslate"> 9 (base 10) = 00000000000000000000000000001001 (base 2) + -------------------------------- +~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10) +</pre> + +<p>按位非运算时,任何数字<code>x<font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">的运算结果都是</span></font></code><code>-(x + 1)</code>。例如,<code>〜-5</code>运算结果为<code>4</code>。</p> + +<p>Note that due to using 32-bit representation for numbers both <code>~-1</code> and <code>~4294967295</code> (2<sup>32</sup>-1) results in <code>0</code>.</p> + +<p>请注意,由于对数字<code>~-1</code>和<code>~4294967295</code> (2<sup>32</sup>-1) 使用32位表示形式,结果均为0。</p> + +<h2 id="例子">例子</h2> + +<h3 id="使用按位取反">使用按位取反</h3> + +<pre class="brush: js notranslate">~0; // -1 +~-1; // 0 +~1; // -2 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-unary-operators', 'Unary NOT expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.bitwise_not")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html new file mode 100644 index 0000000000..48ca962238 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html @@ -0,0 +1,755 @@ +--- +title: 按位操作符 +slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +tags: + - js ^ & Bitwise Operators +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<h2 id="Summary" name="Summary">概述</h2> + +<p><strong>按位操作符(Bitwise operators)</strong> 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">数值</a>。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。</p> + +<p>下面的表格总结了JavaScript中的按位操作符:</p> + +<table class="standard-table"> + <tbody> + <tr> + <th>运算符</th> + <th>用法</th> + <th>描述</th> + </tr> + <tr> + <td><a href="#Bitwise_AND">按位与( AND)</a></td> + <td style="white-space: nowrap;"><code>a & b</code></td> + <td>对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。</td> + </tr> + <tr> + <td><a href="#Bitwise_OR">按位或(OR)</a></td> + <td style="white-space: nowrap;"><code>a | b</code></td> + <td>对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。</td> + </tr> + <tr> + <td><a href="#Bitwise_XOR">按位异或(XOR)</a></td> + <td style="white-space: nowrap;"><code>a ^ b</code></td> + <td>对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。</td> + </tr> + <tr> + <td><a href="#Bitwise_NOT">按位非(NOT)</a></td> + <td style="white-space: nowrap;"><code>~ a</code></td> + <td>反转操作数的比特位,即0变成1,1变成0。</td> + </tr> + <tr> + <td><a href="#Left_shift">左移(L</a><a href="#Left_shift" style="line-height: 1.5;">eft shift)</a></td> + <td style="white-space: nowrap;"><code>a << b</code></td> + <td>将 <code>a</code> 的二进制形式向左移 <code>b</code> (< 32) 比特位,右边用0填充。</td> + </tr> + <tr> + <td><a href="#Right_shift">有符号右移</a></td> + <td style="white-space: nowrap;"><code>a >> b</code></td> + <td>将 a 的二进制表示向右移<code> b </code>(< 32) 位,丢弃被移出的位。</td> + </tr> + <tr> + <td><a href="#Unsigned_right_shift">无符号右移</a></td> + <td style="white-space: nowrap;"><code>a >>> b</code></td> + <td>将 a 的二进制表示向右移<code> b </code>(< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。</td> + </tr> + </tbody> +</table> + +<h2 id="有符号32位整数">有符号32位整数</h2> + +<p>所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:</p> + +<pre>00000000000000000000000100111010 +</pre> + +<p>下面编码 <code>~314</code>,即 <code>314</code> 的反码:</p> + +<pre>11111111111111111111111011000101 +</pre> + +<p>最后,下面编码 <code>-314</code>,即 <code>314</code> 的反码再加1:</p> + +<pre>11111111111111111111111011000110 +</pre> + +<p>补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(<em>sign bit</em>)。</p> + +<p><code>0</code> 是所有比特数字0组成的整数。</p> + +<pre>0 (base 10) = 00000000000000000000000000000000 (base 2) +</pre> + +<p><code>-1</code> 是所有比特数字1组成的整数。</p> + +<pre>-1 (base 10) = 11111111111111111111111111111111 (base 2) +</pre> + +<p><code>-2147483648</code>(十六进制形式:<code>-0x80000000</code>)是除了最左边为1外,其他比特位都为0的整数。</p> + +<pre>-2147483648 (base 10) = 10000000000000000000000000000000 (base 2) +</pre> + +<p><code>2147483647</code>(十六进制形式:<code>0x7fffffff</code>)是除了最左边为0外,其他比特位都为1的整数。</p> + +<pre>2147483647 (base 10) = 01111111111111111111111111111111 (base 2) +</pre> + +<p>数字<code>-2147483648</code> 和 <code>2147483647</code> 是32位有符号数字所能表示的最小和最大整数。</p> + +<h2 id="按位逻辑操作符">按位逻辑操作符</h2> + +<p>从概念上讲,按位逻辑操作符按遵守下面规则:</p> + +<ul> + <li>操作数被转换成32位整数,用比特序列(0和1组成)表示。超过32位的数字会被丢弃。<br> + 例如, 以下具有32位以上的整数将转换为32位整数:</li> + <li> + <pre>转换前: 11100110111110100000000000000110000000000001 +转换后: 10100000000000000110000000000001</pre> + </li> + <li>第一个操作数的每个比特位与第二个操作数的相应比特位匹配:第一位对应第一位,第二位对应第二位,以此类推。</li> + <li>位运算符应用到每对比特位,结果是新的比特值。</li> +</ul> + +<h3 id="(按位与)"><a name="Bitwise_AND">& (按位与)</a></h3> + +<p>对每对比特位执行<strong>与(AND)操作</strong>。只有 a 和 b 都是 1 时,a AND b 才是 1。<strong>与操作</strong>的真值表如下:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">a</td> + <td class="header">b</td> + <td class="header">a AND b</td> + </tr> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>0</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>1</td> + </tr> + </tbody> +</table> + +<pre> 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10) +</pre> + +<p>将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。</p> + +<h3 id="(按位或)"><a name="Bitwise_OR">| (按位或)</a></h3> + +<p>对每一对比特位执行<strong>或(OR)操作</strong>。如果 a 或 b 为 1,则 <code>a</code> OR <code>b</code> 结果为 1。<strong>或操作</strong>的真值表:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">a</td> + <td class="header">b</td> + <td class="header">a OR b</td> + </tr> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>1</td> + </tr> + </tbody> +</table> + +<pre> 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10) +</pre> + +<p>将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。</p> + +<p>补充一些例子:</p> + +<pre class="brush: js">1 | 0 ; // 1 + +1.1 | 0 ; // 1 + +'asfdasfda' | 0 ; // 0 + +0 | 0 ; // 0 + +(-1) | 0 ; // -1 + +(-1.5646) | 0 ; // -1 + +[] | 0 ; // 0 + +({}) | 0 ; // 0 + +"123456" | 0 ; // 123456 + +1.23E2 | 0; // 123 + +1.23E12 | 0; // 1639353344 + +-1.23E2 | 0; // -123 + +-1.23E12 | 0; // -1639353344</pre> + +<h3 id="(按位异或)"><a name="Bitwise_XOR">^ (按位异或)</a></h3> + +<p>对每一对比特位执行<strong>异或(XOR)操作</strong>。当 a 和 b 不相同时,<code>a</code> XOR <code>b</code> 的结果为 1。<strong>异或操作</strong>真值表:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">a</td> + <td class="header">b</td> + <td class="header">a XOR b</td> + </tr> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>0</td> + </tr> + </tbody> +</table> + +<pre> 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10) +</pre> + +<p>将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。</p> + +<h3 id="(按位非)"><a name="Bitwise_NOT">~ (按位非)</a></h3> + +<p>对每一个比特位执行<strong>非(NOT)操作</strong>。NOT <code>a</code> 结果为 a 的反转(即反码)。<strong>非操作</strong>的真值表:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">a</td> + <td class="header">NOT a</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + </tr> + </tbody> +</table> + +<pre> 9 (base 10) = 00000000000000000000000000001001 (base 2) + -------------------------------- +~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10) +</pre> + +<p>对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。</p> + +<p>与 indexOf 一起使用示例:</p> + +<pre class="brush: js">var str = 'rawr'; +var searchFor = 'a'; + +// 这是 if (-1*str.indexOf('a') <= 0) 条件判断的另一种方法 +if (~str.indexOf(searchFor)) { + // searchFor 包含在字符串中 +} else { + // searchFor 不包含在字符串中 +} + +// (~str.indexOf(searchFor))的返回值 +// r == -1 +// a == -2 +// w == -3 +</pre> + +<h2 id="按位移动操作符">按位移动操作符</h2> + +<p>按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。</p> + +<p>按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。</p> + +<pre>注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端, +又称为"高位编址"。 +Big-Endian是最直观的字节序: +①把内存地址从左到右按照由低到高的顺序写出; +②把值按照通常的高位到低位的顺序写出; +③两者对照,一个字节一个字节的填充进去。</pre> + +<h3 id="<<_(左移)"><a name="Left_shift"><< (左移)</a></h3> + +<p>该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。</p> + +<p>For example, <code>9 << 2</code> yields 36:</p> + +<pre> 9 (base 10): 00000000000000000000000000001001 (base 2) + -------------------------------- +9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10) +</pre> + +<p>在数字 <strong>x</strong> 上左移 <strong>y</strong> 比特得到 <strong>x * 2<sup>y</sup></strong>.</p> + +<h3 id=">>_(有符号右移)"><a name="Right_shift">>> (有符号右移)</a></h3> + +<p>该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。</p> + +<p>例如, <code>9 >> 2</code> 得到 2:</p> + +<pre> 9 (base 10): 00000000000000000000000000001001 (base 2) + -------------------------------- +9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10) +</pre> + +<p>相比之下, <code>-9 >> 2</code> 得到 -3,因为符号被保留了。</p> + +<pre> -9 (base 10): 11111111111111111111111111110111 (base 2) + -------------------------------- +-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10) +</pre> + +<h3 id=">>>_(无符号右移)"><a name="Unsigned_right_shift">>>> (无符号右移)</a></h3> + +<p>该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)</p> + +<p>对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 <code>9 >>> 2</code> 和 <code>9 >> 2</code> 一样返回 2:</p> + +<pre> 9 (base 10): 00000000000000000000000000001001 (base 2) + -------------------------------- +9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10) +</pre> + +<p>但是对于负数却不尽相同。 <code>-9 >>> 2</code> 产生 1073741821 这和 <code>-9 >> 2</code> 不同:</p> + +<pre> -9 (base 10): 11111111111111111111111111110111 (base 2) + -------------------------------- +-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10) +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="例子:标志位与掩码">例子:标志位与掩码</h3> + +<p>位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。</p> + +<p>例如,有 4 个标志位:</p> + +<ul> + <li>标志位 A:我们有 ant</li> + <li>标志位 B:我们有 bat</li> + <li>标志位 C:我们有 cat</li> + <li>标志位 D:我们有 duck</li> +</ul> + +<p>标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 <code>flags</code> 的二进制值为 0101:</p> + +<pre class="brush: js">var flags = 5; // 二进制 0101 +</pre> + +<p>这个值表示:</p> + +<ul> + <li>标志位 A 是 true (我们有 ant);</li> + <li>标志位 B 是 false (我们没有 bat);</li> + <li>标志位 C 是 true (我们有 cat);</li> + <li>标志位 D 是 false (我们没有 duck);</li> +</ul> + +<p>因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。</p> + +<p>掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:</p> + +<pre class="brush: js">var FLAG_A = 1; // 0001 +var FLAG_B = 2; // 0010 +var FLAG_C = 4; // 0100 +var FLAG_D = 8; // 1000 +</pre> + +<p>新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:</p> + +<pre class="brush: js">var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011 +</pre> + +<p>某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:</p> + +<pre class="brush: js">// 如果我们有 cat +if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true + // do stuff +} +</pre> + +<p>一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:</p> + +<pre class="brush: js">// 如果我们有 bat 或者 cat 至少一个 +// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true +if ((flags & FLAG_B) || (flags & FLAG_C)) { + // do stuff +} +</pre> + +<pre class="brush: js">// 如果我们有 bat 或者 cat 至少一个 +var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110 +if (flags & mask) { // 0101 & 0110 => 0100 => true + // do stuff +} +</pre> + +<p>可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:</p> + +<pre class="brush: js">// 我们有 cat 和 duck +var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100 +flags |= mask; // 0101 | 1100 => 1101 +</pre> + +<p>可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :</p> + +<pre class="brush: js">// 我们没有 ant 也没有 cat +var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010 +flags &= mask; // 1101 & 1010 => 1000 +</pre> + +<p>如上的掩码同样可以通过 <code>~FLAG_A & ~FLAG_C</code> 得到(德摩根定律):</p> + +<pre class="brush: js">// 我们没有 ant 也没有 cat +var mask = ~FLAG_A & ~FLAG_C; +flags &= mask; // 1101 & 1010 => 1000 +</pre> + +<p>标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:</p> + +<pre class="brush: js">// 如果我们以前没有 bat ,那么我们现在有 bat +// 但是如果我们已经有了一个,那么现在没有了 +// 对 cat 也是相同的情况 +var mask = FLAG_B | FLAG_C; +flags = flags ^ mask; // 1100 ^ 0110 => 1010 +</pre> + +<p>最后,所有标志位可以通过非运算翻转:</p> + +<pre class="brush: js">// entering parallel universe... +flags = ~flags; // ~1010 => 0101 +</pre> + +<h3 id="转换片段">转换片段</h3> + +<p>将一个二进制数的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code> 转换为十进制的 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code>:</p> + +<pre class="brush: js">var sBinString = "1011"; +var nMyNumber = parseInt(sBinString, 2); +alert(nMyNumber); // 打印 11 +</pre> + +<p>将一个十进制的 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code> 转换为二进制数的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code>:</p> + +<pre class="brush: js">var nMyNumber = 11; +var sBinString = nMyNumber.toString(2); +alert(sBinString); // 打印 1011 +</pre> + +<h3 id="自动化掩码创建">自动化掩码创建</h3> + +<p>如果你需要从一系列的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Boolean</a></code> 值创建一个掩码,你可以:</p> + +<pre class="brush: js">function createMask () { + var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length; + for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++); + return nMask; +} +var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011 +var mask2 = createMask(false, false, true); // 4, i.e.: 0100 +var mask3 = createMask(true); // 1, i.e.: 0001 +// etc. + +alert(mask1); // 打印 11 +</pre> + +<h3 id="逆算法:从掩码得到布尔数组">逆算法:从掩码得到布尔数组</h3> + +<p>如果你希望从掩码得到得到 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Boolean</a></code> <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Array" title="/en-US/docs/JavaScript/Reference/Global_Objects/Array">Array</a></code> :</p> + +<pre class="brush: js">function arrayFromMask (nMask) { + // nMask 必须介于 -2147483648 和 2147483647 之间 + if (nMask > 0x7fffffff || nMask < -0x80000000) { + throw new TypeError("arrayFromMask - out of range"); + } + for (var nShifted = nMask, aFromMask = []; nShifted; + aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1); + return aFromMask; +} + +var array1 = arrayFromMask(11); +var array2 = arrayFromMask(4); +var array3 = arrayFromMask(1); + +alert("[" + array1.join(", ") + "]"); +// 打印 "[true, true, false, true]", i.e.: 11, i.e.: 1011 +</pre> + +<p>你可以同时测试以上两个算法……</p> + +<pre class="brush: js">var nTest = 19; // our custom mask +var nResult = createMask.apply(this, arrayFromMask(nTest)); + +alert(nResult); // 19 +</pre> + +<p>仅仅由于教学目的 (因为有 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString">Number.toString(2)</a></code> 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:</p> + +<pre class="brush: js">function createBinaryString (nMask) { + // nMask must be between -2147483648 and 2147483647 + for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32; + nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1); + return sMask; +} + +var string1 = createBinaryString(11); +var string2 = createBinaryString(4); +var string3 = createBinaryString(1); + +alert(string1); +// 打印 00000000000000000000000000001011, i.e. 11 +</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>ECMAScript 1st Edition.</td> + <td>Standard</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}<br> + {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}<br> + {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}<br> + {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}<br> + {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td><a href="#Bitwise_NOT">Bitwise NOT (<code>~</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_AND">Bitwise AND (<code>&</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_OR">Bitwise OR (<code>|</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_XOR">Bitwise XOR (<code>^</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Left_shift">Left shift (<code><<</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Right_shift">Right shift (<code>>></code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Unsigned_right_shift">Unsigned right shift (<code>>>></code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td><a href="#Bitwise_NOT">Bitwise NOT (<code>~</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_AND">Bitwise AND (<code>&</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_OR">Bitwise OR (<code>|</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Bitwise_XOR">Bitwise XOR (<code>^</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Left_shift">Left shift (<code><<</code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Right_shift">Right shift (<code>>></code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + <tr> + <td><a href="#Unsigned_right_shift">Unsigned right shift (<code>>>></code>)</a></td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">Logical operators</a></li> + <li> + <p><strong>js ^</strong> & <strong>Bitwise Operators</strong></p> + </li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html new file mode 100644 index 0000000000..dcd9c54de0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html @@ -0,0 +1,108 @@ +--- +title: Bitwise OR (|) +slug: Web/JavaScript/Reference/Operators/Bitwise_OR +translation_of: Web/JavaScript/Reference/Operators/Bitwise_OR +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The bitwise OR operator (<code>|</code>) returns a <code>1</code> in each bit position for which the corresponding bits of either or both operands are <code>1</code>s.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-or.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> | <var>b</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer:</p> + +<pre class="brush: js notranslate">Before: 11100110111110100000000000000110000000000001 +After: 10100000000000000110000000000001</pre> + +<p>Each bit in the first operand is paired with the corresponding bit in the second operand: <em>first bit</em> to <em>first bit</em>, <em>second bit</em> to <em>second bit</em>, and so on.</p> + +<p>The operator is applied to each pair of bits, and the result is constructed bitwise.</p> + +<p>The truth table for the OR operation is:</p> + +<table class="standard-table"> + <thead> + <tr> + <th class="header" scope="col">a</th> + <th class="header" scope="col">b</th> + <th class="header" scope="col">a OR b</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>1</td> + </tr> + </tbody> +</table> + +<pre class="brush: js notranslate">. 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10) +</pre> + +<p>Bitwise ORing any number <code><var>x</var></code> with <code>0</code> yields <code><var>x</var></code>.</p> + +<h2 id="例子">例子</h2> + +<h3 id="Using_bitwise_OR">Using bitwise OR</h3> + +<pre class="brush: js notranslate">// 9 (00000000000000000000000000001001) +// 14 (00000000000000000000000000001110) + +14 | 9; +// 15 (00000000000000000000000000001111)</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-BitwiseORExpression', 'Bitwise OR expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.bitwise_or")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR_assignment">Bitwise OR assignment operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html new file mode 100644 index 0000000000..752a80154a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html @@ -0,0 +1,57 @@ +--- +title: Bitwise OR assignment (|=) +slug: Web/JavaScript/Reference/Operators/Bitwise_OR_assignment +translation_of: Web/JavaScript/Reference/Operators/Bitwise_OR_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The bitwise OR assignment operator (<code>|=</code>) uses the binary representation of both operands, does a bitwise OR operation on them and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-or-assignment.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x |= y +<strong>Meaning:</strong> x = x | y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_bitwise_OR_assignment">Using bitwise OR assignment</h3> + +<pre class="brush: js notranslate">let a = 5; +a |= 2; // 7 +// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +// ----------------------------------- +// 7: 00000000000000000000000000000111</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.bitwise_or_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR">Bitwise OR operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment">Logical OR assignment (<code>||=</code>)</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html new file mode 100644 index 0000000000..4bb149667d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html @@ -0,0 +1,108 @@ +--- +title: Bitwise XOR (^) +slug: Web/JavaScript/Reference/Operators/Bitwise_XOR +translation_of: Web/JavaScript/Reference/Operators/Bitwise_XOR +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The bitwise XOR operator (<code>^</code>) returns a <code>1</code> in each bit position for which the corresponding bits of either but not both operands are <code>1</code>s.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> ^ <var>b</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer:</p> + +<pre class="brush: js notranslate">Before: 11100110111110100000000000000110000000000001 +After: 10100000000000000110000000000001</pre> + +<p>Each bit in the first operand is paired with the corresponding bit in the second operand: <em>first bit</em> to <em>first bit</em>, <em>second bit</em> to <em>second bit</em>, and so on.</p> + +<p>The operator is applied to each pair of bits, and the result is constructed bitwise.</p> + +<p>The truth table for the XOR operation is:</p> + +<table class="standard-table"> + <thead> + <tr> + <th class="header" scope="col">a</th> + <th class="header" scope="col">b</th> + <th class="header" scope="col">a XOR b</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>1</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>0</td> + </tr> + </tbody> +</table> + +<pre class="brush: js notranslate">. 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10) +</pre> + +<p>Bitwise XORing any number <code><var>x</var></code> with <code>0</code> yields <code><var>x</var></code>.</p> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_bitwise_XOR">Using bitwise XOR</h3> + +<pre class="brush: js notranslate">// 9 (00000000000000000000000000001001) +// 14 (00000000000000000000000000001110) + +14 ^ 9; +// 7 (00000000000000000000000000000111)</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-BitwiseXORExpression', 'Bitwise XOR expression')}}</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 class="external" 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.operators.bitwise_xor")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment">Bitwise XOR assignment operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html new file mode 100644 index 0000000000..7257e9cdb5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html @@ -0,0 +1,65 @@ +--- +title: 按位异或赋值 (^=) +slug: Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment +translation_of: Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>按位异或赋值操作符 (<code>^=</code>) 使用二进制表示操作数,进行一次按位异或操作并赋值。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x ^= y +<strong>Meaning:</strong> x = x ^ y</pre> + +<h2 id="例子">例子</h2> + +<h3 id="使用按位异或赋值">使用按位异或赋值</h3> + +<pre class="brush: js notranslate">let a = 5; // 00000000000000000000000000000101 +a ^= 3; // 00000000000000000000000000000011 + +console.log(a); // 00000000000000000000000000000110 +// 6 + +let b = 5; // 00000000000000000000000000000101 +b ^= 0; // 00000000000000000000000000000000 + +console.log(b); // 00000000000000000000000000000101 +// 5 + + + +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.bitwise_xor_assignment")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR">Bitwise XOR operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/class/index.html b/files/zh-cn/web/javascript/reference/operators/class/index.html new file mode 100644 index 0000000000..739c651513 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/class/index.html @@ -0,0 +1,112 @@ +--- +title: 类表达式 +slug: Web/JavaScript/Reference/Operators/class +tags: + - Class + - Classes + - ES6 +translation_of: Web/JavaScript/Reference/Operators/class +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>类表达式</strong>是用来定义类的一种语法。和<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/function">函数表达式</a>相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。JavaScript 的类也是基于原型继承的。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">const MyClass = class <em>[className]</em> [extends] { + // class body +};</pre> + +<h2 id="描述">描述</h2> + +<p>类表达式的语法和<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/class">类语句</a>的语法很类似,只是在类表达式中,你可以省略掉类名,而类语句中不能。</p> + +<p>和类声明一样,类表达式中的代码也是强制<a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>的。</p> + +<h2 id="示例">示例</h2> + +<h3 id="使用类表达式">使用类表达式</h3> + +<p>下面的代码使用类表达式语法创建了一个匿名类,然后赋值给变量 Foo。</p> + +<pre class="brush: js">let Foo = class { + constructor() {} + bar() { + return "Hello World!"; + } +}; + +let instance = new Foo(); +instance.bar(); +// "Hello World!" +</pre> + +<h3 id="命名类表达式">命名类表达式</h3> + +<p>如果你想在类体内部也能引用这个类本身,那么你就可以使用命名类表达式,并且这个类名只能在类体内部访问。</p> + +<pre class="brush: js">const Foo = class NamedFoo { + constructor() {} + whoIsThere() { + return NamedFoo.name; + } +} + +let bar = new Foo(); + +bar.whoIsThere(); +// "NamedFoo" + +NamedFoo.name; +// ReferenceError: NamedFoo is not defined + +Foo.name; +// "NamedFoo" + +</pre> + +<h2 id="规范">规范</h2> + +<table> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}</td> + <td>{{Spec2('ES2016')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}</td> + <td>{{Spec2('ES2017')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.class")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/function"><code>函数表达式</code></a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/class"><code>类语句</code></a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Classes">类</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html b/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html new file mode 100644 index 0000000000..0636731b0b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/comma_operator/index.html @@ -0,0 +1,84 @@ +--- +title: 逗号操作符 +slug: Web/JavaScript/Reference/Operators/Comma_Operator +tags: + - comma operator + - 逗号操作符 +translation_of: Web/JavaScript/Reference/Operators/Comma_Operator +--- +<div> +<div>{{jsSidebar("Operators")}}</div> +</div> + +<p><strong>逗号操作符 </strong> 对它的每个操作数求值(从左到右),并返回最后一个操作数的值。</p> + +<p>{{EmbedInteractiveExample("pages/js/expressions-commaoperators.html")}}</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox"><em>expr1</em>, <em>expr2, expr3...</em></pre> + +<h2 id="参数">参数</h2> + +<dl> + <dt><code>expr1</code>, <code>expr2, expr3...</code></dt> + <dd>任一表达式。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>当你想要在期望一个表达式的位置包含多个表达式时,可以使用逗号操作符。这个操作符最常用的一种情况是:<code>for</code> 循环中提供多个参数。</p> + +<h2 id="示例">示例</h2> + +<p>假设 <code>a</code> 是一个二维数组,每一维度包含10个元素,则下面的代码使用逗号操作符一次递增/递减两个变量。需要注意的是,<code>var</code> 语句中的逗号<em><strong>不是</strong></em>逗号操作符,因为它不是存在于一个表达式中。尽管从实际效果来看,那个逗号同逗号运算符的表现很相似。但确切地说,它是 <code style="font-style: normal;">var</code> 语句中的一个特殊符号,用于把多个变量声明结合成一个。下面的代码打印一个二维数组中斜线方向的元素:</p> + +<pre class="brush:js;highlight:[1]">for (var i = 0, j = 9; i <= 9; i++, j--) + document.writeln("a[" + i + "][" + j + "] = " + a[i][j]);</pre> + +<h3 id="处理后返回">处理后返回</h3> + +<p>另一个使用逗号操作符的例子是在返回值前处理一些操作。如同下面的代码,只有最后一个表达式被返回,其他的都只是被求值。</p> + +<pre>function myFunc () { + var x = 0; + + return (x += 1, x); // the same of return ++x; +}</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>ECMAScript 1st Edition.</td> + <td>Standard</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{Compat("javascript.operators.comma")}}</p> + +<h2 id="See_also" name="See_also">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for loop</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html b/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html new file mode 100644 index 0000000000..d05ce68abd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html @@ -0,0 +1,277 @@ +--- +title: 比较操作符 +slug: Web/JavaScript/Reference/Operators/Comparison_Operators +tags: + - 严格比较操作符 + - 比较操作符 +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符。对于严格比较运算符(===)来说,仅当两个操作数的类型相同且值相等为 true,而对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。</p> + +<p>字符串比较则是使用基于标准字典的 Unicode 值来进行比较的。</p> + +<p>比较的特点:</p> + +<ul> + <li>对于两个拥有相同字符顺序,相同长度,并且每个字符的位置都匹配的字符串,应该使用严格比较运算符。</li> + <li><span style="line-height: 1.5;"> 对于两个数值相同的数字应该使用严格比较运算符,NaN和任何值不相等,包括其自身,正数零等于负数零。</span></li> + <li>对于两个同为true或同为false的布尔操作数,应使用严格比较运算符。</li> + <li>不要使用严格比较运算符或比较运算符来比较两个不相等的对象。</li> + <li>当比较一个表达式和一个对象时,仅当两个操作数引用相同的对象(指针指向相同对象)。</li> + <li>对于Null 和 Undefined 类型而言,应使用严格比较运算符比较其自身,使用比较运算符进行互相比较。</li> +</ul> + +<h2 id="相等运算符">相等运算符</h2> + +<h3 id="相等()">相等(==)</h3> + +<p>比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。</p> + +<h4 id="语法">语法</h4> + +<pre class="syntaxbox">x == y +</pre> + +<h4 id="例子">例子</h4> + +<pre class="brush: js"> 1 == 1 // true +"1" == 1 // true + 1 == '1' // true + 0 == false // true +</pre> + +<h3 id="不相等_(!)"><a name="Inequality">不相等 (!=)</a></h3> + +<p>不等操作符仅当操作数不相等时返回true,如果两操作数不是同一类型,JavaScript会尝试将其转为一个合适的类型,然后进行比较。如果两操作数为对象类型,JavaScript会比较其内部引用地址,仅当他们在内存中引用不同对象时不相等。</p> + +<h4 id="语法_2">语法</h4> + +<pre class="syntaxbox">x != y</pre> + +<h4 id="例子_2">例子</h4> + +<pre class="brush: js">1 != 2 // true +1 != "1" // false +1 != '1' // false +1 != true // false +0 != false // false +</pre> + +<h3 id="一致严格相等_()"><a name="Identity">一致/严格相等 (===)</a></h3> + +<p>一致运算符不会进行类型转换,仅当操作数严格相等时返回true</p> + +<h4 id="语法_3">语法</h4> + +<pre class="syntaxbox">x === y</pre> + +<h4 id="例子_3">例子</h4> + +<pre class="brush: js ">3 === 3 // true +3 === '3' // false +var object1 = {"value":"key"}, object2={"value":"key"}; +object1 === object2 //false</pre> + +<h3 id="不一致严格不相等_(!)"><a name="Nonidentity">不一致/严格不相等 (!==)</a></h3> + +<p>不一致运算符当操作数不相等或不同类型时返回true</p> + +<h4 id="语法_4">语法</h4> + +<pre class="syntaxbox">x !== y</pre> + +<h4 id="例子_4">例子</h4> + +<pre class="brush: js">3 !== '3' // true +4 !== 3 // true +</pre> + +<h2 id="关系运算符">关系运算符</h2> + +<h3 id="大于运算符_(>)"><a name="Greater_than_operator">大于运算符 (>)</a></h3> + +<p>大于运算符仅当左操作数大于右操作数时返回true</p> + +<h4 id="语法_5">语法</h4> + +<pre class="syntaxbox">x > y</pre> + +<h4 id="例子_5">例子</h4> + +<pre class="brush: js">4 > 3 // true +</pre> + +<h3 id="大于等于运算符_(>)"><a name="Greater_than_or_equal_operator">大于等于运算符 (>=)</a></h3> + +<p>大于等于运算符当左操作数大于或等于右操作数时返回true</p> + +<h4 id="语法_6">语法</h4> + +<pre class="syntaxbox"> x >= y</pre> + +<h4 id="例子_6">例子</h4> + +<pre class="brush: js">4 >= 3 // true +3 >= 3 // true +</pre> + +<h3 id="小于运算符_(<)"><a name="Less_than_operator">小于运算符 (<)</a></h3> + +<p>小于运算符仅当左操作数小于右操作数时返回true</p> + +<h4 id="语法_7">语法</h4> + +<pre class="syntaxbox"> x < y</pre> + +<h4 id="例子_7">例子</h4> + +<pre class="brush: js">3 < 4 // true +</pre> + +<h3 id="小于等于运算符_(<)"><a id="Less_than_or_equal_operator" name="Less_than_or_equal_operator">小于等于运算符 (<=)</a></h3> + +<p>小于等于运算符当左操作数小于或等于右操作数时返回true</p> + +<h4 id="语法_8">语法</h4> + +<pre class="syntaxbox"> x <= y</pre> + +<h4 id="例子_8">例子</h4> + +<pre class="brush: js">3 <= 4 // true +</pre> + +<h2 id="使用比较操作符">使用比较操作符</h2> + +<p>标准相等操作符(<code>==</code> and <code>!=</code>) 使用 <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3">Abstract Equality Comparison Algorithm</a> 去比较两个操作数。当两个操作数类型不相等时,会在比较前尝试将其转换为相同类型。 e.g., 对于表达式 <code>5 == '5'</code>, 在比较前会先将右边字符串类型的操作数 5 转换为数字。</p> + +<p>严格相等操作符 (<code>===</code> and <code>!==</code>) 使用 Strict Equality Comparison Algorithm 并尝试对两个相同操作数进行相等比较,如果它们的类型不相等,那么永远会返回false 所以 <code>5 !== '5'。</code></p> + +<p>当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。</p> + +<p>当比较运算涉及类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:</p> + +<ul> + <li>当比较数字和字符串时,字符串会转换成数字值。 JavaScript 尝试将数字字面量转换为数字类型的值。 首先, 一个数学上的值会从数字字面量中衍生出来,然后这个值将被转为一个最接近的<code>Number</code>类型的值。</li> + <li>如果其中一个操作数为布尔类型,那么布尔操作数如果为true,那么会转换为1,如果为false,会转换为整数0,即0。</li> + <li>如果一个对象与数字或字符串相比较,JavaScript会尝试返回对象的默认值。操作符会尝试通过方法valueOf和toString将对象转换为其原始值(一个字符串或数字类型的值)。如果尝试转换失败,会产生一个运行时错误。</li> + <li>注意:当且仅当与原始值比较时,对象会被转换为原始值。当两个操作数均为对象时,它们作为对象进行比较,仅当它们引用相同对象时返回true。</li> +</ul> + +<div class="note"><strong>注意:</strong> 字符串对象的类型是对象,不是字符串!字符串对象很少被使用,所以下面的结果也许会让你惊讶:</div> + +<pre class="brush:js">// true as both operands are Type String (i.e. string primitives): +'foo' === 'foo' + +var a = new String('foo'); +var b = new String('foo'); + +// false as a and b are Type Object and reference different objects +a == b + +// false as a and b are Type Object and reference different objects +a === b + +// true as a and 'foo' are of different type and, the Object (a) +// is converted to String 'foo' before comparison +a == 'foo' </pre> + +<h2 id="Specifications">Specifications</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>ECMAScript 1st Edition.</td> + <td>Standard</td> + <td>Initial definition. Implemented in JavaScript 1.0</td> + </tr> + <tr> + <td>ECMAScript 3rd Edition.</td> + <td>Standard</td> + <td>Adds <code>===</code> and <code>!==</code> operators. Implemented in JavaScript 1.3</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.8', 'Relational Operators')}}<br> + {{SpecName('ES5.1', '#sec-11.9', 'Equality Operators')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.8">Relational Operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.9">Equality Operators</a></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}<br> + {{SpecName('ES6', '#sec-equality-operators', 'Equality Operators')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-relational-operators">Relational Operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-equality-operators">Equality Operators</a></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Defined in several sections of the specification: <a href="http://tc39.github.io/ecma262/#sec-relational-operators">Relational Operators</a>, <a href="http://tc39.github.io/ecma262/#sec-equality-operators">Equality Operators</a></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Object.is()")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness">Equality comparisons and sameness</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html b/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html new file mode 100644 index 0000000000..179496d7e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html @@ -0,0 +1,126 @@ +--- +title: 条件运算符 +slug: Web/JavaScript/Reference/Operators/Conditional_Operator +tags: + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>条件(三元)运算符</strong>是 JavaScript 仅有的使用三个操作数的运算符。一个条件后面会跟一个问号(?),如果条件为 {{Glossary("truthy")}} ,则问号后面的表达式A将会执行;表达式A后面跟着一个冒号(:),如果条件为 {{Glossary("falsy")}} ,则冒号后面的表达式B将会执行。本运算符经常作为 <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if</a></code> 语句的简捷形式来使用。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-conditionaloperators.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox"><em>condition</em> ? <em>exprIfTrue</em> : <em>exprIfFalse</em></pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code><var>condition</var></code></dt> + <dd>计算结果用作条件的表达式</dd> + <dt><code><var>exprIfTrue</var></code></dt> + <dd>如果表达式 <code><var>condition</var></code> 的计算结果是 {{Glossary("truthy")}}(它和 <code>true</code> 相等或者可以转换成 <code>true</code> ),那么表达式 <code><var>exprIfTrue</var></code> 将会被求值。</dd> + <dt><code><var>exprIfFalse</var></code></dt> + <dd>如果表达式 <code><var>condition</var></code> 的计算结果是 {{Glossary("falsy")}}(它可以转换成 <code>false</code> ),那么表达式 <code><var>exprIfFalse</var></code> 将会被执行。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>除了 <code>false</code>,可能的假值表达式还有:<code>null</code> 、<code>NaN</code> 、 + <code>0</code> 、空字符串( <code>""</code> )、和 <code>undefined</code> 。如果 <code><var>condition</var></code> 是以上中的任何一个, 那么条件表达式的结果就是 <code>exprIfFalse</code> 表达式执行的结果。</p> + +<p>一个简单的例子:</p> + +<pre class="brush: js">var age = 26; +var beverage = (age >= 21) ? "Beer" : "Juice"; +console.log(beverage); // "Beer" +</pre> + +<p>一个常见的用法是处理可能为 <code>null</code> 的值:</p> + +<pre class="brush: js">function greeting(person) { + var name = person ? person.name : "stranger"; + return "Howdy, " + name; +} + +console.log(greeting({name: 'Alice'})); // "Howdy, Alice" +console.log(greeting(null)); // "Howdy, stranger" +</pre> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">The optional chaining operator</a> 设计用来处理这种使用场景。在本文档写成的时候 (2019.01),这个运算符还处于实验阶段并且没有实现。</p> +</div> + +<h3 id="条件链">条件链</h3> + +<p>这个三元操作符是右结合的,也就是说你可以像这样把它链接起来, 和 <code>if … else if … else if … else</code> 链类似:</p> +<pre class="brush: js">function example(…) { + return condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; +} + +// Equivalent to: + +function example(…) { + if (condition1) { return value1; } + else if (condition2) { return value2; } + else if (condition3) { return value3; } + else { return value4; } +} +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.0.</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 class="external" 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.operators.conditional")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if statement</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">Optional chaining</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressions and operators</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/delete/index.html b/files/zh-cn/web/javascript/reference/operators/delete/index.html new file mode 100644 index 0000000000..ce03a46d29 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/delete/index.html @@ -0,0 +1,298 @@ +--- +title: delete 操作符 +slug: Web/JavaScript/Reference/Operators/delete +tags: + - JavaScript + - Operator + - Reference + - delete +translation_of: Web/JavaScript/Reference/Operators/delete +--- +<div>{{jsSidebar("Operators")}}</div> + +<p> <strong><code>delete</code> 操作符</strong>用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。</p> + +<div> +<div>{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}</div> +</div> + + + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox notranslate">delete <em>expression</em> +</pre> + +<p> <em>expression</em> 的计算结果应该是某个属性的引用,例如:</p> + +<pre class="syntaxbox notranslate">delete <em>object.property</em> +delete <em>object</em>['<em>property</em>'] +</pre> + +<h3 id="Parameters" name="Parameters">参数</h3> + +<dl> + <dt><code>object</code></dt> + <dd>对象的名称,或计算结果为对象的表达式。</dd> +</dl> + +<dl> + <dt><code>property</code></dt> + <dd>要删除的属性。</dd> +</dl> + +<h3 id="返回值">返回值</h3> + +<p>对于所有情况都是<code>true</code>,除非属性是一个{{jsxref("Object.hasOwnProperty", "自身的")}} {{jsxref("Errors/Cant_delete", "不可配置")}}的属性,在这种情况下,非严格模式返回 <code>false</code>。</p> + +<h3 id="异常">异常</h3> + +<p>在<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">严格模式</a>下,如果是属性是一个自己不可配置的属性,会抛出{{jsxref("TypeError")}}。</p> + +<h2 id="Description" name="Description">描述</h2> + +<p>与通常的看法不同,<code>delete</code>操作符与直接释放内存<strong>无关</strong>。内存管理 通过断开引用来间接完成的,查看<a href="https://developer.mozilla.org/zh-CNdocs/Web/JavaScript/Memory_Management">内存管理</a>页可了解详情。</p> + +<p><strong><code>delete </code></strong>操作符会从某个对象上移除指定属性。成功删除的时候会返回 <code>true</code>,否则返回 <code>false</code>。</p> + +<p>但是,以下情况需要重点考虑:</p> + +<ul> + <li>如果你试图删除的属性不存在,那么delete将不会起任何作用,但仍会返回true</li> + <li>如果对象的原型链上有一个与待删除属性同名的属性,那么删除属性之后,对象会使用原型链上的那个属性(也就是说,delete操作只会在自身的属性上起作用)</li> + <li>任何使用 {{jsxref("Statements/var","var")}} 声明的属性不能从全局作用域或函数的作用域中删除。 + <ul> + <li>这样的话,delete操作不能删除任何在全局作用域中的函数(无论这个函数是来自于函数声明或函数表达式)</li> + <li>除了在全局作用域中的函数不能被删除,在对象(object)中的函数是能够用delete操作删除的。</li> + </ul> + </li> + <li>任何用{{jsxref("Statements/let","let")}}或{{jsxref("Statements/const","const")}}声明的属性不能够从它被声明的作用域中删除。</li> + <li>不可设置的(Non-configurable)属性不能被移除。这意味着像{{jsxref("Math")}}, {{jsxref("Array")}}, {{jsxref("Object")}}内置对象的属性以及使用{{jsxref("Object.defineProperty()")}}方法设置为不可设置的属性不能被删除。</li> +</ul> + +<p>下面的代码块给出了一个简单的例子:</p> + +<pre class="brush: js notranslate">var Employee = { + age: 28, + name: 'abc', + designation: 'developer' +} + +console.log(delete Employee.name); // returns true +console.log(delete Employee.age); // returns true + +// 当试着删除一个不存在的属性时 +// 同样会返回true +console.log(delete Employee.salary); // returns true</pre> + +<h3 id="不可配置属性">不可配置属性</h3> + +<p>当一个属性被设置为不可设置,delete操作将不会有任何效果,并且会返回false。在严格模式下会抛出语法错误({{jsxref("SyntaxError")}})。</p> + +<pre class="brush: js notranslate">var Employee = {}; +Object.defineProperty(Employee, 'name', {configurable: false}); + +console.log(delete Employee.name); // returns false</pre> + +<p>{{jsxref("Statements/var","var")}}, {{jsxref("Statements/let","let")}}以及{{jsxref("Statements/const","const")}}创建的不可设置的属性不能被delete操作删除。</p> + +<pre class="brush: js notranslate">var nameOther = 'XYZ'; + +// 通过以下方法获取全局属性: +Object.getOwnPropertyDescriptor(window, 'nameOther'); + +// 输出: Object {value: "XYZ", +// writable: true, +// enumerable: true, +// configurable: false} + +// 因为“nameOther”使用var关键词添加, +// 它被设置为不可设置(non-configurable) +delete nameOther; // return false</pre> + +<p>在严格模式下,这样的操作会抛出异常。</p> + +<h3 id="严格模式与非严格模式的对比"><strong>严格模式与非严格模式的对比</strong></h3> + +<p>在严格模式下,如果对一个变量的直接引用、函数的参数或者函数名使用delete操作,将会抛出语法错误({{jsxref("SyntaxError")}})。因此,为避免严格模式下的语法错误,必须以<code>delete object.property</code>或<code>delete object['property']</code>的形式使用delete运算符。</p> + +<pre class="brush: js notranslate">Object.defineProperty(globalThis, 'variable1', { value: 10, configurable: true, }); +Object.defineProperty(globalThis, 'variable2', { value: 10, configurable: false, }); + +console.log(delete variable1); // true + +// SyntaxError in strict mode. +console.log(delete variable2); // false +</pre> + +<pre class="brush: js notranslate">function func(param) { + // SyntaxError in strict mode. + console.log(delete param); // false +} + +// SyntaxError in strict mode. +console.log(delete func); // false +</pre> + +<div class="blockIndicator note"> +<p>下文在英文原版中已删除</p> +</div> + +<p>任何使用var声明的变量都会被标记为不可设置的。在下面的例子中,salary是不可设置的以及不能被删除的。在非严格模式下,下面的delete操作将会返回false。</p> + +<pre class="brush: js notranslate">function Employee() { + delete salary; + var salary; +} + +Employee();</pre> + +<p>让我们来看看相同的代码在严格模式下会有怎样的表现。会抛出一个语法错误( <code>SyntaxError)而不是返回false。</code></p> + +<pre class="brush: js notranslate">"use strict"; + +function Employee() { + delete salary; // SyntaxError + var salary; +} + +// 相似的,任何对任何函数 +// 直接使用delete操作将会抛出语法错误。 + +function DemoFunction() { + //some code +} + +delete DemoFunction; // SyntaxError</pre> + +<h2 id="示例">示例</h2> + +<pre class="brush: js notranslate">// 在全局作用域创建 adminName 属性 +adminName = 'xyz'; + +// 在全局作用域创建 empCount 属性 +// 因为我们使用了 var,它会标记为不可配置。同样 let 或 const 也是不可配置的。 +var empCount = 43; + +EmployeeDetails = { + name: 'xyz', + age: 5, + designation: 'Developer' +}; + +// adminName 是全局作用域的一个属性。 +// 因为它不是用 var 创建的,所在可以删除。 +// 因此,它是可配置的。 +delete adminName; // 返回 true + +// 相反,empCount 是不可配置的, +// 因为创建它时使用了 var。 +delete empCount; // 返回 false + +// delete 可用于删除对象的属性 +delete EmployeeDetails.name; // 返回 true + +// 甚至属性不存在,它也会返回 "true" +delete EmployeeDetails.salary; // 返回 true + +// delete 对内建静态属性不起作用 +delete Math.PI; // 返回 false + +// EmployeeDetails 是全局作用域的一个属性。 +// 因为定义它的时候没有使用 "var",它被标记为可配置。 +delete EmployeeDetails; // 返回 true + +function f() { + var z = 44; + + // delete 对局部变量名不起作用 + delete z; // 返回 false +}</pre> + +<h3 id="delete_和原型链"><code>delete</code> 和原型链</h3> + +<p>在下面的示例中,我们删除一个对象的自己的属性,而原型链上具有相同名称的属性可用:</p> + +<pre class="brush: js notranslate">function Foo() { + this.bar = 10; +} + +Foo.prototype.bar = 42; + +var foo = new Foo(); + +// 返回 true,因为删除的是 foo 对象的自身属性 +delete foo.bar; + +// foo.bar 仍然可用,因为它在原型链上可用。 +console.log(foo.bar); //42 + +// 从原型上删除属性 +delete Foo.prototype.bar; //true + +// 由于已删除“ bar”属性,因此不能再从Foo继承它。 +console.log(foo.bar); //undefined +</pre> + +<h3 id="Deleting_array_elements" name="Deleting_array_elements">删除数组元素</h3> + +<p>当你删除一个数组元素时,数组的长度不受影响。即便你删除了数组的最后一个元素也是如此。</p> + +<p>当用 <code>delete</code> 操作符删除一个数组元素时,被删除的元素已经不再属于该数组。下面的例子中用 <code>delete </code>删除了<code> trees[3]</code>。</p> + +<pre class="brush: js notranslate">var trees = ["redwood","bay","cedar","oak","maple"]; +delete trees[3]; +if (3 in trees) { + // 这里不会执行 +} +</pre> + +<p>如果你想让一个数组元素继续存在但是其值是 <code>undefined</code>,那么可以使用将 <code>undefined</code> 赋值给这个元素而不是使用 <code>delete</code>。下面的例子中,trees[3] 被赋值为 <code>undefined</code>,但该元素仍然存在。</p> + +<pre class="brush: js notranslate">var trees = ["redwood","bay","cedar","oak","maple"]; +trees[3] = undefined; +if (3 in trees) { + // 这里会被执行 +}</pre> + +<p>如果你想通过改变数组的内容来移除一个数组元素,请使用{{jsxref("Array.splice()", "splice()")}} 方法。在下面的例子中,通过使用{{jsxref("Array.splice()", "splice()")}},将trees[3]从数组中移除。</p> + +<pre class="brush: js notranslate">var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +trees.splice(3,1); +console.log(trees); // ["redwood", "bay", "cedar", "maple"] +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.delete")}}</p> + +<h2 id="跨浏览器提示">跨浏览器提示</h2> + +<p>尽管ECMAScript使得对象的迭代顺序依赖于实现,但似乎所有主流浏览器都支持基于最早添加的属性(至少对于不在原型上的属性)的迭代顺序(译注:ES5 标准取消了属性遍历的顺序的规定)。但是,在 IE 中,使用 <code>delete</code> 删除一个属性后,奇怪的事情发生了。在IE中,如果被删除的属性重新被添加,那么遍历时,该属性的顺序会在上次删除前的那个位置,而不是出现在遍历的最后一个。</p> + +<p>如果您想在跨浏览器的环境中使用有序的关联数组,请使用{{jsxref("Map")}}对象(如果有),或使用两个单独的数组来模拟(一个用于键,另一个用于 值),或者建立<span class="short_text" id="result_box" lang="zh-CN"><span>一个</span><span>由单一</span><span>属性</span><span>的</span><span>对象组成的</span><span>数组</span></span>等。</p> + +<h2 id="See_also" name="See_also">参见</h2> + +<ul> + <li><a href="http://perfectionkills.com/understanding-delete/">深入分析 delete</a></li> + <li>{{jsxref("Reflect.deleteProperty()")}}</li> + <li>{{jsxref("Map.prototype.delete()")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html new file mode 100644 index 0000000000..39d57a75d7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html @@ -0,0 +1,431 @@ +--- +title: 解构赋值 +slug: Web/JavaScript/Reference/Operators/Destructuring_assignment +tags: + - ECMAScript 2015 + - JavaScript + - 对象 + - 操作符 + - 数组 + - 结构 + - 赋值 +translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>解构赋值</strong>语法是一种 Javascript 表达式。通过<strong>解构赋值, </strong>可以将属性/值从对象/数组中取出,赋值给其他变量。</p> + +<p>{{EmbedInteractiveExample("pages/js/expressions-destructuringassignment.html")}}</p> + + + +<h2 id="语法">语法</h2> + +<pre class="brush: js">var a, b, rest; +[a, b] = [10, 20]; +console.log(a); // 10 +console.log(b); // 20 + +[a, b, ...rest] = [10, 20, 30, 40, 50]; +console.log(a); // 10 +console.log(b); // 20 +console.log(rest); // [30, 40, 50] + +({ a, b } = { a: 10, b: 20 }); +console.log(a); // 10 +console.log(b); // 20 + + +// Stage 4(已完成)提案中的特性 +({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}); +console.log(a); // 10 +console.log(b); // 20 +console.log(rest); // {c: 30, d: 40} +</pre> + +<h2 id="描述">描述</h2> + +<p>对象和数组逐个对应表达式,或称对象字面量和数组字面量,提供了一种简单的定义一个特定的数据组的方法。</p> + +<pre class="brush: js">var x = [1, 2, 3, 4, 5];</pre> + +<p>解构赋值使用了相同的语法,不同的是在表达式左边定义了要从原变量中取出什么变量。</p> + +<pre class="brush: js">var x = [1, 2, 3, 4, 5]; +var [y, z] = x; +console.log(y); // 1 +console.log(z); // 2 +</pre> + +<p>JavaScript 中,解构赋值的作用类似于 Perl 和 Python 语言中的相似特性。</p> + +<h2 id="解构数组">解构数组</h2> + +<h3 id="变量声明并赋值时的解构">变量声明并赋值时的解构</h3> + +<pre class="brush: js">var foo = ["one", "two", "three"]; + +var [one, two, three] = foo; +console.log(one); // "one" +console.log(two); // "two" +console.log(three); // "three"</pre> + +<h3 id="变量先声明后赋值时的解构">变量先声明后赋值时的解构</h3> + +<p>通过解构分离变量的声明,可以为一个变量赋值。</p> + +<pre class="brush: js">var a, b; + +[a, b] = [1, 2]; +console.log(a); // 1 +console.log(b); // 2</pre> + +<h3 id="默认值">默认值</h3> + +<p>为了防止从数组中取出一个值为<code>undefined</code>的对象,可以在表达式左边的数组中为任意对象预设默认值。</p> + +<pre class="brush: js">var a, b; + +[a=5, b=7] = [1]; +console.log(a); // 1 +console.log(b); // 7</pre> + +<h3 id="交换变量">交换变量</h3> + +<p>在一个解构表达式中可以交换两个变量的值。</p> + +<p>没有解构赋值的情况下,交换两个变量需要一个临时变量(或者用低级语言中的<a class="external" href="http://en.wikipedia.org/wiki/XOR_swap">XOR-swap技巧</a>)。</p> + +<pre class="brush: js">var a = 1; +var b = 3; + +[a, b] = [b, a]; +console.log(a); // 3 +console.log(b); // 1</pre> + +<h3 id="解析一个从函数返回的数组">解析一个从函数返回的数组</h3> + +<p>从一个函数返回一个数组是十分常见的情况。解构使得处理返回值为数组时更加方便。</p> + +<p>在下面例子中,要让 <code>[1, 2]</code> 成为函数的 <code>f()</code> 的输出值,可以使用解构在一行内完成解析。</p> + +<pre class="brush: js">function f() { + return [1, 2]; +} + +var a, b; +[a, b] = f(); +console.log(a); // 1 +console.log(b); // 2 +</pre> + +<h3 id="忽略某些返回值">忽略某些返回值</h3> + +<p>你也可以忽略你不感兴趣的返回值:</p> + +<pre class="brush:js">function f() { + return [1, 2, 3]; +} + +var [a, , b] = f(); +console.log(a); // 1 +console.log(b); // 3</pre> + +<p>你也可以忽略全部返回值:</p> + +<pre class="brush:js">[,,] = f(); +</pre> + +<h3 id="将剩余数组赋值给一个变量">将剩余数组赋值给一个变量</h3> + +<p>当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。</p> + +<pre class="brush: js">var [a, ...b] = [1, 2, 3]; +console.log(a); // 1 +console.log(b); // [2, 3]</pre> + +<p>注意:如果剩余元素右侧有逗号,会抛出 {{jsxref("SyntaxError")}},因为剩余元素必须是数组的最后一个元素。</p> + +<pre class="brush: js example-bad">var [a, ...b,] = [1, 2, 3]; +// SyntaxError: rest element may not have a trailing comma</pre> + +<h3 id="用正则表达式匹配提取值">用正则表达式匹配提取值</h3> + +<p>用正则表达式的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec">exec()</a></code> 方法匹配字符串会返回一个数组,该数组第一个值是完全匹配正则表达式的字符串,然后的值是匹配正则表达式括号内内容部分。解构赋值允许你轻易地提取出需要的部分,忽略完全匹配的字符串——如果不需要的话。</p> + +<pre class="brush: js">function parseProtocol(url) { + var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); + if (!parsedURL) { + return false; + } + console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"] + + var [, protocol, fullhost, fullpath] = parsedURL; + return protocol; +} + +console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https" +</pre> + +<h2 id="解构对象">解构对象</h2> + +<h3 id="基本赋值">基本赋值</h3> + +<pre class="brush: js">var o = {p: 42, q: true}; +var {p, q} = o; + +console.log(p); // 42 +console.log(q); // true +</pre> + +<h3 id="无声明赋值">无声明赋值</h3> + +<p>一个变量可以独立于其声明进行解构赋值。</p> + +<pre class="brush: js">var a, b; + +({a, b} = {a: 1, b: 2}); +</pre> + +<div class="note"> +<p><strong>注意</strong>:赋值语句周围的圆括号 <code>( ... )</code> 在使用对象字面量无声明解构赋值时是必须的。</p> + +<p><code>{a, b} = {a: 1, b: 2}</code> 不是有效的独立语法,因为左边的 <code>{a, b}</code> 被认为是一个块而不是对象字面量。</p> + +<p>然而,<code>({a, b} = {a: 1, b: 2})</code> 是有效的,正如 <code>var {a, b} = {a: 1, b: 2}</code></p> + +<p>你的 <code>( ... )</code> 表达式之前需要有一个分号,否则它可能会被当成上一行中的函数执行。</p> +</div> + +<h3 id="给新的变量名赋值">给新的变量名赋值</h3> + +<p>可以从一个对象中提取变量并赋值给和对象属性名不同的新的变量名。</p> + +<pre class="brush: js">var o = {p: 42, q: true}; +var {p: foo, q: bar} = o; + +console.log(foo); // 42 +console.log(bar); // true </pre> + +<h3 id="默认值_2">默认值</h3> + +<p>变量可以先赋予默认值。当要提取的对象没有对应的属性,变量就被赋予默认值。</p> + +<pre class="brush: js">var {a = 10, b = 5} = {a: 3}; + +console.log(a); // 3 +console.log(b); // 5 +</pre> + +<h3 id="给新的变量命名并提供默认值">给新的变量命名并提供默认值</h3> + +<p>一个属性可以同时 1)从一个对象解构,并分配给一个不同名称的变量 2)分配一个默认值,以防未解构的值是 <code>undefined</code>。</p> + +<pre class="brush: js">var {a:aa = 10, b:bb = 5} = {a: 3}; + +console.log(aa); // 3 +console.log(bb); // 5 +</pre> + +<h3 id="函数参数默认值">函数参数默认值</h3> + +<h4 id="ES5_版本">ES5 版本</h4> + +<pre class="brush: js">function drawES5Chart(options) { + options = options === undefined ? {} : options; + var size = options.size === undefined ? 'big' : options.size; + var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords; + var radius = options.radius === undefined ? 25 : options.radius; + console.log(size, cords, radius); + // now finally do some chart drawing +} + +drawES5Chart({ + cords: { x: 18, y: 30 }, + radius: 30 +});</pre> + +<h4 id="ES2015_版本">ES2015 版本</h4> + +<pre class="brush: js">function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) +{ + console.log(size, cords, radius); + // do some chart drawing +} + +drawES2015Chart({ + cords: { x: 18, y: 30 }, + radius: 30 +});</pre> + +<div class="note"> +<p>在上面的 <strong><code>drawES2015Chart</code></strong> 的函数签名中,解构的左手边被分配给右手边的空对象字面值:<code>{size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}</code>。你也可以在没有右侧分配的情况下编写函数。但是,如果你忽略了右边的赋值,那么函数会在被调用的时候查找至少一个被提供的参数,而在当前的形式下,你可以直接调用 <code><strong>drawES2015Chart()</strong></code> 而不提供任何参数。如果你希望能够在不提供任何参数的情况下调用该函数,则当前的设计非常有用,而另一种方法在您确保将对象传递给函数时非常有用。</p> +</div> + +<h3 id="解构嵌套对象和数组">解构嵌套对象和数组</h3> + +<pre class="brush:js">const metadata = { + title: 'Scratchpad', + translations: [ + { + locale: 'de', + localization_tags: [], + last_edit: '2014-04-14T08:43:37', + url: '/de/docs/Tools/Scratchpad', + title: 'JavaScript-Umgebung' + } + ], + url: '/en-US/docs/Tools/Scratchpad' +}; + +let { + title: englishTitle, // rename + translations: [ + { + title: localeTitle, // rename + }, + ], +} = metadata; + +console.log(englishTitle); // "Scratchpad" +console.log(localeTitle); // "JavaScript-Umgebung"</pre> + +<h3 id="For_of_迭代和解构">For of 迭代和解构</h3> + +<pre class="brush: js">var people = [ + { + name: 'Mike Smith', + family: { + mother: 'Jane Smith', + father: 'Harry Smith', + sister: 'Samantha Smith' + }, + age: 35 + }, + { + name: 'Tom Jones', + family: { + mother: 'Norah Jones', + father: 'Richard Jones', + brother: 'Howard Jones' + }, + age: 25 + } +]; + +for (var {name: n, family: {father: f}} of people) { + console.log('Name: ' + n + ', Father: ' + f); +} + +// "Name: Mike Smith, Father: Harry Smith" +// "Name: Tom Jones, Father: Richard Jones"</pre> + +<h3 id="从作为函数实参的对象中提取数据">从作为函数实参的对象中提取数据</h3> + +<pre class="brush:js">function userId({id}) { + return id; +} + +function whois({displayName: displayName, fullName: {firstName: name}}){ + console.log(displayName + " is " + name); +} + +var user = { + id: 42, + displayName: "jdoe", + fullName: { + firstName: "John", + lastName: "Doe" + } +}; + +console.log("userId: " + userId(user)); // "userId: 42" +whois(user); // "jdoe is John"</pre> + +<p>这段代码从user对象中提取并输出<code>id<font face="Open Sans, Arial, sans-serif">、</font></code><code>displayName</code> 和 <code>firstName</code>。</p> + +<h3 id="对象属性计算名和解构">对象属性计算名和解构</h3> + +<p>计算属性名,如 <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names">object literals</a>,可以被解构。</p> + +<pre class="brush: js">let key = "z"; +let { [key]: foo } = { z: "bar" }; + +console.log(foo); // "bar" +</pre> + +<h3 id="对象解构中的_Rest">对象解构中的 Rest</h3> + +<p><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript</a> 提案(阶段 4)将 <a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest</a> 语法添加到解构中。Rest 属性收集那些尚未被解构模式拾取的剩余可枚举属性键。</p> + +<pre class="brush: js">let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40} +a; // 10 +b; // 20 +rest; // { c: 30, d: 40 }</pre> + +<h3 id="无效的_JavaScript_标识符作为属性名称">无效的 JavaScript 标识符作为属性名称</h3> + +<p>通过提供有效的替代标识符,解构可以与不是有效的JavaScript<a href="/zh-CN/docs/Glossary/Identifier">标识符</a>的属性名称一起使用。</p> + +<pre class="brush: js">const foo = { 'fizz-buzz': true }; +const { 'fizz-buzz': fizzBuzz } = foo; + +console.log(fizzBuzz); // "true" +</pre> + +<h3 id="解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)">解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)</h3> + +<pre class="brush: js">// 声明对象 和 自身 self 属性 +var obj = {self: '123'}; +// 在原型链中定义一个属性 prot +obj.__proto__.prot = '456'; +// test +const {self, prot} = obj; +// self "123" +// prot "456"(访问到了原型链)</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('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></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.operators.destructuring")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators">赋值操作符</a></li> + <li><a href="https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/">"ES6 in Depth: Destructuring" on hacks.mozilla.org</a></li> +</ul> + +<h3 id="译者注:关于_42">译者注:关于 42</h3> + +<p>为什么在示例代码中出现了那么多 42?如果有什么特别的原因的话,以下是译者的猜测。</p> + +<ul> + <li><a class="external-icon" href="https://zh.wikipedia.org/wiki/42#%E5%9C%A8%E4%BA%BA%E7%B1%BB%E6%96%87%E5%8C%96%E4%B8%AD">42#在人类文化中 - 维基百科</a></li> + <li><a class="external-icon" href="https://zh.wikipedia.org/wiki/%E7%94%9F%E5%91%BD%E3%80%81%E5%AE%87%E5%AE%99%E4%BB%A5%E5%8F%8A%E4%BB%BB%E4%BD%95%E4%BA%8B%E6%83%85%E7%9A%84%E7%B5%82%E6%A5%B5%E7%AD%94%E6%A1%88">生命、宇宙以及任何事情的终极答案 - 维基百科</a></li> + <li><a class="external-icon" href="https://en.wikipedia.org/wiki/42_(number)#The_Hitchhiker's_Guide_to_the_Galaxy">42_(number)#The Hitchhiker's Guide to the Galaxy - Wikipedia</a></li> + <li><a class="external-icon" href="https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life,_the_Universe,_and_Everything_(42)">Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life,_the_Universe,_and_Everything_(42) - Wikipedia</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/division/index.html b/files/zh-cn/web/javascript/reference/operators/division/index.html new file mode 100644 index 0000000000..8bfc53db1f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/division/index.html @@ -0,0 +1,76 @@ +--- +title: 除法 (/) +slug: Web/JavaScript/Reference/Operators/Division +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Division +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>除法运算符 (<code>/</code>) 计算了两个操作数的商,左边的数是被除数,右边的是除数</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-division.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>x</var> / <var>y</var> +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="基本除法">基本除法</h3> + +<pre class="brush: js notranslate">1 / 2 // 0.5 + +Math.floor(3 / 2) // 1 + +1.0 / 2.0 // 0.5 +</pre> + +<h3 id="除以0">除以0</h3> + +<pre class="brush: js notranslate">2.0 / 0 // Infinity + +2.0 / 0.0 // Infinity, because 0.0 === 0 + +2.0 / -0.0 // -Infinity</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Division operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.division")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html new file mode 100644 index 0000000000..25f93e997b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/division_assignment/index.html @@ -0,0 +1,58 @@ +--- +title: Division assignment (/=) +slug: Web/JavaScript/Reference/Operators/Division_assignment +translation_of: Web/JavaScript/Reference/Operators/Division_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The division assignment operator (<code>/=</code>) divides a variable by the value of the right operand and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-division-assignment.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x /= y +<strong>Meaning:</strong> x = x / y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_division_assignment">Using division assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variable +// bar = 5 + +bar /= 2 // 2.5 +bar /= 'foo' // NaN +bar /= 0 // Infinity</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.division_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html b/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html new file mode 100644 index 0000000000..e9299d7f8f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/exponentiation/index.html @@ -0,0 +1,107 @@ +--- +title: 求幂 (**) +slug: Web/JavaScript/Reference/Operators/Exponentiation +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Exponentiation +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><font><font>求幂运算符(</font></font><code>**</code><font><font>)返回将第一个操作数加到第二个操作数</font><font>的幂</font><font>的结果。</font><font>它等效于</font></font><code>Math.pow</code><font><font>,不同之处在于它也接受BigInts作为操作数。</font></font></p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-exponentiation.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>var1</var> ** <var>var2</var> +</pre> + +<h2 id="简介">简介</h2> + +<p>求幂运算符是是<strong>右结合的</strong>: <code><var>a</var> ** <var>b</var> ** <var>c</var></code> 等于 <code><var>a</var> ** (<var>b</var> ** <var>c</var>)</code>.</p> + +<p>在大多数语言里,比如PHP、Python等那些有一个幂运算符 (<code>**</code>) 的语言,幂运算符被定义有一个比一元运算符,比如一元的 <code>+</code> 和一元的 <code>-</code> 更高的运算顺序,但有一些例外。在Bash语言里,<code>**</code> 运算符被定义有一个比一元运算符更低的运算顺序。</p> + +<p>在JavaScript里,你不可能写出一个不明确的求幂表达式。这就是说,你不能立刻将一个一元运算符(<code>+/-/~/!/delete/void/typeof</code>)放在基数前,这样做只会导致一个语法错误。</p> + +<pre class="brush: js notranslate">-2 ** 2; +// 4 in Bash, -4 in other languages. +// This is invalid in JavaScript, as the operation is ambiguous. + + +-(2 ** 2); +// -4 in JavaScript and the author's intention is unambiguous. +</pre> + +<p>注意有些编程语言用扬抑符 <kbd>^</kbd> 做乘方运算,但是JavaScript将这个符号作为了<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR">XOR位逻辑运算符</a>。</p> + +<h2 id="例子">例子</h2> + +<h3 id="基本求幂">基本求幂</h3> + +<pre class="brush: js notranslate">2 ** 3 // 8 +3 ** 2 // 9 +3 ** 2.5 // 15.588457268119896 +10 ** -1 // 0.1 +NaN ** 2 // NaN +</pre> + +<h3 id="结合">结合</h3> + +<pre class="brush: js notranslate">2 ** 3 ** 2 // 512 +2 ** (3 ** 2) // 512 +(2 ** 3) ** 2 // 64</pre> + +<h3 id="与一元运算符的用法">与一元运算符的用法</h3> + +<p>取求幂表达式的值的相反数:</p> + +<pre class="brush: js notranslate">-(2 ** 2) // -4 +</pre> + +<p>将求幂表达式的底数转化为一个负数:</p> + +<pre class="brush: js notranslate">(-2) ** 2 // 4 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-exp-operator', 'Exponentiation operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器支持">浏览器支持</h2> + + + +<p>{{Compat("javascript.operators.exponentiation")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html new file mode 100644 index 0000000000..12f77694c7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Exponentiation assignment (**=) +slug: Web/JavaScript/Reference/Operators/Exponentiation_assignment +translation_of: Web/JavaScript/Reference/Operators/Exponentiation_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The exponentiation assignment operator (<code>**=</code>) raises the value of a variable to the power of the right operand.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-exponentiation-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x **= y +<strong>Meaning:</strong> x = x ** y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_exponentiation_assignment">Using exponentiation assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variable +// bar = 5 + +bar **= 2 // 25 +bar **= 'foo' // NaN</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.exponentiation_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html b/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html new file mode 100644 index 0000000000..e5dee577bc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html @@ -0,0 +1,76 @@ +--- +title: Expression closures +slug: Web/JavaScript/Reference/Operators/Expression_closures +tags: + - Functions + - JavaScript + - Reference +translation_of: Archive/Web/JavaScript/Expression_closures +--- +<div class="warning"><strong>非标准,不要使用!</strong><br> +闭包表达式语法是废弃的 SpiderMonkey 的特性,并且<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1083458">将被移除</a>。为了长远使用,考虑使用<a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a>。</div> + +<div>{{jsSidebar("Operators")}}</div> + +<p>表达式闭包是定义简单函数的一种便捷方式。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">function [<em>name</em>]([<em>param1</em>[, <em>param2[</em>, ..., <em>paramN</em>]]]) + <em>expression</em> +</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>name</code></dt> + <dd>函数名。函数名可以省略不写,称为匿名函数。函数名仅在函数体有效。</dd> + <dt><code>paramN</code></dt> + <dd>形参名。一个函数最多可以有255个参数。</dd> + <dt><code>expression</code></dt> + <dd>构成函数体的表达式。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>这一附加特性只是编写简单函数的快捷方式,让语言更类似通常的 <a class="external" href="http://en.wikipedia.org/wiki/Lambda_calculus#Lambda_calculus_and_programming_languages">Lambda 标记</a>。</p> + +<p>JavaScript 1.7 及之前版本:</p> + +<pre class="brush: js">function(x) { return x * x; }</pre> + +<p>JavaScript 1.8:</p> + +<pre class="brush: js">function(x) x * x</pre> + +<p>该语法支持省略花括号和'return'语句。使用这种编码的目的只是为了在句法上使得代码更加简化,但除此之外没有其他好处。</p> + +<h2 id="示例">示例</h2> + +<p>一种绑定事件监听器的便捷方式:</p> + +<pre class="brush: js"> document.addEventListener("click", function() false, true); +</pre> + +<p>在 JavaScript 1.6 中的一些数组函数中使用该标记:</p> + +<pre class="brush: js">elems.some(function(elem) elem.type == "text"); +</pre> + +<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.operators.expression_closures")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("Statements/function", "function statement")}}</li> + <li>{{jsxref("Operators/function", "function expression")}}</li> + <li>{{jsxref("Statements/function*", "function* statement")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("GeneratorFunction")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/function/index.html b/files/zh-cn/web/javascript/reference/operators/function/index.html new file mode 100644 index 0000000000..73939d3da0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/function/index.html @@ -0,0 +1,182 @@ +--- +title: 函数表达式 +slug: Web/JavaScript/Reference/Operators/function +tags: + - Function + - JavaScript + - 函数 + - 基本表达式 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/function +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong><code>function</code></strong> 关键字可以用来在一个表达式中定义一个函数。</p> + +<p>你也可以使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function" title="The Function constructor creates a new Function object. In JavaScript every function is actually a Function object."><code>Function</code></a> 构造函数和一个<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/function">函数声明</a>来定义函数。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox">let function_expression = function [<em>name</em>]([<em>param1</em>[, <em>param2[</em>, ..., <em>paramN</em>]]]) { + <em>statements</em> +};</pre> + +<p>从 <a href="https://developer.mozilla.org/zh-CN/docs/">ES2015</a>开始,你也可以使用<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a> 。</p> + +<h3 id="Parameters" name="Parameters">参数</h3> + +<dl> + <dt><code>name</code></dt> + <dd>函数名称。可被省略,此种情况下的函数是匿名函数(<em>anonymous</em>)。 函数名称只是函数体中的一个本地变量。</dd> + <dt><code>paramN</code></dt> + <dd>被传递给函数的一个参数名称。一个函数至多拥有 255 个参数。</dd> + <dt><code>statements</code></dt> + <dd>构成函数体的语句。</dd> +</dl> + +<h2 id="Description" name="Description">描述</h2> + +<p>函数表达式(function expression)非常类似于函数声明(function statement)<span style="line-height: 1.5;">(详情查看</span><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/function" style="line-height: 1.5;">函数声明</a><span style="line-height: 1.5;">)</span><span style="line-height: 1.5;">,并且两者拥有几乎相同的语法。</span><span style="line-height: 1.5;">函数表达式与函数声明的最主要区别是函数名称(</span><em>function name</em><span style="line-height: 1.5;">),在函数表达式中可省略它,从而创建匿名函数(</span><em>anonymous</em><span style="line-height: 1.5;"> functions)。</span>一个函数表达式可以被用作一个IIFE(Immediately Invoked Function Expression,即时调用的函数表达式),它一旦定义就运行。<span style="line-height: 1.5;">更多信息请查看</span><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope" style="line-height: 1.5;">函数</a><span style="line-height: 1.5;">。</span></p> + +<h3 id="函数表达式提升_(Function_expression_hoisting)"> 函数表达式提升 (Function expression hoisting)</h3> + +<p>JavaScript中的函数表达式没有提升,不像函数声明,你在定义函数表达式之前不能使用函数表达式:</p> + +<pre class="brush: js"><code><font color="#333333" face="Open Sans, arial, sans-serif" size="3"><span style="background-color: #ffffff; white-space: normal;"> </span></font>notHoisted(); // TypeError: notHoisted is not a function + +var notHoisted = function() { + console.log('bar'); +};</code></pre> + +<h3 id="命名函数表达式(Named_function_expression)">命名函数表达式(Named function expression)</h3> + +<p>如果你想在函数体内部引用当前函数,则需要创建一个命名函数表达式。<strong>然后函数名称将会(且只会)作为函数体(作用域内)的本地变量</strong>。这样也可以避免使用非标准的 <a href="/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a> 属性。</p> + +<pre class="brush: js">var math = { + 'factorial': function factorial(n) { + if (n <= 1) + return 1; + return n * factorial(n - 1); + } +}; +</pre> + +<p>被函数表达式赋值的那个变量会有一个name属性,如果你把这个变量赋值给另一个变量的话,这个name属性的值也不会改变。如果函数是一个匿名函数,那name属性的值就是被赋值的变量的名称(隐藏值)。如果函数不是匿名的话,那name属性的值就是这个函数的名称(显性值)。这对于<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a>也同样适用(箭头函数没有名字,所以你只能赋予name属性一个隐性名)。</p> + +<pre class="brush: js"><code>var foo = function() {} +foo.name // "foo" + +var foo2 = foo +foo2.name // "foo" + +var bar = function baz() {} +bar.name // "baz" + +console.log(foo === foo2); //true +console.log(typeof baz);// undefined +console.log(bar === baz); // false (errors because baz == undefined)</code> +</pre> + +<h2 id="示例">示例</h2> + +<p>下面的例子定义了一个匿名函数并把它赋值给变量x。这个函数返回它参数的平方:</p> + +<pre class="brush: js"><code>var x = function(y) { + return y * y; +};</code></pre> + +<p>更多情况下被当作<a href="/zh-CN/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks">回调函数</a>使用:</p> + +<pre class="brush: js"><code>button.addEventListener('click', function(event) { + console.log('button is clicked!') +})</code></pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">说明</th> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-13', 'Function definition')}}</td> + <td>Standard</td> + <td>初始定义。JavaScript 1.5 实现。</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-13', 'Function definition')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-function-definitions', 'Function defintions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("Statements/function", "function statement")}}</li> + <li>{{jsxref("Statements/function*", "function* statement")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("GeneratorFunction")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/function_star_/index.html b/files/zh-cn/web/javascript/reference/operators/function_star_/index.html new file mode 100644 index 0000000000..1f607de5d9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/function_star_/index.html @@ -0,0 +1,89 @@ +--- +title: function* 表达式 +slug: Web/JavaScript/Reference/Operators/function* +tags: + - ECMAScript 2015 + - Function + - Iterator + - JavaScript + - Operator + - Primary Expression +translation_of: Web/JavaScript/Reference/Operators/function* +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong><code>function*</code></strong>关键字可以在表达式内部定义一个生成器函数。</p> + +<p>{{EmbedInteractiveExample("pages/js/expressions-functionasteriskexpression.html")}}</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">function* [<em>name</em>]([<em>param1</em>[, <em>param2[</em>, ..., <em>paramN</em>]]]) { + <em>statements</em> +}</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>name</code></dt> + <dd>函数名。在声明<em>匿名函数</em>时可以省略。函数名称只是函数体中的一个本地变量。</dd> + <dt><code>paramN</code></dt> + <dd>传入函数的一个参数名。一个函数最多有 255 个参数。</dd> + <dt><code>statements</code></dt> + <dd>函数体。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p><code>function*</code>表达式和{{jsxref('Statements/function*', 'function* 声明')}}比较相似,并具有几乎相同的语法。<code>function*</code>表达式和<code>function*</code>声明之间主要区别就是函数名,即在创建匿名函数时,<code>function*</code>表达式可以省略函数名。阅读{{jsxref('Function', '函数')}}章节了解更多信息。</p> + +<h2 id="示例">示例</h2> + +<p>下面的示例定义了一个未命名的生成器函数并把它赋值给<code>x</code>。函数产出它的传入参数的平方:</p> + +<pre class="brush: js">var x = function*(y) { + yield y * y; +}; +</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('ES2015', '#', 'function*')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#', 'function*')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></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.operators.function_star")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li>{{jsxref("Statements/function*", "function* statement")}}</li> + <li>{{jsxref("GeneratorFunction")}} 对象</li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol">The Iterator protocol</a></li> + <li>{{jsxref("Operators/yield", "yield")}}</li> + <li>{{jsxref("Operators/yield*", "yield*")}}</li> + <li>{{jsxref("Function")}} 对象</li> + <li>{{jsxref("Statements/function", "function statement")}}</li> + <li>{{jsxref("Operators/function", "function expression")}}</li> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html new file mode 100644 index 0000000000..1442d50019 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html @@ -0,0 +1,193 @@ +--- +title: Generator推导式 +slug: Web/JavaScript/Reference/Operators/Generator_comprehensions +translation_of: Archive/Web/JavaScript/Generator_comprehensions +--- +<div class="warning"><strong>非标准的。不要使用!</strong><br> +generator推导式是非标准的,而且它不太可能会被添加到ECMAScript。考虑到将来,请使用 {{jsxref("Statements/function*", "generator", "", 1)}}。 +<p> </p> +</div> + +<p>{{jsSidebar("Operators")}}</p> + +<p>生成器推导语法是一种JavaScript表达式,它允许您基于现有的可迭代对象快速组合新的生成器函数。</p> + +<p>许多编程语言中都存在推导。</p> + +<p>看下面,原来Generator推导式语法在SpiderMonkey的不同之处,它是基于对ECMAScript4的提议。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">(for (x of iterable) x) +(for (x of iterable) if (condition) x) +(for (x of iterable) for (y of iterable) x + y) +</pre> + +<h2 id="描述">描述</h2> + +<p>在Generator推导式中,这两种构成方式都是允许的:</p> + +<ul> + <li>{{jsxref("Statements/for...of", "for...of")}} </li> + <li>{{jsxref("Statements/if...else", "if")}}</li> +</ul> + +<p>for-of迭代器是构成的第一个部分。当由多重部分构成时,后面for-of和if构成方式都是被允许的。</p> + +<h2 id="示例">示例</h2> + +<h3 id="单个构成部分的_generator推导式:">单个构成部分的 generator推导式:</h3> + +<pre class="brush:js">(for (i of [ 1, 2, 3 ]) i*i ); +// generator function which yields 1, 4, and 9 + +[...(for (i of [ 1, 2, 3 ]) i*i )]; +// [1, 4, 9] + +var abc = [ "A", "B", "C" ]; +(for (letters of abc) letters.toLowerCase()); +// generator function which yields "a", "b", and "c" + +</pre> + +<h3 id="有if伴随的多重构成的gennerator推导式:">有if伴随的多重构成的gennerator推导式:</h3> + +<pre class="brush: js">var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ]; + +(for (year of years) if (year > 2000) year); +// generator function which yields 2006, 2010, and 2014 + +(for (year of years) if (year > 2000) if(year < 2010) year); +// generator function which yields 2006, the same as below: + +(for (year of years) if (year > 2000 && year < 2010) year); +// generator function which yields 2006 +</pre> + +<h3 id="Generator推导式与Generator函数对比">Generator推导式与Generator函数对比</h3> + +<p>用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。</p> + +<p>Example 1: 仅是 generator.</p> + +<pre class="brush: js">var numbers = [ 1, 2, 3 ]; + +// Generator 函数 +(function*() { + for (let i of numbers) { + yield i * i; + } +})() + +// Generator 推导式 +(for (i of numbers) i*i ); + +// 结果: 两者都得到 yields [ 1, 4, 9 ] +</pre> + +<p>Example 2: 在 generator 中用if.</p> + +<pre class="brush: js">var numbers = [ 1, 2, 3 ]; + +// Generator 函数 +(function*() { + for (let i of numbers) { + if (i < 3) { + yield i * 1; + } + } +})() + +// Generator 推导式 +(for (i of numbers) if (i < 3) i); + +// 结果: 两者都得到 yields [ 1, 2 ]</pre> + +<h2 id="规范">规范</h2> + +<p>Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.</p> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoDesktop("30") }}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoMobile("30") }}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h3 id="SpiderMonkey的具体实现笔记">SpiderMonkey的具体实现笔记</h3> + +<ul> + <li>{{jsxref("Statements/let", "let")}} 作为标识符,因为let当前仅可用于JS版本1.7和XUL脚本标记.</li> + <li>目前还不支持解构 ({{bug(980828)}}).</li> +</ul> + +<h3 id="与旧的JS1.7_JS1.8理解的区别">与旧的JS1.7 / JS1.8理解的区别</h3> + +<ul> + <li>ES2016 的解析为每个“for”节点创建一个范围,而不是作为一个整体的理解。 + <ul> + <li>Old: <code>[...(()=>x for (x of [0, 1, 2]))][1]() // 2</code></li> + <li>New: <code>[...(for (x of [0, 1, 2]) ()=>x)][1]() // 1, 每个迭代都会创建一个新的x的绑定事件。</code></li> + </ul> + </li> + <li> ES2016的解析以“for”而不是赋值表达式开头。 + <ul> + <li>Old: <code>(i * 2 for (i of numbers))</code></li> + <li>New: <code>(for (i of numbers) <code>i * 2</code>)</code></li> + </ul> + </li> + <li>ES2016 解析可以有多个if和for组件。</li> + <li>ES2016 解析仅这种方式工作<code>{{jsxref("Statements/for...of", "for...of")}}</code> 而不是<code>{{jsxref("Statements/for...in", "for...in")}}</code> 的方式迭代。</li> +</ul> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li>{{jsxref("Statements/for...of", "for...of")}}</li> + <li>{{jsxref("Operators/Array_comprehensions", "Array comprehensions")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/greater_than/index.html b/files/zh-cn/web/javascript/reference/operators/greater_than/index.html new file mode 100644 index 0000000000..afb4a2d134 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/greater_than/index.html @@ -0,0 +1,95 @@ +--- +title: 大于运算符 (>) +slug: Web/JavaScript/Reference/Operators/Greater_than +translation_of: Web/JavaScript/Reference/Operators/Greater_than +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>当左边操作数大于右边的时候,大于(<code>></code>) 运算符返回<code>true</code>,否则返回<code>false</code></p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-greater-than.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">x > y</pre> + +<h2 id="描述">描述</h2> + +<p>操作数之间按照 <a class="external external-icon" href="https://tc39.es/ecma262/#sec-abstract-relational-comparison" rel="noopener">Abstract Relational Comparison</a> 算法进行比较。进一步了解该算法,请参考 <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">小于</a> 运算符的相关文档.</p> + +<h2 id="例子">例子</h2> + +<h3 id="字符串的比较">字符串的比较</h3> + +<pre class="brush: js notranslate">console.log("a" > "b"); // false +console.log("a" > "a"); // false +console.log("a" > "3"); // true</pre> + +<h3 id="字符串和数字的比较">字符串和数字的比较</h3> + +<pre class="brush: js notranslate">console.log("5" > 3); // true +console.log("3" > 3); // false +console.log("3" > 5); // false + +console.log("hello" > 5); // false +console.log(5 > "hello"); // false + +console.log("5" > 3n); // true +console.log("3" > 5n); // false</pre> + +<h3 id="数字间的比较">数字间的比较</h3> + +<pre class="brush: js notranslate">console.log(5 > 3); // true +console.log(3 > 3); // false +console.log(3 > 5); // false</pre> + +<h3 id="数字和_BigInt_数据的比较">数字和 BigInt 数据的比较</h3> + +<pre class="brush: js notranslate">console.log(5n > 3); // true +console.log(3 > 5n); // false</pre> + +<h3 id="Boolean_null_undefined_NaN的比较">Boolean, null, undefined, NaN的比较</h3> + +<pre class="brush: js notranslate">console.log(true > false); // true +console.log(false > true); // false + +console.log(true > 0); // true +console.log(true > 1); // false + +console.log(null > 0); // false +console.log(1 > null); // true + +console.log(undefined > 3); // false +console.log(3 > undefined); // false + +console.log(3 > NaN); // false +console.log(NaN > 3); // false</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + + + +<p>{{Compat("javascript.operators.greater_than")}}</p> + +<h2 id="参考">参考</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal">Greater than or equal operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">Less than operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal">Less than or equal operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html b/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html new file mode 100644 index 0000000000..9fa5b48436 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html @@ -0,0 +1,95 @@ +--- +title: 大于或等于 +slug: Web/JavaScript/Reference/Operators/Greater_than_or_equal +translation_of: Web/JavaScript/Reference/Operators/Greater_than_or_equal +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The greater than or equal operator (<code>>=</code>) returns <code>true</code> if the left operand is greater than or equal to the right operand, and <code>false</code> otherwise.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-greater-than-or-equal.html")}}</div> + + + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate"> x >= y</pre> + +<h2 id="Description">Description</h2> + +<p>The operands are compared using the <a class="external external-icon" href="https://tc39.es/ecma262/#sec-abstract-relational-comparison" rel="noopener">Abstract Relational Comparison</a> algorithm. See the documentation for the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">Less than</a> operator for a summary of this algorithm.</p> + +<h2 id="Examples">Examples</h2> + +<h3 id="String_to_string_comparison">String to string comparison</h3> + +<pre class="brush: js notranslate">console.log("a" >= "b"); // false +console.log("a" >= "a"); // true +console.log("a" >= "3"); // true +</pre> + +<h3 id="String_to_number_comparison">String to number comparison</h3> + +<pre class="brush: js notranslate">console.log("5" >= 3); // true +console.log("3" >= 3); // true +console.log("3" >= 5); // false + +console.log("hello" >= 5); // false +console.log(5 >= "hello"); // false</pre> + +<h3 id="Number_to_Number_comparison">Number to Number comparison</h3> + +<pre class="brush: js notranslate">console.log(5 >= 3); // true +console.log(3 >= 3); // true +console.log(3 >= 5); // false</pre> + +<h3 id="Number_to_BigInt_comparison">Number to BigInt comparison</h3> + +<pre class="brush: js notranslate">console.log(5n >= 3); // true +console.log(3 >= 3n); // true +console.log(3 >= 5n); // false</pre> + +<h3 id="Comparing_Boolean_null_undefined_NaN">Comparing Boolean, null, undefined, NaN</h3> + +<pre class="brush: js notranslate">console.log(true >= false); // true +console.log(true >= true); // true +console.log(false >= true); // false + +console.log(true >= 0); // true +console.log(true >= 1); // true + +console.log(null >= 0); // true +console.log(1 >= null); // true + +console.log(undefined >= 3); // false +console.log(3 >= undefined); // false + +console.log(3 >= NaN); // false +console.log(NaN >= 3); // false</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.greater_than_or_equal")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than">Greater than operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">Less than operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal">Less than or equal operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/grouping/index.html b/files/zh-cn/web/javascript/reference/operators/grouping/index.html new file mode 100644 index 0000000000..837cdf366f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/grouping/index.html @@ -0,0 +1,93 @@ +--- +title: 圆括号运算符 +slug: Web/JavaScript/Reference/Operators/Grouping +tags: + - JavaScript + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Grouping +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>圆括号运算符 <code>( )</code> 用于控制表达式中的运算优先级。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-groupingoperator.html")}}</div> + +<p class="hidden">这些交互的事例资源都是基于Github的仓库.如果你想提交更多的交互事例,请克隆这个url<a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 并且向我们发送合并请求。</p> + +<h2 id="语法">语法</h2> + +<p>译者:下列语法是 MDN 上已知的最简单的之一。</p> + +<pre class="syntaxbox"> ( )</pre> + +<h2 id="说明">说明</h2> + +<p>圆括号运算符由一对圆括号组成,包裹表达式和子表达式用来覆盖常规的<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a>,达到低优先级的表达式比高优先级的表达式更早运算。</p> + +<h2 id="示例">示例</h2> + +<p>下面的代码展示了加法运算先于乘法运算的情况。</p> + +<pre class="brush:js">var a = 1; +var b = 2; +var c = 3; + +// default precedence +a + b * c // 7 +// evaluated by default like this +a + (b * c) // 7 + +// now overriding precedence +// addition before multiplication +(a + b) * c // 9 + +// which is equivalent to +a * c + b * c // 9 +</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-grouping-operator', 'The Grouping Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-grouping-operator', 'The Grouping Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.6', 'The Grouping Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.1.4', 'The Grouping Operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>初始化定义.在JavaScript1.0中生效</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div class="hidden">本页的浏览器兼容性表都是基于结构数据,如果你想更新数据.可以查看 <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 并且请给我们发送合并请求.</div> + +<p>{{Compat("javascript.operators.grouping")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a></li> + <li>{{jsxref("Operators/delete", "delete")}}</li> + <li>{{jsxref("Operators/typeof", "typeof")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/in/index.html b/files/zh-cn/web/javascript/reference/operators/in/index.html new file mode 100644 index 0000000000..acd8d18255 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/in/index.html @@ -0,0 +1,145 @@ +--- +title: in +slug: Web/JavaScript/Reference/Operators/in +tags: + - JavaScript + - Operator + - Relational Operators +translation_of: Web/JavaScript/Reference/Operators/in +--- +<p>{{jsSidebar("Operators")}}</p> + +<p>如果指定的属性在指定的对象或其原型链中,则<strong><code>in</code> 运算符</strong>返回<code>true</code>。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-inoperator.html")}}</div> + + + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox notranslate"><em>prop</em> in <em>object</em></pre> + +<h3 id="Parameters" name="Parameters">参数</h3> + +<dl> + <dt><code>prop</code></dt> + <dd>一个字符串类型或者 symbol 类型的属性名或者数组索引(非symbol类型将会强制转为字符串)。</dd> +</dl> + +<dl> + <dt><code>objectName</code></dt> + <dd>检查它(或其原型链)是否包含具有指定名称的属性的对象。</dd> +</dl> + +<h2 id="Description" name="Description">描述</h2> + +<p>下面的例子演示了一些 <code>in</code> 运算符的用法。</p> + +<pre class="brush:js notranslate">// 数组 +var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); +0 in trees // 返回true +3 in trees // 返回true +6 in trees // 返回false +"bay" in trees // 返回false (必须使用索引号,而不是数组元素的值) + +"length" in trees // 返回true (length是一个数组属性) + +Symbol.iterator in trees // 返回true (数组可迭代,只在ES2015+上有效) + + +// 内置对象 +"PI" in Math // 返回true + +// 自定义对象 +var mycar = {make: "Honda", model: "Accord", year: 1998}; +"make" in mycar // 返回true +"model" in mycar // 返回true +</pre> + +<p><code>in</code>右操作数必须是一个对象值。例如,你可以指定使用<code>String</code>构造函数创建的字符串,但不能指定字符串文字。</p> + +<pre class="brush:js notranslate">var color1 = new String("green"); +"length" in color1 // 返回true +var color2 = "coral"; +"length" in color2 // 报错(color2不是对象) +</pre> + +<h3 id="Using_in_with_deleted_or_undefined_properties" name="Using_in_with_deleted_or_undefined_properties">对被删除或值为 undefined 的属性使用<code>in</code></h3> + +<p>如果你使用 <code><a href="/zh-CN/docs/JavaScript/Reference/Operators/delete" title="zh-CN/docs/JavaScript/Reference/Operators/Special/delete">delete</a></code> 运算符删除了一个属性,则 <code>in</code> 运算符对所删除属性返回 <code>false</code>。</p> + +<pre class="brush:js notranslate">var mycar = {make: "Honda", model: "Accord", year: 1998}; +delete mycar.make; +"make" in mycar; // 返回false + +var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); +delete trees[3]; +3 in trees; // 返回false +</pre> + +<p>如果你只是将一个属性的值赋值为{{jsxref("Global_Objects/undefined", "undefined")}},而没有删除它,则 <code>in</code> 运算仍然会返回<code>true</code>。</p> + +<pre class="brush:js notranslate">var mycar = {make: "Honda", model: "Accord", year: 1998}; +mycar.make = undefined; +"make" in mycar; // 返回true +</pre> + +<pre class="brush:js notranslate">var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); +trees[3] = undefined; +3 in trees; // 返回true +</pre> + +<h3 id="Inherited_properties" name="Inherited_properties">继承属性</h3> + +<p>如果一个属性是从原型链上继承来的,<code>in</code> 运算符也会返回 <code>true</code>。</p> + +<pre class="brush:js notranslate">"toString" in {}; // 返回true +</pre> + +<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</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-relational-operators', 'Relational Operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-relational-operators', 'Relational Operators')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.8.7', 'The in Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.8.7', 'The in Operator')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition. Implemented in JavaScript 1.4.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容" style="margin-bottom: 20px; line-height: 30px;">浏览器兼容</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.operators.in")}}</p> + +<h2 id="See_also" name="See_also" style="margin-bottom: 20px; line-height: 30px;">相关链接</h2> + +<ul> + <li><code><a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a></code></li> + <li><code><a href="/zh-CN/docs/JavaScript/Reference/Operators/delete" title="zh-CN/docs/JavaScript/Reference/Operators/Special/delete">delete</a></code></li> + <li>{{jsxref("Object.prototype.hasOwnProperty()")}}</li> + <li>{{jsxref("Reflect.has()")}}</li> + <li><a href="/zh-CN/docs/Enumerability_and_ownership_of_properties" title="/zh-CN/docs/Enumerability_and_ownership_of_properties">属性的可枚举性和所有权</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/increment/index.html b/files/zh-cn/web/javascript/reference/operators/increment/index.html new file mode 100644 index 0000000000..afe307f389 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/increment/index.html @@ -0,0 +1,84 @@ +--- +title: 自增 (++) +slug: Web/JavaScript/Reference/Operators/Increment +tags: + - JavaScript + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/Increment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>自增运算符 (<code>++</code>) 将其操作数递增(加1)并返回一个值。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-increment.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>x</var>++ or ++<var>x</var> +</pre> + +<h2 id="描述">描述</h2> + +<p>如使用后置(Postfix)自增,操作符在操作数后(例如 <code><var>x</var>++</code>), 操作数将在自增前返回。</p> + +<p>如使用前置(Prefix)自增,操作符在操作数前(例如 <code>++<var>x</var></code>), 操作数将先自增后返回。</p> + +<h2 id="示例">示例</h2> + +<h3 id="后置自增Postfix_increment">后置自增(Postfix increment)</h3> + +<pre class="brush: js notranslate">let x = 3; +y = x++; + +// y = 3 +// x = 4 +</pre> + +<h3 id="前置自增Prefix_increment">前置自增(Prefix increment)</h3> + +<pre class="brush: js notranslate">let a = 2; +b = ++a; + +// a = 3 +// b = 3 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-postfix-increment-operator', 'Increment operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.increment")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> + +<div id="gtx-trans" style="position: absolute; left: 126px; top: 21px;"> +<div class="gtx-trans-icon"></div> +</div> diff --git a/files/zh-cn/web/javascript/reference/operators/index.html b/files/zh-cn/web/javascript/reference/operators/index.html new file mode 100644 index 0000000000..238cbb8cb9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/index.html @@ -0,0 +1,297 @@ +--- +title: 表达式和运算符 +slug: Web/JavaScript/Reference/Operators +tags: + - JavaScript + - Operators + - 概览 +translation_of: Web/JavaScript/Reference/Operators +--- +<p>{{jsSidebar("Operators")}}<br> + 该章节说明了JavaScript语言所有的运算符,表达式和关键字。</p> + +<h2 id="表达式和运算符分类">表达式和运算符分类</h2> + +<p>左侧工具栏是按字母表排序的列表。</p> + +<h3 id="主要表达式">主要表达式</h3> + +<p>JavaScript中基本关键字和常用表达式。</p> + +<dl> + <dt>{{jsxref("Operators/this", "this")}}</dt> + <dd><code>this</code> 关键字指向函数的执行上下文。</dd> + <dt>{{jsxref("Operators/function", "function")}}</dt> + <dd><code>function</code> 关键字定义了函数表达式。</dd> + <dt>{{jsxref("Operators/class", "class")}}</dt> + <dd><code>class</code> 关键字定义了类表达式。</dd> + <dt>{{jsxref("Operators/function*", "function*")}}</dt> + <dd><code>function*</code> 关键字定义了一个 generator 函数表达式。</dd> + <dt>{{jsxref("Operators/yield", "yield")}}</dt> + <dd>暂停和恢复 generator 函数。</dd> + <dt>{{jsxref("Operators/yield*", "yield*")}}</dt> + <dd>委派给另外一个generator函数或可迭代的对象。</dd> + <dt>{{jsxref("Operators/async_function", "async function")}}</dt> + <dd><code>async function</code> 定义一个异步函数表达式。</dd> + <dt>{{jsxref("Operators/await", "await")}}</dt> + <dd>暂停或恢复执行异步函数,并等待promise的resolve/reject回调。</dd> + <dt>{{jsxref("Global_Objects/Array", "[]")}}</dt> + <dd>数组初始化/字面量语法。</dd> + <dt>{{jsxref("Operators/Object_initializer", "{}")}}</dt> + <dd>对象初始化/字面量语法。</dd> + <dt>{{jsxref("Global_Objects/RegExp", "/ab+c/i")}}</dt> + <dd>正则表达式字面量语法。</dd> + <dt>{{jsxref("Operators/Grouping", "( )")}}</dt> + <dd>分组操作符。</dd> +</dl> + +<h3 id="左表达式">左表达式</h3> + +<p>左边的值是赋值的目标。</p> + +<dl> + <dt>{{jsxref("Operators/Property_accessors", "属性访问符", "", 1)}}</dt> + <dd>成员运算符提供了对对象的属性或方法的访问<br> + (<code>object.property</code> 和 <code>object["property"]</code>).</dd> + <dt>{{jsxref("Operators/new", "new")}}</dt> + <dd><code>new</code> 运算符创建了构造函数实例。</dd> + <dt>{{JSxRef("Operators/new%2Etarget", "new.target")}}</dt> + <dd>在构造器中,<code>new.target</code> 指向{{jsxref("Operators/new", "new")}}调用的构造器。</dd> + <dt>{{jsxref("Operators/super", "super")}}</dt> + <dd><code>super</code> 关键字调用父类的构造器.</dd> + <dt>{{jsxref("Operators/Spread_operator", "...obj")}}</dt> + <dd>展开运算符可以将一个可迭代的对象在函数调用的位置展开成为多个参数,或者在数组字面量中展开成多个数组元素。</dd> +</dl> + +<h3 id="自增和自减">自增和自减</h3> + +<p>前置/后置自增运算符和前置/后置自减运算符.</p> + +<dl> + <dt>{{jsxref("Operators/Arithmetic_Operators", "A++", "#Increment")}}</dt> + <dd>后置自增运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "A--", "#Decrement")}}</dt> + <dd>后置自减运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "++A", "#Increment")}}</dt> + <dd>前置自增运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "--A", "#Decrement")}}</dt> + <dd>前置自减运算符.</dd> +</dl> + +<h3 id="一元运算符">一元运算符</h3> + +<p>一元运算符只有一个操作数.</p> + +<dl> + <dt>{{jsxref("Operators/delete", "delete")}}</dt> + <dd><code>delete</code> 运算符用来删除对象的属性.</dd> + <dt>{{jsxref("Operators/void", "void")}}</dt> + <dd><code>void</code> 运算符表示表达式放弃返回值.</dd> + <dt>{{jsxref("Operators/typeof", "typeof")}}</dt> + <dd><code>typeof</code> 运算符用来判断给定对象的类型.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}</dt> + <dd>一元加运算符将操作转换为Number类型.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}</dt> + <dd>一元减运算符将操作转换为Number类型并取反.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}</dt> + <dd>按位非运算符.</dd> + <dt>{{jsxref("Operators/Logical_Operators", "!", "#Logical_NOT")}}</dt> + <dd>逻辑非运算符.</dd> +</dl> + +<h3 id="算术运算符">算术运算符</h3> + +<p>算术运算符以二个数值(字面量或变量)作为操作数,并返回单个数值。</p> + +<dl> + <dt>{{jsxref("Operators/Arithmetic_Operators", "+", "#Addition")}}</dt> + <dd>加法运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "-", "#Subtraction")}}</dt> + <dd>减法运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "/", "#Division")}}</dt> + <dd>除法运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "*", "#Multiplication")}}</dt> + <dd>乘法运算符.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "%", "#Remainder")}}</dt> + <dd>取模运算符.</dd> +</dl> + +<h3 id="关系运算符">关系运算符</h3> + +<p>比较运算符比较二个操作数并返回基于比较结果的<code>Boolean</code>值。</p> + +<dl> + <dt>{{jsxref("Operators/in", "in")}}</dt> + <dd><code>in运算符用来判断对象是否拥有给定属性</code>.</dd> + <dt>{{jsxref("Operators/instanceof", "instanceof")}}</dt> + <dd><code>instanceof</code> 运算符判断一个对象是否是另一个对象的实例.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "<", "#Less_than_operator")}}</dt> + <dd>小于运算符</dd> + <dt>{{jsxref("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}</dt> + <dd>大于运算符.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}</dt> + <dd>小于等于运算符.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}</dt> + <dd>大于等于运算符。 </dd> +</dl> + +<div class="note"><strong>注意: =></strong> 不是运算符,而是{{jsxref("Functions/Arrow_functions", "箭头函数")}}的表示符。</div> + +<h3 id="相等运算符">相等运算符</h3> + +<p>如果相等,操作符返回的是Boolean(布尔)类型的true,否则是false。</p> + +<dl> + <dt>{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}}</dt> + <dd>相等 运算符.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "!=", "#Inequality")}}</dt> + <dd>不等 运算符.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}}</dt> + <dd>全等 运算符.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "!==", "#Nonidentity")}}</dt> + <dd>非全等 运算符.</dd> +</dl> + +<h3 id="位移运算符">位移运算符</h3> + +<p>在二进制的基础上对数字进行移动操作</p> + +<dl> + <dt>{{jsxref("Operators/Bitwise_Operators", "<<", "#Left_shift")}}</dt> + <dd>按位左移运算符。</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", ">>", "#Right_shift")}}</dt> + <dd>按位右移运算符。</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}</dt> + <dd>按位无符号右移运算符。</dd> +</dl> + +<h3 id="二进制位运算符">二进制位运算符</h3> + +<p>二进制运算符将它们的操作数作为32个二进制位(0或1)的集合,并返回标准的JavaScript数值。</p> + +<dl> + <dt>{{jsxref("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}</dt> + <dd>二进制位与(AND)。</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}</dt> + <dd>二进制位或(OR)。</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}</dt> + <dd>二进制位异或(XOR)。</dd> +</dl> + +<h3 id="二元逻辑运算符">二元逻辑运算符</h3> + +<p>逻辑运算符典型的用法是用于boolean(逻辑)值运算, 它们返回boolean值。</p> + +<dl> + <dt>{{jsxref("Operators/Logical_Operators", "&&", "#Logical_AND")}}</dt> + <dd>逻辑与.</dd> + <dt>{{jsxref("Operators/Logical_Operators", "||", "#Logical_OR")}}</dt> + <dd>逻辑或.</dd> + <dt>{{JSxRef("Operators/Nullish_coalescing_operator", "??")}}</dt> + <dd>空值合并运算符 , 如果 ?? 前面是 null 或 undefined ,取后面的默认值</dd> +</dl> + +<h3 id="条件三元运算符">条件(三元)运算符</h3> + +<dl> + <dt>{{jsxref("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}</dt> + <dd> + <p>条件元素运算符把两个结果中其中一个符合运算逻辑的值返回。</p> + </dd> +</dl> + +<h3 id="赋值运算符">赋值运算符</h3> + +<p>赋值元素符会将右边的操作数的值分配给左边的操作数,并将其值修改为右边操作数相等的值。</p> + +<dl> + <dt>{{jsxref("Operators/Assignment_Operators", "=", "#Assignment")}}</dt> + <dd>赋值运算符。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}</dt> + <dd>赋值乘积。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "/=", "#Division_assignment")}}</dt> + <dd>赋值商。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}</dt> + <dd>赋值求余。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}</dt> + <dd>赋值求和。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}</dt> + <dd>赋值求差。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}</dt> + <dd>左位移。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}</dt> + <dd>右位移。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}</dt> + <dd>无符号右位移。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}</dt> + <dd>赋值与。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}</dt> + <dd>赋值按位异或。</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}</dt> + <dd>赋值或。</dd> + <dt>{{jsxref("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}<br> + {{jsxref("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}</dt> + <dd> + <p>解构赋值允许你分配数组或者对象变量的属性通过使用规定的语法,其看起来和数组和对象字面量很相似。</p> + </dd> + <dt> + <h3 id="逗号操作符">逗号操作符</h3> + </dt> + <dt>{{jsxref("Operators/Comma_Operator", ",")}}</dt> + <dd>逗号操作符允许在一个判断状态中有多个表达式去进行运算并且最后返回最后一个表达式的值。</dd> + <dt> + <h3 id="非标准化特性">非标准化特性</h3> + </dt> + <dt>{{JSxRef("Operators/Expression_closures", "Expression closures", "", 1)}} {{non-standard_inline}}{{obsolete_inline(60)}}</dt> + <dd>闭包表达式语法是一个缩写简单的函数。</dd> + <dt>{{JSxRef("Operators/Legacy_generator_function", "Legacy generator function", "", 1)}} {{non-standard_inline}}{{obsolete_inline(58)}}</dt> + <dd>function关键字能用来定义表达式内部未执行完的function的余下功能。 为了能执行function内部余下的代码, 这个function的内部至少包含一个{{jsxref("Operators/yield", "yield")}} 表达式。</dd> + <dt>{{JSxRef("Operators/Array_comprehensions", "[for (x of y) x]")}} {{non-standard_inline}}{{obsolete_inline(58)}}</dt> + <dd>数组解析</dd> + <dt>{{JSxRef("Operators/Generator_comprehensions", "(for (x of y) y)")}} {{non-standard_inline}}{{obsolete_inline(58)}}</dt> + <dd>生成器解析</dd> +</dl> + +<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('ES1', '#sec-11', 'Expressions')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11', 'Expressions')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>New: Spread syntax, rest syntax, destructuring assignment, <code>super</code> keyword.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + + + +<p>{{Compat("javascript.operators")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/inequality/index.html b/files/zh-cn/web/javascript/reference/operators/inequality/index.html new file mode 100644 index 0000000000..2c0bccddfd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/inequality/index.html @@ -0,0 +1,104 @@ +--- +title: 不等于 (!=) +slug: Web/JavaScript/Reference/Operators/Inequality +tags: + - JavaScript + - 参考 + - 语言特征 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Inequality +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>不等于运算符 (<code>!=</code>) 检查其两个操作数是否不相等,并返回布尔结果。 与严格的不等式运算符不同,它尝试转换和比较不同类型的操作数。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-inequality.html")}}</div> + +<p class="hidden"><font><font>该交互式示例的源代码存储在GitHub存储库中。</font><font>如果您想为交互式示例项目做出贡献,请克隆</font></font><a href="https://github.com/mdn/interactive-examples"><font><font>https://github.com/mdn/interactive-examples</font></font></a><font><font>并向我们发送请求请求。</font></font></p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">x != y</pre> + +<h2 id="描述"><font><font>描述</font></font></h2> + +<p><font><font>不等式运算符检查其操作数是否不相等。</font><font>这是</font></font><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality"><font><font>等于</font></font></a><font><font>运算符</font><font>的取反,</font><font>因此以下两行将始终给出相同的结果:</font></font> </p> + +<pre class="brush: js notranslate">x != y + +!(x == y)</pre> + +<p><font><font>有关比较算法的详细信息,请参见</font></font><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality"><font><font>等于</font></font></a><font><font>运算符</font><font>的页面</font><font>。</font></font></p> + +<p><font><font>与等于运算符一样,不等于运算符将尝试转换和比较不同类型的操作数:</font></font></p> + +<pre class="brush: js notranslate">3 != "3"; // false</pre> + +<p><font><font>为避免这种情况,并要求将不同类型视为不同,请使用</font></font><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_inequality"><font><font>严格的不等于</font></font></a><font><font>运算符:</font></font></p> + +<pre class="brush: js notranslate">3 !== "3"; // true</pre> + +<h2 id="例子"><font><font>例子</font></font></h2> + +<h3 id="没有类型转换的比较"><font><font>没有类型转换的比较</font></font></h3> + +<pre class="brush: js notranslate">1 != 2; // true +"hello" != "hola"; // true + +1 != 1; // false +"hello" != "hello"; // false</pre> + +<h3 id="与类型转换比较"><font><font>与类型转换比较</font></font></h3> + +<pre class="brush: js notranslate">"1" != 1; // false +1 != "1"; // false +0 != false; // false +0 != null; // true +0 != undefined; // true +0 != !!null; // false, look at Logical NOT operator +0 != !!undefined; // false, look at Logical NOT operator +null != undefined; // false + +const number1 = new Number(3); +const number2 = new Number(3); +number1 != 3; // false +number1 != number2; // true</pre> + +<h3 id="对象比较"><font><font>对象比较</font></font></h3> + +<pre class="brush: js notranslate">const object1 = {"key": "value"} +const object2 = {"key": "value"}; + +object1 != object2 // true +object2 != object2 // false</pre> + +<h2 id="规范"><font><font>规范</font></font></h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性"><font><font>浏览器兼容性</font></font></h2> + +<div class="hidden"><font><font>此页面上的兼容性表是根据结构化数据生成的。</font><font>如果您想提供数据,请查看</font></font><a href="https://github.com/mdn/browser-compat-data"><font><font>https://github.com/mdn/browser-compat-data</font></font></a><font><font>并向我们发送请求请求。</font></font></div> + +<p>{{Compat("javascript.operators.inequality")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality">Equality operator</a></li> + <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">Strict equality operator</a></li> + <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_inequality">Strict inequality operator</a></li> +</ul> + +<div id="gtx-trans" style="position: absolute; left: 16px; top: 1743.2px;"> +<div class="gtx-trans-icon"></div> +</div> diff --git a/files/zh-cn/web/javascript/reference/operators/instanceof/index.html b/files/zh-cn/web/javascript/reference/operators/instanceof/index.html new file mode 100644 index 0000000000..c97b2a72a4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/instanceof/index.html @@ -0,0 +1,186 @@ +--- +title: instanceof +slug: Web/JavaScript/Reference/Operators/instanceof +tags: + - JavaScript + - instanceof + - 原型 + - 原型链 + - 对象 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/instanceof +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong><code>instanceof</code></strong> <strong>运算符</strong>用于检测构造函数的 <code>prototype</code> 属性是否出现在某个实例对象的原型链上。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-instanceof.html")}}</div> + + + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre><code><em>object</em> instanceof <em>constructor</em></code></pre> + +<h3 id="Parameters" name="Parameters">参数</h3> + +<dl> + <dt><code>object</code></dt> + <dd>某个实例对象</dd> +</dl> + +<dl> + <dt><code>constructor</code></dt> + <dd>某个构造函数</dd> +</dl> + +<h2 id="Description" name="Description">描述</h2> + +<p><code>instanceof</code> 运算符用来检测 <code>constructor.prototype </code>是否存在于参数 <code>object</code> 的原型链上。</p> + +<pre class="brush: js">// 定义构造函数 +function C(){} +function D(){} + +var o = new C(); + + +o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype + + +o instanceof D; // false,因为 D.prototype 不在 o 的原型链上 + +o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true +C.prototype instanceof Object // true,同上 + +C.prototype = {}; +var o2 = new C(); + +o2 instanceof C; // true + +o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上. + +D.prototype = new C(); // 继承 +var o3 = new D(); +o3 instanceof D; // true +o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上 +</pre> + +<p>需要注意的是,如果表达式 <code>obj instanceof Foo</code> 返回 <code>true</code>,则并不意味着该表达式会永远返回 <code>true</code>,因为 <code>Foo.prototype</code> 属性的值有可能会改变,改变之后的值很有可能不存在于 <code>obj</code> 的原型链上,这时原表达式的值就会成为 <code>false</code>。另外一种情况下,原表达式的值也会改变,就是改变对象 <code>obj</code> 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 <code>__proto__</code> 伪属性,是可以实现的。比如执行 <code>obj.__proto__ = {}</code> 之后,<code>obj instanceof Foo</code> 就会返回 <code>false</code> 了。</p> + +<h3 id="instanceof_和多全局对象例如:多个_frame_或多个_window_之间的交互"><code>instanceof</code> 和多全局对象(例如:多个 frame 或多个 window 之间的交互)</h3> + +<p>在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 <code>[] instanceof window.frames[0].Array</code> 会返回 <code>false</code>,因为 <code>Array.prototype !== window.frames[0].Array.prototype</code>,并且数组从前者继承。</p> + +<p>起初,你会认为这样并没有意义,但是当你在你的脚本中开始处理多个 frame 或多个 window 以及通过函数将对象从一个窗口传到另一个窗口时,这就是一个有效而强大的话题。比如,实际上你可以通过使用<code>Array.isArray(myObj)</code> 或者<code>Object.prototype.toString.call(myObj) === "[object Array]"</code> 来安全的检测传过来的对象是否是一个数组。</p> + +<p>比如检测一个 <code>Nodes</code> 在另一个窗口中是不是 <code>SVGElement</code>,你可以使用<code>myNode instanceof myNode.ownerDocument.defaultView.SVGElement</code></p> + +<div class="note"><strong>Mozilla开发者注意:</strong><br> +在代码中使用 XPCOM <code>instanceof </code>有特殊影响: 如果查询接口成功执行后,<code>obj instanceof </code><em><code>xpcomInterface</code></em> (e.g. <code>Components.interfaces.nsIFile</code>) 调用<code>obj.QueryInterface(<em>xpcomInterface</em>)</code> 并且返回 <code>true</code> 。这种调用的副作用是在一次成功的 <code>instanceof</code> 测试后,你可以在 <code>obj</code> 上使用<code>xpcomInterface</code> 的属性。这与标准的 <code>JavaScript</code> 全局变量不同,即使 <code>obj</code> 来自不同的作用域,<code>obj instanceof xpcomInterface</code> 也可以按预期产生作用。</div> + +<h2 id="Examples" name="Examples">示例</h2> + +<h3 id="Example_Demonstrating_that_String_and_Date_are_of_type_Object" name="Example:_Demonstrating_that_String_and_Date_are_of_type_Object">演示 <code>String</code> 对象和 <code>Date</code> 对象都属于 <code>Object</code> 类型和一些特殊情况</h3> + +<p>下面的代码使用了 <code>instanceof</code> 来证明:<code>String</code> 和 <code>Date</code> 对象同时也属于<code>Object</code> 类型(他们是由 <code>Object</code> 类派生出来的)。</p> + +<p>但是,使用对象文字符号创建的对象在这里是一个例外:虽然原型未定义,但 <code>instanceof Object</code> 返回 <code>true</code>。</p> + +<pre class="brush: js">var simpleStr = "This is a simple string"; +var myString = new String(); +var newStr = new String("String created with constructor"); +var myDate = new Date(); +var myObj = {}; +var myNonObj = Object.create(null); + +simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined +myString instanceof String; // 返回 true +newStr instanceof String; // 返回 true +myString instanceof Object; // 返回 true + +myObj instanceof Object; // 返回 true, 尽管原型没有定义 +({}) instanceof Object; // 返回 true, 同上 +myNonObj instanceof Object; // 返回 false, 一种创建非 Object 实例的对象的方法 + +myString instanceof Date; //返回 false + +myDate instanceof Date; // 返回 true +myDate instanceof Object; // 返回 true +myDate instanceof String; // 返回 false</pre> + +<h3 id="Example_Demonstrating_that_mycar_is_of_type_Car_and_type_Object" name="Example:_Demonstrating_that_mycar_is_of_type_Car_and_type_Object">演示 <code>mycar</code> 属于 <code>Car</code> 类型的同时又属于 <code>Object</code> 类型</h3> + +<p>下面的代码创建了一个类型 <code>Car</code>,以及该类型的对象实例 <code>mycar</code>. <code>instanceof</code> 运算符表明了这个 <code>mycar</code> 对象既属于 <code>Car</code> 类型,又属于 <code>Object</code> 类型。</p> + +<pre class="brush: js" dir="rtl">function Car(make, model, year) { + this.make = make; + this.model = model; + this.year = year; +} +var mycar = new Car("Honda", "Accord", 1998); +var a = mycar instanceof Car; // 返回 true +var b = mycar instanceof Object; // 返回 true + +</pre> + +<h3 id="不是...的实例">不是...的实例</h3> + +<p>要检测对象不是某个构造函数的实例时,你可以这样做</p> + +<pre class="brush: js">if (!(mycar instanceof Car)) { + // Do something, like mycar = new Car(mycar) +}</pre> + +<p>这和以下代码完全不同</p> + +<pre class="brush: js">if (!mycar instanceof Car)</pre> + +<p>这段代码永远会得到 <code>false</code>(<code>!mycar</code> 将在 <code>instanceof</code> 之前被处理,所以你总是在验证一个布尔值是否是 <code>Car</code> 的一个实例)。</p> + +<h2 id="相关规范">相关规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">注释</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.8.6', 'The instanceof operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.8.6', 'The instanceof operator')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition. Implemented in JavaScript 1.4.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div class="hidden"> +<p>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.</p> +</div> + +<p>{{Compat("javascript.operators.instanceof")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/JavaScript/Reference/Operators/typeof" title="/zh-CN/docs/JavaScript/Reference/Operators/typeof">typeof</a></li> + <li>{{jsxref("Symbol.hasInstance")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/left_shift/index.html b/files/zh-cn/web/javascript/reference/operators/left_shift/index.html new file mode 100644 index 0000000000..aba9c6bee2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/left_shift/index.html @@ -0,0 +1,72 @@ +--- +title: 左移 (<<) +slug: Web/JavaScript/Reference/Operators/Left_shift +translation_of: Web/JavaScript/Reference/Operators/Left_shift +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>左移操作符 (<code><<</code>)</strong> 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-left-shift.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> << <var>b</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>左移操作符将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。</p> + +<p>例如, <code>9 << 2</code> 得出 36:</p> + +<pre class="brush: js notranslate">. 9 (十进制): 00000000000000000000000000001001 (二进制) + -------------------------------- +9 << 2 (十进制): 00000000000000000000000000100100 (二进制) = 36 (十进制) +</pre> + +<p>移动任意数字 <code>x</code> 至左边 <code>y</code> 位,得出 <code>x * 2 ** y</code> 。<br> + 所以例如:<code>9 << 3</code> 等价于 <code>9 * 2³ = 9 * 8 = 72</code>。</p> + +<h2 id="例子">例子</h2> + +<h3 id="使用左移">使用左移</h3> + +<pre class="brush: js notranslate">9 << 3; // 72 + +// 9 * 2³ = 9 * 8 = 72 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.left_shift")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift_assignment">Left shift assignment operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html new file mode 100644 index 0000000000..3ebe7cef88 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Left shift assignment (<<=) +slug: Web/JavaScript/Reference/Operators/Left_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Left_shift_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The left shift assignment operator (<code><<=</code>) moves the specified amount of bits to the left and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-left-shift-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x <<= y +<strong>Meaning:</strong> x = x << y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_left_shift_assignment">Using left shift assignment</h3> + +<pre class="brush: js notranslate">let a = 5; +// 00000000000000000000000000000101 + +a <<= 2; // 20 +// 00000000000000000000000000010100</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.left_shift_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift">Left shift operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/less_than/index.html b/files/zh-cn/web/javascript/reference/operators/less_than/index.html new file mode 100644 index 0000000000..1a33554b98 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/less_than/index.html @@ -0,0 +1,110 @@ +--- +title: Less than (<) +slug: Web/JavaScript/Reference/Operators/Less_than +translation_of: Web/JavaScript/Reference/Operators/Less_than +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The less than operator (<code><</code>) returns <code>true</code> if the left operand is less than the right operand, and <code>false</code> otherwise.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-less-than.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"> x < y</pre> + +<h2 id="Description">Description</h2> + +<p>The operands are compared using the <a href="https://tc39.es/ecma262/#sec-abstract-relational-comparison">Abstract Relational Comparison</a> algorithm, which is roughly summarised below:</p> + +<ul> + <li>First, objects are converted to primitives using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive">Symbol.ToPrimitive</a></code> with the <code>hint</code> parameter be <code>'number'</code>.</li> + <li>If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.</li> + <li>Otherwise JavaScript attempts to convert non-numeric types to numeric values: + <ul> + <li>Boolean values <code>true</code> and <code>false</code> are converted to 1 and 0 respectively.</li> + <li><code>null</code> is converted to 0.</li> + <li><code>undefined</code> is converted to <code>NaN</code>.</li> + <li>Strings are converted based on the values they contain, and are converted as <code>NaN</code> if they do not contain numeric values.</li> + </ul> + </li> + <li>If either value is <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN">NaN</a></code>, the operator returns <code>false</code>.</li> + <li>Otherwise the values are compared as numeric values.</li> +</ul> + +<h2 id="Examples">Examples</h2> + +<h3 id="String_to_string_comparison">String to string comparison</h3> + +<pre class="brush: js notranslate">console.log("a" < "b"); // true +console.log("a" < "a"); // false +console.log("a" < "3"); // false</pre> + +<h3 id="String_to_number_comparison">String to number comparison</h3> + +<pre class="brush: js notranslate">console.log("5" < 3); // false +console.log("3" < 3); // false +console.log("3" < 5); // true + +console.log("hello" < 5); // false +console.log(5 < "hello"); // false + +console.log("5" < 3n); // false +console.log("3" < 5n); // true</pre> + +<h3 id="Number_to_Number_comparison">Number to Number comparison</h3> + +<pre class="brush: js notranslate">console.log(5 < 3); // false +console.log(3 < 3); // false +console.log(3 < 5); // true</pre> + +<h3 id="Number_to_BigInt_comparison">Number to BigInt comparison</h3> + +<pre class="brush: js notranslate">console.log(5n < 3); // false +console.log(3 < 5n); // true</pre> + +<h3 id="Comparing_Boolean_null_undefined_NaN">Comparing Boolean, null, undefined, NaN</h3> + +<pre class="brush: js notranslate">console.log(true < false); // false +console.log(false < true); // true + +console.log(0 < true); // true +console.log(true < 1); // false + +console.log(null < 0); // false +console.log(null < 1); // true + +console.log(undefined < 3); // false +console.log(3 < undefined); // false + +console.log(3 < NaN); // false +console.log(NaN < 3); // false</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.less_than")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than">Greater than operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal">Greater than or equal operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal">Less than or equal operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html b/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html new file mode 100644 index 0000000000..97a6f6746b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html @@ -0,0 +1,97 @@ +--- +title: 小于或等于 +slug: Web/JavaScript/Reference/Operators/Less_than_or_equal +translation_of: Web/JavaScript/Reference/Operators/Less_than_or_equal +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The less than or equal operator (<code><=</code>) returns <code>true</code> if the left operand is less than or equal to the right operand, and <code>false</code> otherwise.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-less-than-or-equal.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate"> x <= y</pre> + +<h2 id="Description">Description</h2> + +<p>The operands are compared using the <a class="external external-icon" href="https://tc39.es/ecma262/#sec-abstract-relational-comparison" rel="noopener">Abstract Relational Comparison</a> algorithm. See the documentation for the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">Less than</a> operator for a summary of this algorithm.</p> + +<h2 id="Examples">Examples</h2> + +<h3 id="String_to_string_comparison">String to string comparison</h3> + +<pre class="brush: js notranslate">console.log("a" <= "b"); // true +console.log("a" <= "a"); // true +console.log("a" <= "3"); // false +</pre> + +<h3 id="String_to_number_comparison">String to number comparison</h3> + +<pre class="brush: js notranslate">console.log("5" <= 3); // false +console.log("3" <= 3); // true +console.log("3" <= 5); // true + +console.log("hello" <= 5); // false +console.log(5 <= "hello"); // false</pre> + +<h3 id="Number_to_Number_comparison">Number to Number comparison</h3> + +<pre class="brush: js notranslate">console.log(5 <= 3); // false +console.log(3 <= 3); // true +console.log(3 <= 5); // true</pre> + +<h3 id="Number_to_BigInt_comparison">Number to BigInt comparison</h3> + +<pre class="brush: js notranslate">console.log(5n <= 3); // false +console.log(3 <= 3n); // true +console.log(3 <= 5n); // true</pre> + +<h3 id="Comparing_Boolean_null_undefined_NaN">Comparing Boolean, null, undefined, NaN</h3> + +<pre class="brush: js notranslate">console.log(true <= false); // false +console.log(true <= true); // true +console.log(false <= true); // true + +console.log(true <= 0); // false +console.log(true <= 1); // true + +console.log(null <= 0); // true +console.log(1 <= null); // false + +console.log(undefined <= 3); // false +console.log(3 <= undefined); // false + +console.log(3 <= NaN); // false +console.log(NaN <= 3); // false</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.less_than_or_equal")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than">Greater than operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal">Greater than or equal operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Less_than">Less than operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html new file mode 100644 index 0000000000..3ed9a1582a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html @@ -0,0 +1,83 @@ +--- +title: Logical AND assignment (&&=) +slug: Web/JavaScript/Reference/Operators/Logical_AND_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_AND_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The logical AND assignment (<code>x &&= y</code>) operator only assigns if <code>x</code> is {{Glossary("truthy")}}.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-and-assignment.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><em>expr1</em> &&= <em>expr2</em> +</pre> + +<h2 id="描述">描述</h2> + +<h3 id="Short-circuit_evaluation">Short-circuit evaluation</h3> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND">logical AND</a> operator is evaluated left to right, it is tested for possible short-circuit evaluation using the following rule:</p> + +<p><code>(some falsy expression) && expr</code> is short-circuit evaluated to the falsy expression;</p> + +<p>Short circuit means that the <code><em>expr</em></code> part above is <strong>not evaluated</strong>, hence any side effects of doing so do not take effect (e.g., if <code><em>expr</em></code> is a function call, the calling never takes place).</p> + +<p>Logical AND assignment short-circuits as well meaning that <code>x &&= y</code> is equivalent to:</p> + +<pre class="brush: js notranslate">x && (x = y);</pre> + +<p>And not equivalent to the following which would always perform an assignment:</p> + +<pre class="brush: js notranslate example-bad">x = x && y; +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="Using_logical_AND_assignment">Using logical AND assignment</h3> + +<pre class="brush: js notranslate">let x = 0; +let y = 1; + +x &&= 0; // 0 +x &&= 1; // 0 +y &&= 1; // 1 +y &&= 0; // 0 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.logical_and_assignment")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND">Logical AND (&&)</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">The nullish coalescing operator (<code>??</code>)</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND_assignment">Bitwise AND assignment (<code>&=</code>)</a></li> + <li>{{jsxref("Boolean")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_not/index.html b/files/zh-cn/web/javascript/reference/operators/logical_not/index.html new file mode 100644 index 0000000000..75084956a7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_not/index.html @@ -0,0 +1,104 @@ +--- +title: Logical NOT (!) +slug: Web/JavaScript/Reference/Operators/Logical_NOT +translation_of: Web/JavaScript/Reference/Operators/Logical_NOT +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The logical NOT (<code>!</code>) operator (logical complement, negation) takes truth to falsity and vice versa. It is typically used with {{jsxref("Boolean")}} (logical) values. When used with non-Boolean values, it returns <code>false</code> if its single operand can be converted to <code>true</code>; otherwise, returns <code>true</code>.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-not.html", "shorter")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">!<var>expr</var> +</pre> + +<h2 id="Description">Description</h2> + +<p>Returns <code>false</code> if its single operand can be converted to <code>true</code>; otherwise, returns <code>true</code>.</p> + +<p>If a value can be converted to <code>true</code>, the value is so-called {{Glossary("truthy")}}. If a value can be converted to <code>false</code>, the value is so-called {{Glossary("falsy")}}.</p> + +<p>Examples of expressions that can be converted to false are:</p> + +<ul> + <li><code>null</code>;</li> + <li><code>NaN</code>;</li> + <li><code>0</code>;</li> + <li>empty string (<code>""</code> or <code>''</code> or <code>``</code>);</li> + <li><code>undefined</code>.</li> +</ul> + +<p>Even though the <code>!</code> operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a <a href="/en-US/docs/Web/JavaScript/Data_structures#Boolean_type">boolean primitive</a>. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">NOT operator</a> or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.</p> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_NOT">Using NOT</h3> + +<p>The following code shows examples of the <code>!</code> (logical NOT) operator.</p> + +<pre class="brush: js notranslate">n1 = !true // !t returns false +n2 = !false // !f returns true +n3 = !'' // !f returns true +n4 = !'Cat' // !t returns false</pre> + +<h3 id="Double_NOT_!!">Double NOT (<code>!!</code>)</h3> + +<p>It is possible to use a couple of NOT operators in series to explicitly force the conversion of any value to the corresponding <a href="/en-US/docs/Web/JavaScript/Data_structures#Boolean_type">boolean primitive</a>. The conversion is based on the "truthyness" or "falsyness" of the value (see {{Glossary("truthy")}} and {{Glossary("falsy")}}).</p> + +<p>The same conversion can be done through the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} function.</p> + +<pre class="brush: js notranslate">n1 = !!true // !!truthy returns true +n2 = !!{} // !!truthy returns true: <strong>any</strong> object is truthy... +n3 = !!(new Boolean(false)) // ...even Boolean objects with a false <em>.valueOf()</em>! +n4 = !!false // !!falsy returns false +n5 = !!"" // !!falsy returns false +n6 = !!Boolean(false) // !!falsy returns false</pre> + +<h3 id="Converting_between_NOTs">Converting between NOTs</h3> + +<p>The following operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">!!bCondition</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">bCondition</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-logical-not-operator', 'Logical NOT expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.logical_not")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Boolean")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html new file mode 100644 index 0000000000..a57c18e5c2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html @@ -0,0 +1,82 @@ +--- +title: 逻辑空赋值 (??=) +slug: Web/JavaScript/Reference/Operators/Logical_nullish_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_nullish_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>逻辑空赋值运算符 (<code>x ??= y</code>) 仅在 <code>x</code> 是 {{Glossary("nullish")}} (<code>null</code> 或 <code>undefined</code>) 时对其赋值。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-nullish-assignment.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><em>expr1</em> ??= <em>expr2</em> +</pre> + +<h2 id="描述">描述</h2> + +<h3 id="语法短路求值">语法短路求值</h3> + +<p><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">空值合并</a>运算符从左至右求值,其使用以下规则测试是否可能进行语法短路求值:</p> + +<p><code>(结果非 null 或 undefined 的表达式) ?? expr</code> 被短路求值为左侧表达式,当左侧证明为既非 <code>null</code> 也非 <code>undefined</code>.</p> + +<p>语法短路意味着 <code><em>expr</em></code> 部分<strong>尚未被求值</strong>,因此任何与其求值产生的相关副作用都不会生效(例如,如果 <code><em>expr</em></code> 是一个函数调用,则该调用将不会发生)。</p> + +<p>逻辑空赋值的语法短路也意味着 <code>x ??= y</code> 等价于:</p> + +<pre class="brush: js notranslate">x ?? (x = y);</pre> + +<p>而不等价于如下的表达式,因为其一定会发生赋值:</p> + +<pre class="brush: js notranslate example-bad">x = x ?? y; +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="使用逻辑空赋值">使用逻辑空赋值</h3> + +<pre class="brush: js notranslate">function config(options) { + options.duration ??= 100; + options.speed ??= 25; + return options; +} + +config({ duration: 125 }); // { duration: 125, speed: 25 } +config({}); // { duration: 100, speed: 25 } +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.logical_nullish_assignment")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">The nullish coalescing operator (<code>??</code>)</a></li> + <li>{{Glossary("Nullish")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html b/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html new file mode 100644 index 0000000000..ba2b8c21bb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html @@ -0,0 +1,237 @@ +--- +title: 逻辑运算符 +slug: Web/JavaScript/Reference/Operators/Logical_Operators +tags: + - JavaScript + - 操作符 + - 逻辑 +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,<code>&&</code> 和 <code>||</code> 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}</div> + + + +<h2 id="描述">描述</h2> + +<p>逻辑运算符如下表所示 (其中<code><em>expr</em></code>可能是任何一种<a href="https://developer.mozilla.org/zh-CN/docs/Glossary/Data_structure">类型</a>, 不一定是布尔值):</p> + +<table class="fullwidth-table syntaxbox"> + <tbody> + <tr> + <th>运算符</th> + <th>语法</th> + <th>说明</th> + </tr> + <tr> + <td>逻辑与,AND(<code>&&</code>)</td> + <td><code><em>expr1</em> && <em>expr2</em></code></td> + <td>若 <code>expr<strong>1</strong></code> 可转换为 <code>true</code>,则返回 <code>expr<strong>2</strong></code>;否则,返回 <code>expr<strong>1</strong></code>。</td> + </tr> + <tr> + <td>逻辑或,OR(<code>||</code>)</td> + <td><code><em>expr1</em> || <em>expr2</em></code></td> + <td>若 <code>expr<strong>1</strong></code> 可转换为 <code>true</code>,则返回 <code>expr<strong>1</strong></code>;否则,返回 <code>expr<strong>2</strong></code>。</td> + </tr> + <tr> + <td>逻辑非,NOT(<code>!</code>)</td> + <td><code>!<em>expr</em></code></td> + <td>若 <code>expr</code> 可转换为 <code>true</code>,则返回 <code>false</code>;否则,返回 <code>true</code>。</td> + </tr> + </tbody> +</table> + +<p>如果一个值可以被转换为 <code>true</code>,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 <code>false</code>,那么这个值就是所谓的 {{Glossary("falsy")}}。</p> + +<p>会被转换为 <code>false</code> 的表达式有:</p> + +<ul> + <li><code>null</code>;</li> + <li><code>NaN</code>;</li> + <li><code>0</code>;</li> + <li>空字符串(<code>""</code> or <code>''</code> or <code>``</code>);</li> + <li><code>undefined</code>。</li> +</ul> + +<p>尽管 <code>&&</code> 和 <code>||</code> 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#%E9%80%BB%E8%BE%91%E9%9D%9E%EF%BC%88!%EF%BC%89">双重非运算符</a>(即<code>!!</code>)或者<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a>构造函数。</p> + +<h3 id="短路计算">短路计算</h3> + +<p>由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:</p> + +<ul> + <li><code>(some falsy expression) && (<em>expr)</em></code> 短路计算的结果为假。</li> + <li><code>(some truthy expression) || <em>(expr)</em></code> 短路计算的结果为真。</li> +</ul> + +<p>短路意味着上述表达式中的expr部分<strong>不会被执行</strong>,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:</p> + +<pre class="brush: js">function A(){ console.log('called A'); return false; } +function B(){ console.log('called B'); return true; } + +console.log( A() && B() ); +// logs "called A" due to the function call, +// then logs false (which is the resulting value of the operator) + +console.log( B() || A() ); +// logs "called B" due to the function call, +// then logs true (which is the resulting value of the operator) +</pre> + +<h3 id="Operators_precedence">Operators precedence</h3> + +<p>请注意,由于<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a>的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。</p> + +<pre class="brush: js">false && true || true // 结果为 true +false && (true || true) // 结果为 false +</pre> + +<h3 id="逻辑与()">逻辑与(<code>&&</code>)</h3> + +<p>下面的代码是 && (逻辑与) 运算符的示例.</p> + +<pre class="brush: js">a1 = true && true // t && t 返回 true +a2 = true && false // t && f 返回 false +a3 = false && true // f && t 返回 false +a4 = false && (3 == 4) // f && f 返回 false +a5 = "Cat" && "Dog" // t && t 返回 "Dog" +a6 = false && "Cat" // f && t 返回 false +a7 = "Cat" && false // t && f 返回 false +a8 = '' && false // f && f 返回 "" +a9 = false && '' // f && f 返回 false +</pre> + +<h3 id="逻辑或()">逻辑或(<code>||</code>)</h3> + +<p>下面的代码是 || (逻辑或) 运算符的示例。</p> + +<pre class="brush: js">o1 = true || true // t || t 返回 true +o2 = false || true // f || t 返回 true +o3 = true || false // t || f 返回 true +o4 = false || (3 == 4) // f || f 返回 false +o5 = "Cat" || "Dog" // t || t 返回 "Cat" +o6 = false || "Cat" // f || t 返回 "Cat" +o7 = "Cat" || false // t || f 返回 "Cat" +o8 = '' || false // f || f 返回 false +o9 = false || '' // f || f 返回 "" +</pre> + +<h3 id="逻辑非(!)">逻辑非(<code>!</code>)</h3> + +<p>下面的代码是 <code>!</code> (逻辑非) 运算符的示例.</p> + +<pre class="brush: js">n1 = !true // !t 返回 false +n2 = !false // !f 返回 true +n3 = !'' // !f 返回 true +n4 = !'Cat' // !t 返回 false +</pre> + +<h4 id="双重非(!!)运算符">双重非(<code>!!</code>)运算符</h4> + +<p>可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B">布尔值</a>。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。</p> + +<p>同样的转换可以通过 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a> 函数完成。</p> + +<pre class="brush: js syntaxbox">n1 = !!true // !!truthy 返回 true +n2 = !!{} // !!truthy 返回 true: <strong>任何</strong> 对象都是 truthy 的… +n3 = !!(new Boolean(false)) // …甚至 <em>.valueOf()</em> 返回 false 的布尔值对象也是! +n4 = !!false // !!falsy 返回 false +n5 = !!"" // !!falsy 返回 false +n6 = !!Boolean(false) // !!falsy 返回 false +</pre> + +<h3 id="布尔值转换规则">布尔值转换规则</h3> + +<h4 id="将_AND_转换为_OR">将 AND 转换为 OR</h4> + +<p>以下涉及<strong>布尔</strong>运算的操作:</p> + +<pre class="brush: js">bCondition1 && bCondition2</pre> + +<p>总是等于:</p> + +<pre class="brush: js">!(!bCondition1 || !bCondition2)</pre> + +<h4 id="将_OR_转换为_AND">将 OR 转换为 AND</h4> + +<p>以下涉及<strong>布尔</strong>运算的操作:</p> + +<pre class="brush: js">bCondition1 || bCondition2</pre> + +<p>总是等于:</p> + +<pre class="brush: js">!(!bCondition1 && !bCondition2)</pre> + +<h3 id="删除嵌套的小括号">删除嵌套的小括号</h3> + +<p>由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。</p> + +<h4 id="删除嵌套的_AND">删除嵌套的 AND</h4> + +<p>以下涉及<strong>布尔</strong>运算的操作:</p> + +<pre class="brush: js">bCondition1 || (bCondition2 && bCondition3)</pre> + +<p>总是等于:</p> + +<pre class="brush: js">bCondition1 || bCondition2 && bCondition3</pre> + +<h4 id="删除嵌套的_OR">删除嵌套的 OR</h4> + +<p>以下涉及<strong>布尔</strong>运算的操作:</p> + +<pre class="brush: js">bCondition1 && (bCondition2 || bCondition3)</pre> + +<p>总是等于:</p> + +<pre class="brush: js">!(!bCondition1 || !bCondition2 && !bCondition3)</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.11')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.9">Logical NOT Operator</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.11">Binary Logical Operators</a></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-binary-logical-operators')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-logical-not-operator">Logical NOT Operator</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-binary-logical-operators">Binary Logical Operators</a></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-binary-logical-operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Defined in several sections of the specification: <a href="http://tc39.github.io/ecma262/#sec-logical-not-operator">Logical NOT Operator</a>, <a href="http://tc39.github.io/ecma262/#sec-binary-logical-operators">Binary Logical Operators</a></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.logical")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">按位操作符</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean">布尔值</a></li> + <li><a href="/zh-CN/docs/Glossary/Truthy">Truthy</a></li> + <li><a href="/zh-CN/docs/Glossary/Falsy">Falsy</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_or/index.html b/files/zh-cn/web/javascript/reference/operators/logical_or/index.html new file mode 100644 index 0000000000..1a8f881377 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_or/index.html @@ -0,0 +1,146 @@ +--- +title: Logical OR (||) +slug: Web/JavaScript/Reference/Operators/Logical_OR +translation_of: Web/JavaScript/Reference/Operators/Logical_OR +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The logical OR (<code>||</code>) operator (logical disjunction) for a set of operands is true if and only if one or more of its operands is true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the <code>||</code> operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-or.html", "shorter")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><em>expr1</em> || <em>expr2</em> +</pre> + +<h2 id="Description">Description</h2> + +<p>If <code>expr<strong>1</strong></code> can be converted to <code>true</code>, returns <code>expr<strong>1</strong></code>; else, returns <code>expr<strong>2</strong></code>.</p> + +<p>If a value can be converted to <code>true</code>, the value is so-called {{Glossary("truthy")}}. If a value can be converted to <code>false</code>, the value is so-called {{Glossary("falsy")}}.</p> + +<p>Examples of expressions that can be converted to false are:</p> + +<ul> + <li><code>null</code>;</li> + <li><code>NaN</code>;</li> + <li><code>0</code>;</li> + <li>empty string (<code>""</code> or <code>''</code> or <code>``</code>);</li> + <li><code>undefined</code>.</li> +</ul> + +<p>Even though the <code>||</code> operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a <a href="/en-US/docs/Web/JavaScript/Data_structures#Boolean_type">boolean primitive</a>. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">NOT operator</a> or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.</p> + +<h3 id="Short-circuit_evaluation">Short-circuit evaluation</h3> + +<p>The logical OR expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:</p> + +<p><code>(some truthy expression) || <em>expr</em></code> is short-circuit evaluated to the truthy expression.</p> + +<p>Short circuit means that the <code><em>expr</em></code> part above is <strong>not evaluated</strong>, hence any side effects of doing so do not take effect (e.g., if <code><em>expr</em></code> is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:</p> + +<pre class="brush: js notranslate">function A(){ console.log('called A'); return false; } +function B(){ console.log('called B'); return true; } + +console.log( B() || A() ); +// logs "called B" due to the function call, +// then logs true (which is the resulting value of the operator) +</pre> + +<h3 id="Operator_precedence">Operator precedence</h3> + +<p>The following expressions might seem equivalent, but they are not, because the <code>&&</code> operator is executed before the <code>||</code> operator (see <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">operator precedence</a>).</p> + +<pre class="brush: js notranslate">true || false && false // returns true, because && is executed first +(true || false) && false // returns false, because operator precedence cannot apply</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_OR">Using OR</h3> + +<p>The following code shows examples of the <code>||</code> (logical OR) operator.</p> + +<pre class="brush: js notranslate">o1 = true || true // t || t returns true +o2 = false || true // f || t returns true +o3 = true || false // t || f returns true +o4 = false || (3 == 4) // f || f returns false +o5 = 'Cat' || 'Dog' // t || t returns "Cat" +o6 = false || 'Cat' // f || t returns "Cat" +o7 = 'Cat' || false // t || f returns "Cat" +o8 = '' || false // f || f returns false +o9 = false || '' // f || f returns "" +o10 = false || varObject // f || object returns varObject +</pre> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> If you use this operator to provide a default value to some variable, be aware that any <em>falsy</em> value will not be used. If you only need to filter out {{jsxref("null")}} or {{jsxref("undefined")}}, consider using <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">the nullish coalescing operator</a>.</p> +</div> + +<h3 id="Conversion_rules_for_booleans">Conversion rules for booleans</h3> + +<h4 id="Converting_AND_to_OR">Converting AND to OR</h4> + +<p>The following operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 && bCondition2</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">!(!bCondition1 || !bCondition2)</pre> + +<h4 id="Converting_OR_to_AND">Converting OR to AND</h4> + +<p>The following operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 || bCondition2</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">!(!bCondition1 && !bCondition2)</pre> + +<h3 id="Removing_nested_parentheses">Removing nested parentheses</h3> + +<p>As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.</p> + +<p>The following composite operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 && (bCondition2 || bCondition3)</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">!(!bCondition1 || !bCondition2 && !bCondition3)</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#prod-LogicalORExpression', 'Logical OR expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.logical_or")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">The nullish coalescing operator (<code>??</code>)</a></li> + <li>{{jsxref("Boolean")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html new file mode 100644 index 0000000000..ddd0dc8c79 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html @@ -0,0 +1,87 @@ +--- +title: Logical OR assignment (||=) +slug: Web/JavaScript/Reference/Operators/Logical_OR_assignment +translation_of: Web/JavaScript/Reference/Operators/Logical_OR_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The logical OR assignment (<code>x ||= y</code>) operator only assigns if <code>x</code> is {{Glossary("falsy")}}.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-or-assignment.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法"> 语法</h2> + +<pre class="syntaxbox notranslate"><em>expr1</em> ||= <em>expr2</em> +</pre> + +<h2 id="描述">描述</h2> + +<h3 id="Short-circuit_evaluation">Short-circuit evaluation</h3> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR">logical OR</a> operator works like this:</p> + +<pre class="brush: js notranslate">x || y; +// returns x when x is truthy +// returns y when x is not truthy</pre> + +<p>The logical OR operator short-circuits: the second operand is only evaluated if the first operand doesn’t already determine the result.</p> + +<p>Logical OR assignment short-circuits as well, meaning it only performs an assignment if the logical operation would evaluate the right-hand side. In other words, <code>x ||= y</code> is equivalent to:</p> + +<pre class="brush: js notranslate">x || (x = y); +</pre> + +<p>And not equivalent to the following which would always perform an assignment:</p> + +<pre class="brush: js notranslate example-bad">x = x || y; +</pre> + +<p>Note that this behavior is different to mathematical and bitwise assignment operators.</p> + +<h2 id="例子">例子</h2> + +<h3 id="Setting_default_content">Setting default content</h3> + +<p>If the "lyrics" element is empty, set the <code><a href="/en-US/docs/Web/API/Element/innerHTML">innerHTML</a></code> to a default value:</p> + +<pre class="brush: js notranslate">document.getElementById('lyrics').innerHTML ||= '<i>No lyrics.</i>'</pre> + +<p>Here the short-circuit is especially beneficial, since the element will not be updated unnecessarily and won't cause unwanted side-effects such as additional parsing or rendering work, or loss of focus, etc.</p> + +<p>Note: Pay attention to the value returned by the API you're checking against. If an empty string is returned (a {{Glossary("falsy")}} value), <code>||=</code> must be used, otherwise you want to use the <code>??=</code> operator (for {{jsxref("null")}} or {{jsxref("undefined")}} return values).</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.logical_or_assignment")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR">Logical OR (||)</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">The nullish coalescing operator (<code>??</code>)</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR_assignment">Bitwise OR assignment (<code>|=</code>)</a></li> + <li>{{jsxref("Boolean")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/multiplication/index.html b/files/zh-cn/web/javascript/reference/operators/multiplication/index.html new file mode 100644 index 0000000000..db346f4cbe --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/multiplication/index.html @@ -0,0 +1,69 @@ +--- +title: 乘法 (*) +slug: Web/JavaScript/Reference/Operators/Multiplication +translation_of: Web/JavaScript/Reference/Operators/Multiplication +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>乘法运算符 (<code>*</code>) 计算操作数的乘积。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-multiplication.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>x</var> * <var>y</var> +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="使用数字相乘">使用数字相乘</h3> + +<pre class="brush: js notranslate"> 2 * 2 // 4 +-2 * 2 // -4 +</pre> + +<h3 id="使用_Infinity_相乘">使用 Infinity 相乘</h3> + +<pre class="brush: js notranslate">Infinity * 0 // NaN +Infinity * Infinity // Infinity</pre> + +<h3 id="使用非数字相乘">使用非数字相乘</h3> + +<pre class="brush: js notranslate">'foo' * 2 // NaN</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Multiplication operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.multiplication")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html new file mode 100644 index 0000000000..e05019acba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html @@ -0,0 +1,55 @@ +--- +title: Multiplication assignment (*=) +slug: Web/JavaScript/Reference/Operators/Multiplication_assignment +translation_of: Web/JavaScript/Reference/Operators/Multiplication_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The multiplication assignment operator (<code>*=</code>) multiplies a variable by the value of the right operand and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-multiplication-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x *= y +<strong>Meaning:</strong> x = x * y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_multiplication_assignment">Using multiplication assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variable +// bar = 5 + +bar *= 2 // 10 +bar *= 'foo' // NaN</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.multiplication_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/new.target/index.html b/files/zh-cn/web/javascript/reference/operators/new.target/index.html new file mode 100644 index 0000000000..7d1c41ec89 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/new.target/index.html @@ -0,0 +1,99 @@ +--- +title: new.target +slug: Web/JavaScript/Reference/Operators/new.target +tags: + - Classes + - ECMAScript 2015 + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/new.target +--- +<div>{{JSSidebar("Operators")}}</div> + +<div><strong><code>new.target</code></strong>属性允许你检测函数或构造方法是否是通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/new">new</a>运算符被调用的。在通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/new">new</a>运算符被初始化的函数或构造方法中,<code>new.target</code>返回一个指向构造方法或函数的引用。在普通的函数调用中,<code>new.target</code> 的值是{{jsxref("undefined")}}。</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">new.target</pre> + +<h2 id="描述">描述</h2> + +<p><code>new.target</code>语法由一个关键字"<code>new</code>",一个点,和一个属性名"<font face="Consolas, Liberation Mono, Courier, monospace">target</font>"组成。通常"<code>new.</code>"<code>的</code>作用是提供属性访问的上下文,但这里"<code>new.</code>"其实不是一个真正的对象。不过在构造方法调用中,<code>new.target</code>指向被<code>new</code>调用的构造函数,所以"<code>new.</code>"成为了一个虚拟上下文。</p> + +<p><code>new.target</code>属性适用于所有函数访问的元属性。在 <a href="http://www.javascripttutorial.net/es6/javascript-arrow-function/">arrow functions</a> 中,<code>new.target</code> 指向最近的外层函数的<code>new.target</code>(An arrow function expression does not have its own this, arguments, super , or new.target) 。</p> + +<h2 id="示例">示例</h2> + +<h3 id="函数调用中的_new.target">函数调用中的 new.target</h3> + +<p>在普通的函数调用中(和作为构造函数来调用相对),<code>new.target</code>的值是{{jsxref("undefined")}}。这使得你可以检测一个函数是否是作为构造函数通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/new">new</a>被调用的。</p> + +<pre class="brush: js">function Foo() { + if (!new.target) throw "Foo() must be called with new"; + console.log("Foo instantiated with new"); +} + +Foo(); // throws "Foo() must be called with new" +new Foo(); // logs "Foo instantiated with new" +</pre> + +<h3 id="构造方法中的_new.target">构造方法中的 new.target</h3> + +<p>在类的构造方法中,<code>new.target</code>指向直接被<code>new</code>执行的构造函数。并且当一个父类构造方法在子类构造方法中被调用时,情况与之相同。</p> + +<pre class="brush: js">class A { + constructor() { + console.log(new.target.name); + } +} + +class B extends A { constructor() { super(); } } + +var a = new A(); // logs "A" +var b = new B(); // logs "B" + +class C { constructor() { console.log(new.target); } } +class D extends C { constructor() { super(); } } + +var c = new C(); // logs class C{constructor(){console.log(new.target);}} +var d = new D(); // logs class D extends C{constructor(){super();}} +</pre> + +<p class="summary">从上面类 C 和 D 的例子可以看出来,new.target 指向的是初始化类的类定义。比如当 D 通过 new 初始化的时候,打印出了 D 的类定义,C 的例子与之类似,打印出的是 C 的类定义。</p> + +<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('ES2015', '#sec-built-in-function-objects', 'Built-in Function Objects')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-built-in-function-objects', 'Built-in Function Objects')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </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.operators.new_target")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions">Functions</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Classes">Classes</a></li> + <li><code><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/new">new</a></code></li> + <li><code><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/this">this</a></code></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/new/index.html b/files/zh-cn/web/javascript/reference/operators/new/index.html new file mode 100644 index 0000000000..16ae8bfd75 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/new/index.html @@ -0,0 +1,201 @@ +--- +title: new 运算符 +slug: Web/JavaScript/Reference/Operators/new +tags: + - JavaScript + - Left-hand-side expressions + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/new +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><span class="seoSummary"><strong><code>new</code> 运算符</strong>创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。</span></p> + +<ol> +</ol> + +<p>{{EmbedInteractiveExample("pages/js/expressions-newoperator.html")}}</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">new <em>constructor</em>[([<em>arguments</em>])]</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>constructor</code></dt> + <dd>一个指定对象实例的类型的类或函数。</dd> +</dl> + +<dl> + <dt><code>arguments</code></dt> + <dd>一个用于被 <code>constructor</code> 调用的参数列表。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p><strong><code>new</code></strong> 关键字会进行如下的操作:</p> + +<ol> + <li>创建一个空的简单JavaScript对象(即<code><strong>{}</strong></code>);</li> + <li>链接该对象(设置该对象的<font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);"><strong>constructor</strong></span></font>)到另一个对象 ;</li> + <li>将步骤1新创建的对象作为<code><strong>this</strong></code>的上下文 ;</li> + <li>如果该函数没有返回对象,则返回<code><strong>this</strong></code>。</li> +</ol> + +<p>(译注:关于对象的 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);"><strong>constructor</strong></span></font>,参见 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);"><strong>Object.prototype.constructor</strong></span></font>)</p> + +<p>创建一个用户自定义的对象需要两步:</p> + +<ol> + <li>通过编写函数来定义对象类型。</li> + <li>通过 <code>new</code> 来创建对象实例。</li> +</ol> + +<p>创建一个对象类型,需要创建一个指定其名称和属性的函数;对象的属性可以指向其他对象,看下面的例子:</p> + +<p>当代码 <code>new <em>Foo</em>(...)</code> 执行时,会发生以下事情:</p> + +<ol> + <li>一个继承自 <code><em>Foo</em>.prototype</code> 的新对象被创建。</li> + <li>使用指定的参数调用构造函数 <em><code>Foo</code></em>,并将 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/this">this</a></code> 绑定到新创建的对象。<code>new <em>Foo</em></code> 等同于 <em><code>new Foo</code></em><code>()</code>,也就是没有指定参数列表,<em><code>Foo</code></em> 不带任何参数调用的情况。</li> + <li>由构造函数返回的对象就是 <code>new</code> 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)</li> +</ol> + +<p>你始终可以对已定义的对象添加新的属性。例如,<code>car1.color = "black"</code> 语句给 <code>car1</code> 添加了一个新的属性 <code>color</code>,并给这个属性赋值 "<code>black</code>"。但是,这不会影响任何其他对象。要将新属性添加到相同类型的所有对象,你必须将该属性添加到 <code>Car</code> 对象类型的定义中。</p> + +<p>你可以使用 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype">Function.prototype</a></code> 属性将共享属性添加到以前定义的对象类型。这定义了一个由该函数创建的所有对象共享的属性,而不仅仅是对象类型的其中一个实例。下面的代码将一个值为 <code>null</code> 的 <code>color</code> 属性添加到 <code>car</code> 类型的所有对象,然后仅在实例对象 <code>car1</code> 中用字符串 "<code>black</code>" 覆盖该值。详见 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype">prototype</a>。</p> + +<pre class="brush: js notranslate">function Car() {} +car1 = new Car(); +car2 = new Car(); + +console.log(car1.color); // undefined + +Car.prototype.color = "original color"; +console.log(car1.color); // original color + +car1.color = 'black'; +console.log(car1.color); // black + +console.log(car1.__proto__.color) //original color +console.log(car2.__proto__.color) //original color +console.log(car1.color) // black +console.log(car2.color) // original color +</pre> + +<div class="note"> +<p>如果你没有使用 <code>new</code> 运算符, <strong>构造函数会像其他的常规函数一样被调用,</strong> 并<em>不会创建一个对象<strong>。</strong></em>在这种情况下, <code>this</code> 的指向也是不一样的。</p> +</div> + +<h2 id="示例">示例</h2> + +<h3 id="对象类型和对象实例">对象类型和对象实例</h3> + +<p>假设你要创建一个汽车的对象类型。你希望这个类型叫做car,这个类型具备make, model, year等属性,要做到这些,你需要写这样一个函数:</p> + +<pre class="brush: js notranslate">function Car(make, model, year) { + this.make = make; + this.model = model; + this.year = year; +} +</pre> + +<p>现在,你可以如下所示创建一个 <code>mycar</code> 的对象:</p> + +<pre class="brush: js notranslate">var mycar = new Car("Eagle", "Talon TSi", 1993);</pre> + +<p>这段代码创建了 <code>mycar</code> 并给他的属性指定值,于是 <code>mycar.make</code> 的值为"<code>Eagle</code>", <code>mycar.year</code> 的值为1993,以此类推。</p> + +<p>你可以通过调用 <code>new</code> 来创建任意个汽车对象。例如:</p> + +<pre class="brush: js notranslate">var kenscar = new Car("Nissan", "300ZX", 1992);</pre> + +<h3 id="对象属性为其他对象">对象属性为其他对象</h3> + +<p>假设你定义了一个对象叫做 <code>person</code>:</p> + +<pre class="brush: js notranslate">function Person(name, age, sex) { + this.name = name; + this.age = age; + this.sex = sex; +} +</pre> + +<p>然后实例化两个新的 <code>person</code> 对象如下:</p> + +<pre class="brush: js notranslate">var rand = new Person("Rand McNally", 33, "M"); +var ken = new Person("Ken Jones", 39, "M"); +</pre> + +<p>然后你可以重写 <code>car</code> 的定义,添加一个值为 <code>person</code> 对象的 <code>owner</code> 属性,如下:</p> + +<pre class="brush: js notranslate">function Car(make, model, year, owner) { + this.make = make; + this.model = model; + this.year = year; + this.owner = owner; +} +</pre> + +<p>为了实例化新的对象,你可以用如下代码:</p> + +<pre class="brush: js notranslate">var car1 = new Car("Eagle", "Talon TSi", 1993, rand); +var car2 = new Car("Nissan", "300ZX", 1992, ken); +</pre> + +<p>创建对象时,并没有传字符串或数字给owner,而是传了对象 <code>rand</code> 和 <code>ken</code> 。这个时候,你可以这样来获取 <code>car2</code> 的owner的name:</p> + +<pre class="brush: js notranslate">car2.owner.name</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">说明</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-new-operator', 'The new Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-new-operator', 'The new Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.2.2', 'The new Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.2.2', 'The new Operator')}}</td> + <td>{{Spec2('ES3')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.2.2', 'The new Operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>初始定义。JavaScript 1.0实现。</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.operators.new")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("Reflect.construct()")}}</li> + <li>{{jsxref("Object.prototype")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html b/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html new file mode 100644 index 0000000000..640d0fffa5 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html @@ -0,0 +1,158 @@ +--- +title: 空值合并运算符 +slug: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator +tags: + - '??' + - JavaScript + - 参考 + - 空值 + - 空值合并操作符 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator +--- +<div>{{JSSidebar("Operators")}}</div> + +<p><strong>空值合并操作符</strong>(<strong><code>??</code></strong>)是一个逻辑操作符,当左侧的操作数为 {{jsxref("null")}} 或者 {{jsxref("undefined")}} 时,返回其右侧操作数,否则返回左侧操作数。</p> + +<p>与<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR_2">逻辑或操作符(<code>||</code>)</a>不同,逻辑或操作符会在左侧操作数为{{Glossary("Falsy", "假值")}}时返回右侧操作数。也就是说,如果使用 <code>||</code> 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,<code>''</code> 或 <code>0</code>)时。见下面的例子。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}</div> + +<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.<br> + See <a href="https://github.com/mdn/interactive-examples/pull/1482#issuecomment-553841750">PR #1482</a> regarding the addition of this example.</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><var>leftExpr</var> ?? <var>rightExpr</var> +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="使用空值合并操作符">使用空值合并操作符</h3> + +<p>在这个例子中,我们使用空值合并操作符为常量提供默认值,保证常量不为 <code>null</code> 或者 <code>undefined</code>。</p> + +<pre class="brush: js notranslate">const nullValue = null; +const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false +const someNumber = 42; + +const valA = nullValue ?? "valA 的默认值"; +const valB = emptyText ?? "valB 的默认值"; +const valC = someNumber ?? 0; + +console.log(valA); // "valA 的默认值" +console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined) +console.log(valC); // 42</pre> + +<h3 id="为变量赋默认值">为变量赋默认值</h3> + +<p>以前,如果想为一个变量赋默认值,通常的做法是使用逻辑或操作符(<code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR_2">||</a></code>):</p> + +<pre class="brush: js notranslate">let foo; + +// foo is never assigned any value so it is still undefined +let someDummyText = foo || 'Hello!';</pre> + +<p>然而,由于 <code>||</code> 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(<code>0</code>, <code>''</code>, <code>NaN</code>, <code>null</code>, <code>undefined</code>)都不会被返回。这导致如果你使用<code>0</code>,<code>''</code><font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">或</span></font><code>NaN</code>作为有效值,就会出现不可预料的后果。</p> + +<pre class="brush: js notranslate">let count = 0; +let text = ""; + +let qty = count || 42; +let message = text || "hi!"; +console.log(qty); // 42,而不是 0 +console.log(message); // "hi!",而不是 ""</pre> + +<p>空值合并操作符可以避免这种陷阱,其只在第一个操作数为<code>null</code> 或 <code>undefined</code> 时(而不是其它假值)返回第二个操作数:</p> + +<pre class="brush: js notranslate">let myText = ''; // An empty string (which is also a falsy value) + +let notFalsyText = myText || 'Hello world'; +console.log(notFalsyText); // Hello world + +let preservingFalsy = myText ?? 'Hi neighborhood'; +console.log(preservingFalsy); // '' (as myText is neither undefined nor null) +</pre> + +<h3 id="短路">短路</h3> + +<p>与 OR 和 AND 逻辑操作符相似,当左表达式不为 <code>null</code> 或 <code>undefined</code> 时,不会对右表达式进行求值。</p> + +<pre class="brush: js notranslate">function A() { console.log('函数 A 被调用了'); return undefined; } +function B() { console.log('函数 B 被调用了'); return false; } +function C() { console.log('函数 C 被调用了'); return "foo"; } + +console.log( A() ?? C() ); +// 依次打印 "函数 A 被调用了"、"函数 C 被调用了"、"foo" +// A() 返回了 undefined,所以操作符两边的表达式都被执行了 + +console.log( B() ?? C() ); +// 依次打印 "函数 B 被调用了"、"false" +// B() 返回了 false(既不是 null 也不是 undefined) +// 所以右侧表达式没有被执行 +</pre> + +<h3 id="不能与_AND_或_OR_操作符共用">不能与 AND 或 OR 操作符共用</h3> + +<p>将 <code>??</code> 直接与 AND(<code>&&</code>)和 OR(<code>||</code>)操作符组合使用是不可取的。(译者注:应当是因为空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的)这种情况下会抛出 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a></code> 。</p> + +<pre class="brush: js example-bad notranslate">null || undefined ?? "foo"; // 抛出 SyntaxError +true || undefined ?? "foo"; // 抛出 SyntaxError</pre> + +<p>但是,如果使用括号来显式表明运算优先级,是没有问题的:</p> + +<pre class="brush: js example-good notranslate">(null || undefined ) ?? "foo"; // 返回 "foo" +</pre> + +<h3 id="与可选链式操作符(.)的关系">与可选链式操作符(<code>?.</code>)的关系</h3> + +<p>空值合并操作符针对 <code>undefined</code> 与 <code>null</code> 这两个值,<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">可选链式操作符(<code>?.</code>)</a> 也是如此。在这访问属性可能为 <code>undefined</code> 与 <code>null</code> 的对象时,可选链式操作符非常有用。</p> + +<pre class="brush: js notranslate">let foo = { someFooProp: "hi" }; + +console.log(foo.someFooProp?.toUpperCase()); // "HI" +console.log(foo.someBarProp?.toUpperCase()); // undefined +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-Nulli', 'nullish coalescing expression')}}</td> + <td>Stage 4</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.nullish_coalescing")}}</p> + +<h3 id="Implementation_Progress">Implementation Progress</h3> + +<p>The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in <a href="https://github.com/tc39/test262">Test262</a>, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.</p> + +<div>{{EmbedTest262ReportResultsTable("coalesce-expression")}}</div> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining">可选链操作符</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR_2">逻辑或操作符(<code>||</code>)</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters">函数中的默认参数值</a></li> +</ul> + +<div id="gtx-trans" style="position: absolute; left: 161px; top: 68px;"> +<div class="gtx-trans-icon"></div> +</div> diff --git a/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html b/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html new file mode 100644 index 0000000000..90fb0e6a8a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/object_initializer/index.html @@ -0,0 +1,314 @@ +--- +title: 对象初始化 +slug: Web/JavaScript/Reference/Operators/Object_initializer +tags: + - ECMAScript 2015 + - JavaScript + - Literal + - Methods + - Object + - Primary Expression + - computed + - mutation + - properties +translation_of: Web/JavaScript/Reference/Operators/Object_initializer +--- +<div>{{JsSidebar("Operators")}}</div> + +<p>可以通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object"><code>new Object()</code></a>,<code> <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code>方法,或者使用字面量标记(初始化标记)初始化对象。 一个对象初始化器,由花括号/大括号 (<code>{}</code>) 包含的一个由零个或多个对象属性名和其关联值组成的一个逗号分隔的列表构成。</p> + +<h2 id="语法">语法</h2> + +<pre class="brush: js">var o = {}; +var o = {a: 'foo', b: 42, c: {}}; + +var a = 'foo', b = 42, c = {}; +var o = {a: a, b: b, c: c}; + +var o = { + property: function ([parameters]) {}, + get property() {}, + set property(value) {} +};</pre> + +<h3 id="ECMAScript_2015_的新标记">ECMAScript 2015 的新标记</h3> + +<p>请参考兼容性表格获取这些标记的支持信息。在不被支持的环境中,这些标记将造成语法错误。</p> + +<pre class="brush: js">// Shorthand property names (ES2015) +var a = 'foo', b = 42, c = {}; +var o = {a, b, c}; + +// Shorthand method names (ES2015) +var o = { + property([parameters]) {} +}; + +// Computed property names (ES2015) +var prop = 'foo'; +var o = { + [prop]: 'hey', + ['b' + 'ar']: 'there' +};</pre> + +<h2 id="描述">描述</h2> + +<p>对象初始化是一个描述{{jsxref("Object","对象")}}初始化过程的表达式。对象初始化是由一组描述对象的属性组成。属性的值可以是{{Glossary("primitive","原始")}}类型,也可以是其他对象。</p> + +<h3 id="创建对象">创建对象</h3> + +<p>没有属性的空对象可以用以下方式创建:</p> + +<pre class="brush: js">let obj = {};</pre> + +<p>不过,<em>字面 </em>和<em>初始化 </em>标记的优势在于,可以用内含属性的花括号快速创建对象。简单地编写一个逗号分隔的键值对的类别。如下代码创建了一个含三个属性的对象,键分别为 "<code>foo</code>", "<code>age</code>" 和 "<code>baz</code>"。这些键对应的值,分别是字符串“<code>bar</code>”,数字<code>42</code>和另一个对象。</p> + +<pre class="brush: js">let obj = { + foo: "bar", + age: 42, + baz: { myProp: 12 }, +}</pre> + +<h3 id="属性访问">属性访问</h3> + +<p>创建对象后,可以读取或者修改它。对象属性可以用下标小圆点标记或者方括号标记访问。参考<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">属性访问</a> 获取更多信息。</p> + +<pre class="brush: js">object.foo; // "bar" +object["age"]; // 42 + +object.foo = "baz"; +</pre> + +<h3 id="属性定义">属性定义</h3> + +<p>上面学习了如何用初始化标记对象属性。经常能遇到希望将代码中的变量放到对象中的情况。可能遇到如下代码:</p> + +<pre class="brush: js">var a = "foo", + b = 42, + c = {}; + +var o = { + a: a, + b: b, + c: c +};</pre> + +<p>在 ECMAScript 2015 中,有更简短的标记可以实现同样的效果:</p> + +<pre class="brush: js">var a = 'foo', + b = 42, + c = {}; + +// Shorthand property names (ES2015) +var o = {a, b, c}; + +// In other words, +console.log((o.a === {a}.a)); // true</pre> + +<h4 id="重复属性名">重复属性名</h4> + +<p>属性使用了同样的名称时,后面的属性会覆盖前面的属性。</p> + +<pre class="brush: js">var a = {x: 1, x: 2}; +console.log(a); // { x: 2} +</pre> + +<p>在 ECMAScript 5 严格模式的代码中, 重复的属性名会被当做{{jsxref("SyntaxError")}}。引入计算的属性名以后,属性名会在运行时出现重复。ECMAScript 2015 移除了这个限制。</p> + +<pre class="brush: js">function haveES6DuplicatePropertySemantics(){ + "use strict"; + try { + ({ prop: 1, prop: 2 }); + + // No error thrown, duplicate property names allowed in strict mode + return true; + } catch (e) { + // Error thrown, duplicates prohibited in strict mode + return false; + } +}</pre> + +<h3 id="方法定义">方法定义</h3> + +<p>对象属性也可以是一个<a href="/en-US/docs/Web/JavaScript/Reference/Functions">函数</a>、<a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a>、<a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a>方法。</p> + +<pre class="brush: js">var o = { + <var>property: function </var>([<var>parameters</var>]) {}, + get <var>property</var>() {}, + set <var>property</var>(<var>value</var>) {}, +};</pre> + +<p>ECMAScript 2015引入了一种简短写法, "function" 关键字也可以丢掉。</p> + +<pre class="brush: js">// Shorthand method names (ES6) +var o = { + <var>property</var>([<var>parameters</var>]) {}, + get <var>property</var>() {}, + set <var>property</var>(<var>value</var>) {}, + * <var>generator</var>() {} +};</pre> + +<p>ECMAScript 2015 提供了一种简明地定义以生成器函数作为值的属性的方法。</p> + +<pre class="brush: js">var o = { + * <var>generator</var>() { + ........... + } +};</pre> + +<p>ECMAScript 5 中可以这样书写(需要注意的是 ES5 没有生成器):</p> + +<pre class="brush: js">var o = { + generator<var>Method: function *</var>() { + ........... + } +};</pre> + +<p>获取更多信息和范例,请参考 <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a>。</p> + +<h3 id="计算属性名">计算属性名</h3> + +<p>从ECMAScript 2015开始,对象初始化语法开始支持计算属性名。其允许在[]中放入表达式,计算结果可以当做属性名。这种用法和用方括号访问<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">属性</a>非常类似,也许你已经用来读取和设置属性了。现在同样的语法也可以用于对象字面值了:</p> + +<pre class="brush: js">// Computed property names (ES6) +var i = 0; +var a = { + ["foo" + ++i]: i, + ["foo" + ++i]: i, + ["foo" + ++i]: i +}; + +console.log(a.foo1); // 1 +console.log(a.foo2); // 2 +console.log(a.foo3); // 3 + +var param = 'size'; +var config = { + [param]: 12, + ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4 +}; + +console.log(config); // { size: 12, mobileSize: 4 }</pre> + +<h3 id="扩展属性">扩展属性</h3> + +<p> </p> + +<p>ECMAScript 提案(第3阶段)的<a href="https://github.com/tc39/proposal-object-rest-spread">剩余/扩展属性</a>将<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator">扩展</a>属性添加到对象文字。它将自己提供的对象的枚举属性复制到一个新的对象上。</p> + +<p>使用比{{jsxref("Object.assign()")}}更短的语法,可以轻松克隆(不包括原型)或合并对象。</p> + +<p> </p> + +<pre class="brush: js">var obj1 = { foo: 'bar', x: 42 }; +var obj2 = { foo: 'baz', y: 13 }; + +var clonedObj = { ...obj1 }; +// Object { foo: "bar", x: 42 } + +var mergedObj = { ...obj1, ...obj2 }; +// Object { foo: "baz", x: 42, y: 13 } +</pre> + +<p>请注意,{{jsxref("Object.assign()")}}会触发<a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/set">setter</a>,而展开操作符则不会。</p> + +<h3 id="变更原型">变更原型</h3> + +<p>定义属性为<code>__proto__: 值</code> 或 <code>"__proto__": 值</code> 时,不会创建名为<code>__proto__</code>属性。如果给出的值是对象或者<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a>,那么对象的<code>[[Prototype]]</code>会被设置为给出的值。(如果给出的值不是对象也不是null,那么对象的原型不会改变。)</p> + +<pre class="brush: js">var obj1 = {}; +assert(Object.getPrototypeOf(obj1) === Object.prototype); + +var obj2 = { __proto__: null }; +assert(Object.getPrototypeOf(obj2) === null); + +var protoObj = {}; +var obj3 = { "__proto__": protoObj }; +assert(Object.getPrototypeOf(obj3) === protoObj); + +var obj4 = { __proto__: "not an object or null" }; +assert(Object.getPrototypeOf(obj4) === Object.prototype); +assert(!obj4.hasOwnProperty("__proto__")); +</pre> + +<p>在对象字面值中,仅有一次变更原型的机会;多次变更原型,会被视为语法错误。</p> + +<p>不使用冒号标记的属性定义,不会变更对象的原型;而是和其他具有不同名字的属性一样是普通属性定义。</p> + +<pre class="brush: js">var __proto__ = "variable"; + +var obj1 = { __proto__ }; +assert(Object.getPrototypeOf(obj1) === Object.prototype); +assert(obj1.hasOwnProperty("__proto__")); +assert(obj1.__proto__ === "variable"); + +var obj2 = { __proto__() { return "hello"; } }; +assert(obj2.__proto__() === "hello"); + +var obj3 = { ["__prot" + "o__"]: 17 }; +assert(obj3.__proto__ === 17); +</pre> + +<h2 id="对象字面量表示法与JSON">对象字面量表示法与JSON</h2> + +<p>对象字面量表示法和 <strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation(<a href="/en-US/docs/Glossary/JSON">JSON</a>)是不同的。虽然他们看起来相似,不同点有:</p> + +<ul> + <li>JSON 只允许<code>"property": value</code> syntax形式的属性定义。属性名必须用双引号括起来。且属性定义不允许使用简便写法。</li> + <li>JSON中,属性的值仅允许字符串,数字,数组,<code>true</code>,<code>false</code>,<code>null</code>或其他(JSON)对象。 </li> + <li>JSON中,不允许将值设置为函数。</li> + <li> {{jsxref("Date")}} 等对象,经{{jsxref("JSON.parse()")}}处理后,会变成字符串。</li> + <li>{{jsxref("JSON.parse()")}} 不会处理计算的属性名,会当做错误抛出。</li> +</ul> + +<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('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a> added.</td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Shorthand method/property names and computed property names added.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript </a></td> + <td>Draft</td> + <td>Stage 3 draft.</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.operators.object_initializer")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Property_Accessors">Property accessors</a></li> + <li><code><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/get">get</a></code> / <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/Method_definitions">Method definitions</a></li> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html b/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html new file mode 100644 index 0000000000..de411354aa --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html @@ -0,0 +1,351 @@ +--- +title: 运算符优先级 +slug: Web/JavaScript/Reference/Operators/Operator_Precedence +tags: + - JavaScript + - 优先级 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><span class="st">运算符的优先级决定了表达式中运算执行的先后顺序</span>,优先级高的运算符最先被执行。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}</div> + + + +<h2 id="Associativity" name="Associativity">关联性</h2> + +<p>关联性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:</p> + +<pre class="notranslate">a OP b OP c; +</pre> + +<p>左关联(左到右)相当于把左边的子表达式加上小括号<code>(a OP b) OP c</code>,右关联(右到左)相当于<code>a OP (b OP c)</code>。赋值运算符是右关联的,所以你可以这么写:</p> + +<pre class="notranslate">a = b = 5; </pre> + +<p>结果 <code>a</code> 和 <code>b</code> 的值都会成为5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:<code>b</code>被赋值为5,然后<code>a</code>也被赋值为 <code>b=5</code> 的返回值,也就是5。</p> + +<h2 id="示例">示例</h2> + +<pre class="brush: js notranslate">3 > 2 && 2 > 1 +// return true + +3 > 2 > 1 +// 返回 false,因为 3 > 2 是 true,并且 true > 1 is false +// 加括号可以更清楚:(3 > 2) > 1 +</pre> + +<h2 id="Table" name="Table">汇总表</h2> + +<p>下面的表将所有运算符按照优先级的不同从高(20)到低(1)排列。</p> + +<table class="fullwidth-table"> + <tbody> + <tr> + <th>优先级</th> + <th>运算类型</th> + <th>关联性</th> + <th>运算符</th> + </tr> + <tr> + <td>21</td> + <td>{{jsxref("Operators/Grouping", "圆括号")}}</td> + <td>n/a(不相关)</td> + <td><code>( … )</code></td> + </tr> + <tr> + <td rowspan="5">20</td> + <td>{{jsxref("Operators/Property_Accessors","成员访问", "#点符号表示法")}}</td> + <td>从左到右</td> + <td><code>… . …</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/Property_Accessors","需计算的成员访问", "#括号表示法")}}</td> + <td>从左到右</td> + <td><code>… [ … ]</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/new","new")}} (带参数列表)</td> + <td>n/a</td> + <td><code>new … ( … )</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Functions" title="JavaScript/Reference/Operators/Special_Operators/function_call">函数调用</a></td> + <td>从左到右</td> + <td><code>… ( <var>… </var>)</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining">可选链(Optional chaining)</a></td> + <td>从左到右</td> + <td><code>?.</code></td> + </tr> + <tr> + <td rowspan="1">19</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new" title="JavaScript/Reference/Operators/Special_Operators/new_Operator">new</a> (无参数列表)</td> + <td>从右到左</td> + <td><code>new …</code></td> + </tr> + <tr> + <td rowspan="2">18</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment" title="JavaScript/Reference/Operators/Arithmetic_Operators">后置递增</a>(运算符在后)</td> + <td colspan="1" rowspan="2">n/a<br> + </td> + <td><code>… ++</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement" title="JavaScript/Reference/Operators/Arithmetic_Operators">后置递减</a>(运算符在后)</td> + <td><code>… --</code></td> + </tr> + <tr> + <td colspan="1" rowspan="10">17</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">逻辑非</a></td> + <td colspan="1" rowspan="10">从右到左</td> + <td><code>! …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT" title="JavaScript/Reference/Operators/Bitwise_Operators">按位非</a></td> + <td><code>~ …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus" title="JavaScript/Reference/Operators/Arithmetic_Operators">一元加法</a></td> + <td><code>+ …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation" title="JavaScript/Reference/Operators/Arithmetic_Operators">一元减法</a></td> + <td><code>- …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment" title="JavaScript/Reference/Operators/Arithmetic_Operators">前置递增</a></td> + <td><code>++ …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement" title="JavaScript/Reference/Operators/Arithmetic_Operators">前置递减</a></td> + <td><code>-- …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof" title="JavaScript/Reference/Operators/Special_Operators/typeof_Operator">typeof</a></td> + <td><code>typeof …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/void" title="JavaScript/Reference/Operators/Special_Operators/void_Operator">void</a></td> + <td><code>void …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/delete" title="JavaScript/Reference/Operators/Special_Operators/delete_Operator">delete</a></td> + <td><code>delete …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a></td> + <td><code>await …</code></td> + </tr> + <tr> + <td>16</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation" title="JavaScript/Reference/Operators/Arithmetic_Operators">幂</a></td> + <td>从右到左</td> + <td><code>… ** …</code></td> + </tr> + <tr> + <td rowspan="3">15</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Multiplication" title="JavaScript/Reference/Operators/Arithmetic_Operators">乘法</a></td> + <td colspan="1" rowspan="3">从左到右<br> + </td> + <td><code>… * …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Division" title="JavaScript/Reference/Operators/Arithmetic_Operators">除法</a></td> + <td><code>… / …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder" title="JavaScript/Reference/Operators/Arithmetic_Operators">取模</a></td> + <td><code>… % …</code></td> + </tr> + <tr> + <td rowspan="2">14</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Addition" title="JavaScript/Reference/Operators/Arithmetic_Operators">加法</a></td> + <td colspan="1" rowspan="2">从左到右<br> + </td> + <td><code>… + …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Subtraction" title="JavaScript/Reference/Operators/Arithmetic_Operators">减法</a></td> + <td><code>… - …</code></td> + </tr> + <tr> + <td rowspan="3">13</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="JavaScript/Reference/Operators/Bitwise_Operators">按位左移</a></td> + <td colspan="1" rowspan="3">从左到右</td> + <td><code>… << …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="JavaScript/Reference/Operators/Bitwise_Operators">按位右移</a></td> + <td><code>… >> …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="JavaScript/Reference/Operators/Bitwise_Operators">无符号右移</a></td> + <td><code>… >>> …</code></td> + </tr> + <tr> + <td rowspan="6">12</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_operator" title="JavaScript/Reference/Operators/Comparison_Operators">小于</a></td> + <td colspan="1" rowspan="6">从左到右</td> + <td><code>… < …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than__or_equal_operator" title="JavaScript/Reference/Operators/Comparison_Operators">小于等于</a></td> + <td><code>… <= …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator" title="JavaScript/Reference/Operators/Comparison_Operators">大于</a></td> + <td><code>… > …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_or_equal_operator" title="JavaScript/Reference/Operators/Comparison_Operators">大于等于</a></td> + <td><code>… >= …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/in" title="JavaScript/Reference/Operators/Special_Operators/in_Operator">in</a></td> + <td><code>… in …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/instanceof" title="JavaScript/Reference/Operators/Special_Operators/instanceof_Operator">instanceof</a></td> + <td><code>… instanceof …</code></td> + </tr> + <tr> + <td rowspan="4">11</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality" title="JavaScript/Reference/Operators/Comparison_Operators">等号</a></td> + <td colspan="1" rowspan="4">从左到右<br> + </td> + <td><code>… == …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality" title="JavaScript/Reference/Operators/Comparison_Operators">非等号</a></td> + <td><code>… != …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity" title="JavaScript/Reference/Operators/Comparison_Operators">全等号</a></td> + <td><code>… === …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Nonidentity" title="JavaScript/Reference/Operators/Comparison_Operators">非全等号</a></td> + <td><code>… !== …</code></td> + </tr> + <tr> + <td>10</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND" title="JavaScript/Reference/Operators/Bitwise_Operators">按位与</a></td> + <td>从左到右</td> + <td><code>… & …</code></td> + </tr> + <tr> + <td>9</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR" title="JavaScript/Reference/Operators/Bitwise_Operators">按位异或</a></td> + <td>从左到右</td> + <td><code>… ^ …</code></td> + </tr> + <tr> + <td>8</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR" title="JavaScript/Reference/Operators/Bitwise_Operators">按位或</a></td> + <td>从左到右</td> + <td><code>… | …</code></td> + </tr> + <tr> + <td>7</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_AND" title="JavaScript/Reference/Operators/Logical_Operators">逻辑与</a></td> + <td>从左到右</td> + <td><code>… && …</code></td> + </tr> + <tr> + <td>6</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR" title="JavaScript/Reference/Operators/Logical_Operators">逻辑或</a></td> + <td>从左到右</td> + <td><code>… || …</code></td> + </tr> + <tr> + <td>5</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator" title="JavaScript/Reference/Operators/Nullish_coalescing_operator">空值合并</a></td> + <td>从左到右</td> + <td><code>… ?? …</code></td> + </tr> + <tr> + <td>4</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Conditional_Operator" title="JavaScript/Reference/Operators/Special_Operators/Conditional_Operator">条件运算符</a></td> + <td>从右到左</td> + <td><code>… ? … : …</code></td> + </tr> + <tr> + <td rowspan="16">3</td> + <td rowspan="16"><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment_Operators" title="JavaScript/Reference/Operators/Assignment_Operators">赋值</a></td> + <td rowspan="16">从右到左</td> + <td><code>… = …</code></td> + </tr> + <tr> + <td><code>… += …</code></td> + </tr> + <tr> + <td><code>… -= …</code></td> + </tr> + <tr> + <td><code>… **= …</code></td> + </tr> + <tr> + <td><code>… *= …</code></td> + </tr> + <tr> + <td><code>… /= …</code></td> + </tr> + <tr> + <td><code>… %= …</code></td> + </tr> + <tr> + <td><code>… <<= …</code></td> + </tr> + <tr> + <td><code>… >>= …</code></td> + </tr> + <tr> + <td><code>… >>>= …</code></td> + </tr> + <tr> + <td><code>… &= …</code></td> + </tr> + <tr> + <td><code>… ^= …</code></td> + </tr> + <tr> + <td><code>… |= …</code></td> + </tr> + <tr> + <td><code>… &&= …</code></td> + </tr> + <tr> + <td><code>… ||= …</code></td> + </tr> + <tr> + <td><code>… ??= …</code></td> + </tr> + <tr> + <td colspan="1" rowspan="2">2</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield" title="JavaScript/Reference/Operators/yield">yield</a></td> + <td colspan="1" rowspan="2">从右到左</td> + <td><code>yield …</code></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield*" title="JavaScript/Reference/Operators/yield">yield*</a></td> + <td><code>yield* …</code></td> + </tr> + <tr> + <td>1</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator" title="JavaScript/Reference/Operators/Spread_operator">展开运算符</a></td> + <td>n/a</td> + <td><code>...</code> …</td> + </tr> + <tr> + <td>0</td> + <td><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comma_Operator" title="JavaScript/Reference/Operators/Comma_Operator">逗号</a></td> + <td>从左到右</td> + <td><code>… , …</code></td> + </tr> + </tbody> +</table> diff --git a/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html b/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html new file mode 100644 index 0000000000..f989fe1f22 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html @@ -0,0 +1,153 @@ +--- +title: 属性访问器 +slug: Web/JavaScript/Reference/Operators/Property_Accessors +tags: + - JavaScript + - Operator + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/Property_Accessors +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>属性访问器提供了两种方式用于访问一个对象的属性,它们分别是点号和方括号。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-propertyaccessors.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">object.property +object['property'] +</pre> + +<h2 id="描述">描述</h2> + +<p class="syntaxbox">我们可以将对象看做是一个<em>关联数组(</em>或者:<em>映射</em>、<em>字典</em>、<em>哈希表</em>、<em>查询表</em>)。这个数组中的键就是这个对象中属性的名称。通常,当我们提及一个对象的属性时,会对属性与方法之间做个对比。然而,属性与方法之间的区别并不大。一个方法就是一个可以被调用的属性而已,例如一个指向函数 <a href="/zh-CN/docs/Glossary/Function">Function</a> 实例的引用可以作为对象属性的值。</p> + +<p>访问对象属性有两种方式:点号表示法和方括号表示法。</p> + +<h3 id="点号表示法">点号表示法</h3> + +<pre class="brush: js">get = object.property; +object.property = set; +</pre> + +<p>以上代码中,<code>property</code>必须是一个有效的 JavaScript 标识符,例如,一串字母数字字符,也包括下划线及美元符号,但不能以数字作为开头。比如,<code>object.$1</code>是合法的,而 <code>object.1</code>是无效不合法的。</p> + +<pre class="brush: js">document.createElement('pre'); +</pre> + +<p>在上述代码块中,<code>document</code>中存在一个名为"createElement"的方法并且被调用了。</p> + +<p>如果对数字字面量使用方法,并且数字文字没有指数且没有小数点,请在方法调用之前的点之前留出空格,以防止点被解释为小数点。</p> + +<pre class="brush: js">77 .toExponential(); +// 或 +77 +.toExponential(); +// 或 +(77).toExponential(); +// 或 +77..toExponential(); +// 或 +77.0.toExponential(); +// 因为 77. === 77.0,没有歧义(no ambiguity) +</pre> + +<h3 id="方括号表示法">方括号表示法</h3> + +<pre class="brush: js">get = object[property_name]; +object[property_name] = set; +</pre> + +<p><code>property_name</code> 是一个字符串。该字符串不一定是一个合法的标识符;它可以是任意值,例如,"1foo","!bar!",甚至是 " "(一个空格)。</p> + +<pre class="brush: js">document['createElement']('pre'); +</pre> + +<p>这里的代码的功能跟上一个例子的作用是相同的。</p> + +<p>括号之前允许有空格。</p> + +<pre class="brush: js">document ['createElement']('pre'); +</pre> + +<h3 id="属性名称">属性名称</h3> + +<p>属性名称必须是字符串或符号 Symbol。这意味着非字符串对象不能用来作为一个对象属性的键。任何非字符串对象,包括 Number,都会通过 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString">toString</a> 方法,被转换成一个字符串。</p> + +<pre class="brush: js">var object = {}; +object['1'] = 'value'; +console.log(object[1]); +</pre> + +<p>上述代码的输出为"value",因为 1 被类型转换为'1'。</p> + +<pre class="brush: js">var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {}; +object[foo] = 'value'; +console.log(object[bar]); +</pre> + +<p>上述的代码的输出也是 "value",由于对象 foo 和 bar 都会被转成相同的字符串。在<a href="/zh-CN/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> JavaScript 引擎中,这个字符串是 "[object Object]"。</p> + +<h3 id="方法绑定">方法绑定</h3> + +<p>一个方法没有绑定到对象上,那就意味着这个方法是不起作用的。特别要注意的是,在一个方法中<code>this</code>对象并不是固定的,例如,<code>this</code>不需要指向包含当前方法的对象。<code>this</code>可通过函数调用被传递过去的值所替换。详见<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/this#Method_binding">方法绑定</a>。</p> + +<h3 id="注意eval">注意<code>eval</code></h3> + +<p>在那些可通过方括号表示法替换的场景下,JavaScript 新手在使用<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval">eval</a> 经常会犯错。例如,下面的语法经常在很多代码中找到。</p> + +<pre class="brush: js">x = eval('document.forms.form_name.elements.' + strFormControl + '.value'); +</pre> + +<p><a href="https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/"><code>eval</code></a> 的性能较差,且有安全风险。在任何时候都应该避免使用。而且,此时 <code>strFormControl</code> 必须是一个合法的标识符, 这在一些表单控件的 name、ID 值之中并不是必要的。所以,使用括号来代替会更好一些:</p> + +<pre class="brush: js">x = document.forms["form_name"].elements[strFormControl].value; +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-property-accessors', 'Property Accessors')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-property-accessors', 'Property Accessors')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.2.1', 'Property Accessors')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.2.1', 'Property Accessors')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.0.</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.operators.property_accessors")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li>{{jsxref("Object")}}</li> + <li>{{jsxref("Object/defineProperty")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html new file mode 100644 index 0000000000..a9d015e467 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html @@ -0,0 +1,56 @@ +--- +title: Remainder assignment (%=) +slug: Web/JavaScript/Reference/Operators/Remainder_assignment +translation_of: Web/JavaScript/Reference/Operators/Remainder_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The remainder assignment operator (<code>%=</code>) divides a variable by the value of the right operand and assigns the remainder to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-remainder-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x %= y +<strong>Meaning:</strong> x = x % y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_remainder_assignment">Using remainder assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variable +// bar = 5 + +bar %= 2 // 1 +bar %= 'foo' // NaN +bar %= 0 // NaN</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.remainder_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/right_shift/index.html b/files/zh-cn/web/javascript/reference/operators/right_shift/index.html new file mode 100644 index 0000000000..267a2c0ccc --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/right_shift/index.html @@ -0,0 +1,75 @@ +--- +title: Right shift (>>) +slug: Web/JavaScript/Reference/Operators/Right_shift +translation_of: Web/JavaScript/Reference/Operators/Right_shift +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The <strong>right shift operator (<code>>></code>)</strong> shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-right-shift.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> >> <var>b</var></code> +</pre> + +<h2 id="Description">Description</h2> + +<p>This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".</p> + +<p>For example, <code>9 >> 2</code> yields 2:</p> + +<pre class="brush: js notranslate">. 9 (base 10): 00000000000000000000000000001001 (base 2) + -------------------------------- +9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10) +</pre> + +<p>Likewise, <code>-9 >> 2</code> yields <code>-3</code>, because the sign is preserved:</p> + +<pre class="brush: js notranslate">. -9 (base 10): 11111111111111111111111111110111 (base 2) + -------------------------------- +-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10) +</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_right_shift">Using right shift</h3> + +<pre class="brush: js notranslate"> 9 >> 2; // 2 +-9 >> 2; // -3 +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.right_shift")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift_assignment">Right shift assignment operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html new file mode 100644 index 0000000000..d4163c0f4d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Right shift assignment (>>=) +slug: Web/JavaScript/Reference/Operators/Right_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Right_shift_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The right shift assignment operator (<code>>>=</code>) moves the specified amount of bits to the right and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-right-shift-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x >>= y +<strong>Meaning:</strong> x = x >> y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_right_shift_assignment">Using right shift assignment</h3> + +<pre class="brush: js notranslate">let a = 5; // (00000000000000000000000000000101) +a >>= 2; // 1 (00000000000000000000000000000001) + +let b = -5; // (-00000000000000000000000000000101) +b >>= 2; // -2 (-00000000000000000000000000000010)</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.right_shift_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift">Right shift operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html b/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html new file mode 100644 index 0000000000..4bb2ff8b45 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html @@ -0,0 +1,245 @@ +--- +title: 展开语法 +slug: Web/JavaScript/Reference/Operators/Spread_syntax +tags: + - ECMAScript2015 + - Iterator + - JavaScript + - 展开 +translation_of: Web/JavaScript/Reference/Operators/Spread_syntax +--- +<div>{{jsSidebar("Operators")}}</div> + +<div><strong>展开语法(Spread syntax), </strong>可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。(<strong>译者注</strong>: 字面量一般指 <code>[1, 2, 3]</code> 或者 <code>{name: "mdn"}</code> 这种简洁的构造方式)</div> + +<div>{{EmbedInteractiveExample("pages/js/expressions-spreadsyntax.html")}}</div> + +<p class="hidden">该示例的源代码存放于Github中,如果你想进行修订,请先克隆<a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a>, 修改完成之后再通过pull request的方式推送给源仓库。</p> + +<h2 id="语法"><font><font>语法</font></font></h2> + +<p><font><font>函数调用:</font></font></p> + +<pre class="syntaxbox notranslate">myFunction(...iterableObj);</pre> + +<p><font><font>字面量数组构造或字符串:</font></font></p> + +<pre class="notranslate">[...iterableObj, '4', ...'hello', 6];</pre> + +<p>构造字面量对象时,进行克隆或者属性拷贝(ECMAScript 2018规范新增特性):</p> + +<pre class="syntaxbox notranslate">let objClone = { ...obj };</pre> + +<h2 id="示例"><font><font>示例</font></font></h2> + +<h3 id="在函数调用时使用展开语法">在函数调用时使用展开语法</h3> + +<h4 id="等价于apply的方式">等价于apply的方式</h4> + +<p><font><font>如果想将数组元素迭代为函数参数,一般使用</font></font>{{jsxref( "Function.prototype.apply")}} 的方式进行调用<font><font>。</font></font></p> + +<pre class="brush: js notranslate">function myFunction(x, y, z) { } +var args = [0, 1, 2]; +myFunction.apply(null, args);</pre> + +<p><font><font>有了展开语法,可以这样写:</font></font></p> + +<pre class="brush: js notranslate"><code>function myFunction(x, y, z) { } +var args = [0, 1, 2]; +myFunction(...args);</code></pre> + +<p><font><font>所有参数都可以通过展开语法来传值,也不限制多次使用展开语法。</font></font></p> + +<pre class="brush: js notranslate">function myFunction(v, w, x, y, z) { } +var args = [0, 1]; +myFunction(-1, ...args, 2, ...[3]);</pre> + +<h4 id="在_new_表达式中应用">在 new 表达式中应用</h4> + +<p><font><font>使用 </font></font><code>new</code><font><font> 关键字来调用构造函数时</font></font><font><font>,不能</font></font><strong><font><font>直接</font></font></strong><font><font>使用数组+ </font></font><code>apply</code><font><font> 的方式(</font></font><code>apply</code><font><font> 执行的是调用 </font></font><code>[[Call]]</code><font><font> , 而不是构造 </font></font><code>[[Construct]]</code><font><font>)。当然</font><font>, 有了展开语法, 将数组展开为构造函数的参数就很简单了:</font></font></p> + +<pre class="brush: js notranslate"><font><font>var dateFields = [1970, 0, 1]; </font><font>// 1970年1月1日</font></font><font><font> +var d = new Date(...dateFields);</font></font> +</pre> + +<p><font><font>如果不使用展开语法, 想将数组元素传给构造函数, 实现方式可能是这样的</font></font><font><font>:</font></font></p> + +<pre class="brush: js notranslate">function applyAndNew(constructor, args) { + function partial () { + return constructor.apply(this, args); + }; + if (typeof constructor.prototype === "object") { + partial.prototype = Object.create(constructor.prototype); + } + return partial; +} + + +function myConstructor () { + console.log("arguments.length: " + arguments.length); + console.log(arguments); + this.prop1="val1"; + this.prop2="val2"; +}; + +var myArguments = ["hi", "how", "are", "you", "mr", null]; +var myConstructorWithArguments = applyAndNew(myConstructor, myArguments); + +console.log(new myConstructorWithArguments); +// (myConstructor构造函数中): arguments.length: 6 +// (myConstructor构造函数中): ["hi", "how", "are", "you", "mr", null] +// ("new myConstructorWithArguments"中): {prop1: "val1", prop2: "val2"}</pre> + +<h3 id="构造字面量数组时使用展开语法"><font><font>构造字面量数组时使用展开语法</font></font></h3> + +<h4 id="构造字面量数组时更给力!"><font><font>构造字面量数组时更给力!</font></font></h4> + +<p><font><font>没有展开语法的时候,只能组合使用 </font></font><code>push</code><font><font>, </font></font><code>splice</code><font><font>, </font></font><code>concat</code><font><font> 等方法,来将已有数组元素变成新数组的一部分。有了展开语法, 通过字面量方式, 构造新数组会变得更简单、更优雅:</font></font></p> + +<pre class="brush: js notranslate"><font><font>var parts = ['shoulders', 'knees']; +var lyrics = ['head', ...parts, 'and', 'toes']; </font></font> +// ["head", "shoulders", "knees", "and", "toes"] +</pre> + +<p>和参数列表的展开类似, <code>...</code> 在构造字面量数组时, 可以在任意位置多次使用.</p> + +<h4 id="数组拷贝copy">数组拷贝(copy)</h4> + +<pre class="brush: js notranslate">var arr = [1, 2, 3]; +var arr2 = [...arr]; // like arr.slice() +arr2.push(4); + +// arr2 此时变成 [1, 2, 3, 4] +// arr 不受影响 +</pre> + +<p><strong>提示:</strong> 实际上, 展开语法和 {{jsxref("Object.assign()")}} 行为一致, 执行的都是浅拷贝(只遍历一层)。如果想对多维数组进行深拷贝, 下面的示例就有些问题了。</p> + +<pre class="brush: js notranslate">var a = [[1], [2], [3]]; +var b = [...a]; +b.shift().shift(); // 1 +// Now array a is affected as well: [[2], [3]] +</pre> + +<h4 id="连接多个数组">连接多个数组</h4> + +<p>{{jsxref("Array.concat")}} 函数常用于将一个数组连接到另一个数组的后面。如果不使用展开语法, 代码可能是下面这样的:</p> + +<pre class="brush: js notranslate">var arr1 = [0, 1, 2]; +var arr2 = [3, 4, 5]; +// 将 arr2 中所有元素附加到 arr1 后面并返回 +var arr3 = arr1.concat(arr2);</pre> + +<p>使用展开语法:</p> + +<pre class="brush: js notranslate">var arr1 = [0, 1, 2]; +var arr2 = [3, 4, 5]; +var arr3 = [...arr1, ...arr2]; +</pre> + +<p>{{jsxref("Array.unshift")}} 方法常用于在数组的开头插入新元素/数组. 不使用展开语法, 示例如下:</p> + +<pre class="brush: js notranslate">var arr1 = [0, 1, 2]; +var arr2 = [3, 4, 5]; +// 将 arr2 中的元素插入到 arr1 的开头 +Array.prototype.unshift.apply(arr1, arr2) // arr1 现在是 [3, 4, 5, 0, 1, 2]</pre> + +<p>如果使用展开语法, 代码如下: [请注意, 这里使用展开语法创建了一个新的 <code>arr1</code> 数组, {{jsxref("Array.unshift")}} 方法则是修改了原本存在的 <code>arr1</code> 数组]:</p> + +<pre class="brush: js notranslate">var arr1 = [0, 1, 2]; +var arr2 = [3, 4, 5]; +arr1 = [...arr2, ...arr1]; // arr1 现在为 [3, 4, 5, 0, 1, 2] +</pre> + +<h3 id="构造字面量对象时使用展开语法">构造<font><font>字面量对象时使用展开语法</font></font></h3> + +<p><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript</a> 提议(stage 4) 对 <a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer">字面量对象</a> 增加了展开特性。其行为是, 将已有对象的所有可枚举(enumerable)属性拷贝到新构造的对象中.</p> + +<p>浅拷贝(Shallow-cloning, 不包含 prototype) 和对象合并, 可以使用更简短的展开语法。而不必再使用 {{jsxref("Object.assign()")}} 方式.</p> + +<pre class="brush: js notranslate">var obj1 = { foo: 'bar', x: 42 }; +var obj2 = { foo: 'baz', y: 13 }; + +var clonedObj = { ...obj1 }; +// 克隆后的对象: { foo: "bar", x: 42 } + +var mergedObj = { ...obj1, ...obj2 }; +// 合并后的对象: { foo: "baz", x: 42, y: 13 } +</pre> + +<p><strong>提示</strong>: {{jsxref("Object.assign()")}} 函数会触发 <a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/set">setters</a>,而展开语法则不会。</p> + + + +<p><strong>提示</strong>: 不能替换或者模拟 {{jsxref("Object.assign()")}} 函数:</p> + +<pre class="notranslate"><code>var obj1 = { foo: 'bar', x: 42 }; +var obj2 = { foo: 'baz', y: 13 }; +const merge = ( ...objects ) => ( { ...objects } ); + +var mergedObj = merge ( obj1, obj2); +// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } } + +var mergedObj = merge ( {}, obj1, obj2); +// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }</code></pre> + +<p>在这段代码中, 展开操作符(spread operator)并没有按预期的方式执行: 而是先将多个解构变为剩余参数(rest parameter), 然后再将剩余参数展开为字面量对象.</p> + + + +<h3 id="只能用于可迭代对象">只能用于可迭代对象</h3> + +<p>在数组或函数参数中使用展开语法时, 该语法只能用于 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator">可迭代对象</a>:</p> + +<pre class="brush: js notranslate">var obj = {'key1': 'value1'}; +var array = [...obj]; // TypeError: obj is not iterable +</pre> + +<h3 id="展开多个值">展开多个值</h3> + +<p>在函数调用时使用展开语法,请注意不能超过 JavaScript 引擎限制的最大参数个数。更多详细信息,请参考: <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" title="apply()方法使用给定的这个值调用一个函数,并以一个数组(或类似数组的对象)的形式提供参数。"><code>apply()</code></a>。</p> + +<h2 id="剩余语法(剩余参数)">剩余语法(剩余参数)</h2> + +<p>剩余语法(Rest syntax) 看起来和展开语法完全相同,不同点在于, 剩余参数用于解构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。 请参考: <a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters">剩余参数</a>。</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#sec-array-initializer')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-array-initializer">Array Initializer</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-argument-lists">Argument Lists</a></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-array-initializer')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>No changes.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-object-initializer')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Defined in <a href="https://tc39.github.io/ecma262/2018/#sec-object-initializer">Object Initializer</a></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性"><font><font>浏览器兼容性</font></font></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.operators.spread")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters"><font><font>剩余参数</font></font></a><font><font>(Rest Parameters也使用' </font></font><code>...</code><font><font> ')</font></font></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html b/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html new file mode 100644 index 0000000000..125b67c168 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/strict_equality/index.html @@ -0,0 +1,101 @@ +--- +title: Strict equality (===) +slug: Web/JavaScript/Reference/Operators/Strict_equality +translation_of: Web/JavaScript/Reference/Operators/Strict_equality +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>全等运算符 (===) 会检查它的两个操作数是否相等,并且返回一个布尔值结果。与相等运算符不同,全等运算符总是认为不同类型的操作数是不同的。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">x === y</pre> + +<h2 id="描述">描述</h2> + +<p>全等运算符(<code>===</code>和 <code>!==</code>)使用<a class="external external-icon" href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.6" rel="noopener">全等比较算法</a>来比较两个操作数。</p> + +<ul> + <li>如果操作数的类型不同,则返回 <code>false</code>。</li> + <li>如果两个操作数都是对象,只有当它们指向同一个对象时才返回 <code>true</code>。</li> + <li>如果两个操作数都为 <code>null</code>,或者两个操作数都为 <code>undefined</code>,返回 <code>true</code>。</li> + <li>如果两个操作数有任意一个为 <code>NaN</code>,返回 <code>false</code>。</li> + <li>否则,比较两个操作数的值: + <ul> + <li>数字类型必须拥有相同的数值。<code>+0</code> 和 <code>-0</code> 会被认为是相同的值。</li> + <li>字符串类型必须拥有相同顺序的相同字符。</li> + <li>布尔运算符必须同时为 <code>true</code> 或同时为 <code>false</code>。</li> + </ul> + </li> +</ul> + +<p>全等运算符与<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Equality">相等运算符</a>(<code>==</code>)最显著的区别是,如果操作数的类型不同,<code>== </code>运算符会在比较之前尝试将它们转换为相同的类型。</p> + +<h2 id="例子">例子</h2> + +<h3 id="比较相同类型的操作数">比较相同类型的操作数</h3> + +<pre class="brush: js notranslate">console.log("hello" === "hello"); // true +console.log("hello" === "hola"); // false + +console.log(3 === 3); // true +console.log(3 === 4); // false + +console.log(true === true); // true +console.log(true === false); // false + +console.log(null === null); // true</pre> + +<h3 id="比较不同类型的操作数">比较不同类型的操作数</h3> + +<pre class="brush: js notranslate">console.log("3" === 3); // false + +console.log(true === 1); // false + +console.log(null === undefined); // false</pre> + +<h3 id="比较对象">比较对象</h3> + +<pre class="brush: js notranslate">const object1 = { + name: "hello" +} + +const object2 = { + name: "hello" +} + +console.log(object1 === object2); // false +console.log(object1 === object1); // true</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.strict_equality")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Equality">Equality operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Inequality">Inequality operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_inequality">Strict inequality operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html b/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html new file mode 100644 index 0000000000..e71f28c100 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html @@ -0,0 +1,95 @@ +--- +title: 严格不相等 (!==) +slug: Web/JavaScript/Reference/Operators/Strict_inequality +translation_of: Web/JavaScript/Reference/Operators/Strict_inequality +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><span>严格不等式操作符(!==)检查它的两个对象是否不相等,返回一个布尔结果。与不等式运算符不同,严格不等式运算符总是认为不同类型的对象是不同的。</span></p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">x !== y</pre> + +<h2 id="描述">描述</h2> + +<p><span>严格不等式运算符检查其对象是否不相等。它是严格相等运算符的否定,因此下面两行总是会给出相同的结果:</span></p> + +<pre class="brush: js notranslate">x !== y + +!(x === y)</pre> + +<p><span>有关比较算法的详细信息,请参阅严格相等运算符的页面。</span></p> + +<p><span>与严格相等运算符一样,严格不等运算符始终认为不同类型的对象是不同的</span>:</p> + +<pre class="brush: js notranslate">3 !== "3"; // true</pre> + +<h2 id="示例">示例</h2> + +<h3 id="比较相同类型的对象">比较相同类型的对象</h3> + +<pre class="brush: js notranslate">console.log("hello" !== "hello"); // false +console.log("hello" !== "hola"); // true + +console.log(3 !== 3); // false +console.log(3 !== 4); // true + +console.log(true !== true); // false +console.log(true !== false); // true + +console.log(null !== null); // false</pre> + +<h3 id="比较不同类型的对象">比较不同类型的对象</h3> + +<pre class="brush: js notranslate">console.log("3" !== 3); // true + +console.log(true !== 1); // true + +console.log(null !== undefined); // true</pre> + +<h3 id="比较Object对象">比较Object对象</h3> + +<pre class="brush: js notranslate">const object1 = { + name: "hello" +} + +const object2 = { + name: "hello" +} + +console.log(object1 !== object2); // true +console.log(object1 !== object1); // false</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + + + +<p>{{Compat("javascript.operators.strict_inequality")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Equality">Equality operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Inequality">Inequality operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">Strict equality operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/subtraction/index.html b/files/zh-cn/web/javascript/reference/operators/subtraction/index.html new file mode 100644 index 0000000000..6bb33366e8 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/subtraction/index.html @@ -0,0 +1,67 @@ +--- +title: Subtraction (-) +slug: Web/JavaScript/Reference/Operators/Subtraction +translation_of: Web/JavaScript/Reference/Operators/Subtraction +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The subtraction operator (<code>-</code>) subtracts the two operands, producing their difference.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-subtraction.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>x</var> - <var>y</var> +</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Subtraction_with_numbers">Subtraction with numbers</h3> + +<pre class="brush: js notranslate">5 - 3 // 2 +3 - 5 // -2</pre> + +<h3 id="Subtraction_with_non-numbers">Subtraction with non-numbers</h3> + +<pre class="brush: js notranslate">'foo' - 3 // NaN</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-subtraction-operator-minus', 'Subtraction operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.subtraction")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html new file mode 100644 index 0000000000..8286c2010b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html @@ -0,0 +1,59 @@ +--- +title: Subtraction assignment (-=) +slug: Web/JavaScript/Reference/Operators/Subtraction_assignment +translation_of: Web/JavaScript/Reference/Operators/Subtraction_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The subtraction assignment operator (<code>-=</code>) subtracts the value of the right operand from a variable and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-subtraction-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x -= y +<strong>Meaning:</strong> x = x - y</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_subtraction_assignment">Using subtraction assignment</h3> + +<pre class="brush: js notranslate">// Assuming the following variable +// bar = 5 + +bar -= 2 // 3 +bar -= 'foo' // NaN</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.subtraction_assignment")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> +</ul> + +<p> + <audio style="display: none;"></audio> +</p> diff --git a/files/zh-cn/web/javascript/reference/operators/super/index.html b/files/zh-cn/web/javascript/reference/operators/super/index.html new file mode 100644 index 0000000000..6681f759ab --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/super/index.html @@ -0,0 +1,184 @@ +--- +title: super +slug: Web/JavaScript/Reference/Operators/super +tags: + - Classes + - ECMAScript 2015 + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/super +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>super</strong>关键字用于访问和调用一个对象的父对象上的函数。</p> + +<p><code>super.prop</code>和<code>super[expr]</code>表达式在<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">类</a>和<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">对象字面量</a>任何<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">方法定义</a>中都是有效的。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">super([arguments]); +// 调用 父对象/父类 的构造函数 + +super.functionOnParent([arguments]); +// 调用 父对象/父类 上的方法 +</pre> + +<h2 id="描述">描述</h2> + +<p>在构造函数中使用时,<code>super</code>关键字将单独出现,并且必须在使用<code>this</code>关键字之前使用。<code>super</code>关键字也可以用来调用父对象上的函数。</p> + +<h2 id="示例">示例</h2> + +<h3 id="在类中使用super">在类中使用<code>super</code></h3> + +<p>以下代码片段来自于 <a href="https://github.com/GoogleChrome/samples/blob/gh-pages/classes-es6/index.html">classes sample</a>。</p> + +<pre class="brush: js notranslate">class Polygon { + constructor(height, width) { + this.name = 'Rectangle'; + this.height = height; + this.width = width; + } + sayName() { + console.log('Hi, I am a ', this.name + '.'); + } + get area() { + return this.height * this.width; + } + set area(value) { + this._area = value; + } +} + +class Square extends Polygon { + constructor(length) { + this.height; // ReferenceError,super 需要先被调用! + + // 这里,它调用父类的构造函数的, + // 作为Polygon 的 height, width + super(length, length); + + // 注意: 在派生的类中, 在你可以使用'this'之前, 必须先调用super()。 + // 忽略这, 这将导致引用错误。 + this.name = 'Square'; + } +} +</pre> + +<h3 id="调用父类上的静态方法">调用父类上的静态方法</h3> + +<p>你也可以用 super 调用父类的<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static">静态方法</a>。</p> + +<pre class="brush: js notranslate">class Rectangle { + constructor() {} + static logNbSides() { + return 'I have 4 sides'; + } +} + +class Square extends Rectangle { + constructor() {} + static logDescription() { + return super.logNbSides() + ' which are all equal'; + } +} +Square.logDescription(); // 'I have 4 sides which are all equal'</pre> + +<h3 id="删除_super_上的属性将抛出异常">删除 super 上的属性将抛出异常</h3> + +<p>你不能使用 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete">delete 操作符</a> 加 <code>super.prop</code> 或者 <code>super[expr]</code> 去删除父类的属性,这样做会抛出 {{jsxref("ReferenceError")}}。</p> + +<pre class="brush: js notranslate">class Base { + constructor() {} + foo() {} +} +class Derived extends Base { + constructor() {} + delete() { + delete super.foo; // this is bad + } +} + +new Derived().delete(); // ReferenceError: invalid delete involving 'super'.</pre> + +<h3 id="super.prop_不能覆写不可写属性"><code>super.prop</code> 不能覆写不可写属性</h3> + +<p>当使用 {{jsxref("Object.defineProperty")}} 定义一个属性为不可写时,<code>super</code>将不能重写这个属性的值。</p> + +<pre class="brush: js notranslate">class X { + constructor() { + Object.defineProperty(this, 'prop', { + configurable: true, + writable: false, + value: 1 + }); + } +} + +class Y extends X { + constructor() { + super(); + } + foo() { + super.prop = 2; // Cannot overwrite the value. + } +} + +var y = new Y(); +y.foo(); // TypeError: "prop" is read-only +console.log(y.prop); // 1</pre> + +<h3 id="在对象字面量中使用super.prop">在对象字面量中使用<code>super.prop</code></h3> + +<p><code>Super</code>也可以在<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">object initializer / literal</a> 符号中使用。在下面的例子中,两个对象各定义了一个方法。在第二个对象中, 我们使用<code>super</code>调用了第一个对象中的方法。 当然,这需要我们先利用 {{jsxref("Object.setPrototypeOf()")}} 设置<code>obj2</code>的原型为<code>obj1</code>,然后才能够使用<code>super</code>调用 <code>obj1</code>上的<code>method1</code>。</p> + +<pre class="brush: js notranslate">var obj1 = { + method1() { + console.log("method 1"); + } +} + +var obj2 = { + method2() { + super.method1(); + } +} + +Object.setPrototypeOf(obj2, obj1); +obj2.method2(); // logs "method 1" +</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('ES2015', '#sec-super-keyword', 'super')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></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.operators.super")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a></li> + <li><a href="https://medium.com/beginners-guide-to-mobile-web-development/super-and-extends-in-javascript-es6-understanding-the-tough-parts-6120372d3420">Anurag Majumdar - Super & Extends in JavaScript</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/this/index.html b/files/zh-cn/web/javascript/reference/operators/this/index.html new file mode 100644 index 0000000000..a3378079ac --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/this/index.html @@ -0,0 +1,498 @@ +--- +title: this +slug: Web/JavaScript/Reference/Operators/this +tags: + - JavaScript + - Operator + - Primary Expressions + - Reference + - this + - 参考 +translation_of: Web/JavaScript/Reference/Operators/this +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>与其他语言相比,<strong>函数的 <code>this</code> 关键字</strong>在 JavaScript 中的表现略有不同,此外,在<a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>和非严格模式之间也会有一些差别。</p> + +<p>在绝大多数情况下,函数的调用方式决定了 <code>this</code> 的值(运行时绑定)。<code>this</code> 不能在执行期间被赋值,并且在每次函数被调用时 <code>this</code> 的值也可能会不同。ES5 引入了 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bind</a> 方法来设置函数的 <code>this</code> 值,而不用考虑函数如何被调用的。ES2015 引入了<a href="https://wiki.developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a>,箭头函数不提供自身的 this 绑定(<code>this</code> 的值将保持为闭合词法上下文的值)。</p> + +<p>{{EmbedInteractiveExample("pages/js/expressions-this.html")}}</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">this</pre> + +<h3 id="值">值</h3> + +<p>当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。</p> + +<h2 id="描述">描述</h2> + +<h3 id="全局上下文">全局上下文</h3> + +<p>无论是否在严格模式下,在全局执行环境中(在任何函数体外部)<code>this</code> 都指向全局对象。</p> + +<pre class="brush:js notranslate">// 在浏览器中, window 对象同时也是全局对象: +console.log(this === window); // true + +a = 37; +console.log(window.a); // 37 + +this.b = "MDN"; +console.log(window.b) // "MDN" +console.log(b) // "MDN"</pre> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> 你可以使用 {{jsxref("globalThis")}} 获取全局对象,无论你的代码是否在当前上下文运行。</p> +</div> + +<h3 id="函数上下文">函数上下文</h3> + +<p>在函数内部,<code>this</code>的值取决于函数被调用的方式。</p> + +<p>因为下面的代码不在严格模式下,且 <code>this</code> 的值不是由该调用设置的,所以 <code>this</code> 的值默认指向全局对象,浏览器中就是 {{domxref("Window", "window")}}。</p> + +<pre class="brush:js notranslate">function f1(){ + return this; +} +//在浏览器中: +f1() === window; //在浏览器中,全局对象是window + +//在Node中: +f1() === globalThis; +</pre> + +<p>然而,在严格模式下,如果进入执行环境时没有设置 <code>this</code> 的值,<code>this</code> 会保持为 <code>undefined</code>,如下:</p> + +<pre class="brush:js notranslate">function f2(){ + "use strict"; // 这里是严格模式 + return this; +} + +f2() === undefined; // true +</pre> + +<div class="note">在第二个例子中,<code>this</code> 应是 <a href="/zh-CN/docs/Glossary/undefined">undefined</a>,因为 <code>f2</code> 是被直接调用的,而不是作为对象的属性或方法调用的(如 <code>window.f2()</code>)。有一些浏览器最初在支持<a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>时没有正确实现这个功能,于是它们错误地返回了<code>window</code>对象。</div> + +<p>如果要想把 <code>this</code> 的值从一个环境传到另一个,就要用 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a></code> 或者<code><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a></code> 方法,如下方的示例所示。</p> + +<h3 id="类上下文">类上下文</h3> + +<p><code>this</code> 在 <a href="/zh-CN/docs/Web/JavaScript/Reference/Classes">类</a> 中的表现与在函数中类似,因为类本质上也是函数,但也有一些区别和注意事项。</p> + +<p>在类的构造函数中,<code>this</code> 是一个常规对象。类中所有非静态的方法都会被添加到 <code>this</code> 的原型中:</p> + +<pre class="notranslate">class Example { + constructor() { + const proto = Object.getPrototypeOf(this); + console.log(Object.getOwnPropertyNames(proto)); + } + first(){} + second(){} + static third(){} +} + +new Example(); // ['constructor', 'first', 'second']</pre> + +<div class="blockIndicator note"> +<p><strong>注意:</strong>静态方法不是 this 的属性,它们只是类自身的属性。</p> +</div> + +<h3 id="派生类">派生类</h3> + +<p>不像基类的构造函数,派生类的构造函数没有初始的 <code>this</code> 绑定。在构造函数中调用 {{jsxref("Operators/super", "super()")}} 会生成一个 <code>this</code> 绑定,并相当于执行如下代码,Base为基类:</p> + +<pre class="notranslate">this = new Base();</pre> + +<div class="blockIndicator warning"> +<p><strong>警告:</strong>在调用 <code>super()</code> 之前引用 <code>this</code> 会抛出错误。</p> +</div> + +<p>派生类不能在调用 <code>super()</code> 之前返回,除非其构造函数返回的是一个对象,或者根本没有构造函数。</p> + +<pre class="notranslate">class Base {} +class Good extends Base {} +class AlsoGood extends Base { + constructor() { + return {a: 5}; + } +} +class Bad extends Base { + constructor() {} +} + +new Good(); +new AlsoGood(); +new Bad(); // ReferenceError</pre> + +<h2 id="示例">示例</h2> + +<h3 id="函数上下文中的_this">函数上下文中的 this</h3> + +<pre dir="rtl">// An object can be passed as the first argument to call or apply and this will be bound to it. +var obj = {a: 'Custom'}; + +// We declare a variable and the variable is assigned to the global window as its property. +var a = 'Global'; + +function whatsThis() { + return this.a; // The value of this is dependent on how the function is called +} + +whatsThis(); // 'Global' as this in the function isn't set, so it defaults to the global/window object +whatsThis.call(obj); // 'Custom' as this in the function is set to obj +whatsThis.apply(obj); // 'Custom' as this in the function is set to obj +</pre> + +<h3 id="this_和对象转换">this 和对象转换</h3> + +<pre class="notranslate">function add(c, d) { + return this.a + this.b + c + d; +} + +var o = {a: 1, b: 3}; + +// 第一个参数是用作“this”的对象 +// 其余参数用作函数的参数 +add.call(o, 5, 7); // 16 + +// 第一个参数是用作“this”的对象 +// 第二个参数是一个数组,数组中的两个成员用作函数参数 +add.apply(o, [10, 20]); // 34 +</pre> + +<p>在非严格模式下使用 <code>call</code> 和 <code>apply</code> 时,如果用作 <code>this</code> 的值不是对象,则会被尝试转换为对象。<code>null</code> 和 <code>undefined</code> 被转换为全局对象。原始值如 <code>7</code> 或 <code>'foo'</code> 会使用相应构造函数转换为对象。因此 <code>7</code> 会被转换为 <code>new Number(7)</code> 生成的对象,字符串 <code>'foo'</code> 会转换为 <code>new String('foo')</code> 生成的对象。</p> + +<pre class="notranslate">function bar() { + console.log(Object.prototype.toString.call(this)); +} + +bar.call(7); // [object Number] +bar.call('foo'); // [object String] +bar.call(undefined); // [object global]</pre> + +<h3 id="bind方法"><code>bind</code>方法</h3> + +<p>ECMAScript 5 引入了 {{jsxref("Function.prototype.bind()")}}。调用<code>f.bind(someObject)</code>会创建一个与<code>f</code>具有相同函数体和作用域的函数,但是在这个新函数中,<code>this</code>将永久地被绑定到了<code>bind</code>的第一个参数,无论这个函数是如何被调用的。</p> + +<pre class="brush:js notranslate">function f(){ + return this.a; +} + +var g = f.bind({a:"azerty"}); +console.log(g()); // azerty + +var h = g.bind({a:'yoo'}); // bind只生效一次! +console.log(h()); // azerty + +var o = {a:37, f:f, g:g, h:h}; +console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty +</pre> + +<h3 id="箭头函数">箭头函数</h3> + +<p>在<a href="/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions">箭头函数</a>中,<code>this</code>与封闭词法环境的<code>this</code>保持一致。在全局代码中,它将被设置为全局对象:</p> + +<pre class="brush: js notranslate">var globalObject = this; +var foo = (() => this); +console.log(foo() === globalObject); // true</pre> + +<div class="note"> +<p>注意:如果将<code>this</code>传递给<code>call</code>、<code>bind</code>、或者<code>apply</code>来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(<code>thisArg</code>)应该设置为<code>null</code>。</p> +</div> + +<pre class="brush: js notranslate">// 接着上面的代码 +// 作为对象的一个方法调用 +var obj = {foo: foo}; +console.log(obj.foo() === globalObject); // true + +// 尝试使用call来设定this +console.log(foo.call(obj) === globalObject); // true + +// 尝试使用bind来设定this +foo = foo.bind(obj); +console.log(foo() === globalObject); // true</pre> + +<p>无论如何,<code>foo</code> 的 <code>this</code> 被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的<code>this</code>被设置为封闭的词法环境的。</p> + +<pre class="brush: js notranslate">// 创建一个含有bar方法的obj对象, +// bar返回一个函数, +// 这个函数返回this, +// 这个返回的函数是以箭头函数创建的, +// 所以它的this被永久绑定到了它外层函数的this。 +// bar的值可以在调用中设置,这反过来又设置了返回函数的值。 +var obj = { + bar: function() { + var x = (() => this); + return x; + } +}; + +// 作为obj对象的一个方法来调用bar,把它的this绑定到obj。 +// 将返回的函数的引用赋值给fn。 +var fn = obj.bar(); + +// 直接调用fn而不设置this, +// 通常(即不使用箭头函数的情况)默认为全局对象 +// 若在严格模式则为undefined +console.log(fn() === obj); // true + +// 但是注意,如果你只是引用obj的方法, +// 而没有调用它 +var fn2 = obj.bar; +// 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。 +console.log(fn2()() == window); // true</pre> + +<p>在上面的例子中,一个赋值给了 <code>obj.bar</code>的函数(称为匿名函数 A),返回了另一个箭头函数(称为匿名函数 B)。因此,在 <code>A</code> 调用时,函数B的<code>this</code>被永久设置为obj.bar(函数A)的<code>this</code>。当返回的函数(函数B)被调用时,它<code>this</code>始终是最初设置的。在上面的代码示例中,函数B的<code>this</code>被设置为函数A的<code>this</code>,即obj,所以即使被调用的方式通常将其设置为 <code>undefined</code> 或全局对象(或者如前面示例中的其他全局执行环境中的方法),它的 <code>this</code> 也仍然是 <code>obj</code> 。</p> + +<h3 id="作为对象的方法">作为对象的方法</h3> + +<p>当函数作为对象里的方法被调用时,<code>this</code> 被设置为调用该函数的对象。</p> + +<p>下面的例子中,当 <code>o.f()</code> 被调用时,函数内的 <code>this</code> 将绑定到 <code>o</code> 对象。</p> + +<pre class="brush:js notranslate">var o = { + prop: 37, + f: function() { + return this.prop; + } +}; + +console.log(o.f()); // 37 +</pre> + +<p>请注意,这样的行为完全不会受函数定义方式或位置的影响。在前面的例子中,我们在定义对象<code>o</code>的同时,将其中的函数定义为成员 <code>f</code> 。但是,我们也可以先定义函数,然后再将其附属到<code>o.f</code>。这样做的结果是一样的:</p> + +<pre class="brush:js notranslate">var o = {prop: 37}; + +function independent() { + return this.prop; +} + +o.f = independent; + +console.log(o.f()); // 37 +</pre> + +<p>这表明函数是从 <code>o</code> 的 <code>f</code> 成员调用的才是重点。</p> + +<p>同样,<code>this</code> 的绑定只受最接近的成员引用的影响。在下面的这个例子中,我们把一个方法<code>g</code>当作对象<code>o.b</code>的函数调用。在这次执行期间,函数中的<code>this</code>将指向<code>o.b</code>。事实证明,这与他是对象 <code>o</code> 的成员没有多大关系,最近的引用才是最重要的。</p> + +<pre class="brush: js notranslate"><code>o.b = {g: independent, prop: 42}; +console.log(o.b.g()); // 42</code></pre> + +<h4 id="原型链中的_this">原型链中的 <code><strong>this</strong></code></h4> + +<p>对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 <code>this</code> 指向的是调用这个方法的对象,就像该方法就在这个对象上一样。</p> + +<pre class="brush:js notranslate">var o = { + f: function() { + return this.a + this.b; + } +}; +var p = Object.create(o); +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +</pre> + +<p>在这个例子中,对象 <code>p</code> 没有属于它自己的 <code>f</code> 属性,它的 <code>f</code> 属性继承自它的原型。虽然最终是在 <code>o</code> 中找到 <code>f</code> 属性的,这并没有关系;查找过程首先从 <code>p.f</code> 的引用开始,所以函数中的 <code>this</code> 指向<code>p</code>。也就是说,因为<code>f</code>是作为<code>p</code>的方法调用的,所以它的<code>this</code>指向了<code>p</code>。这是 JavaScript 的原型继承中的一个有趣的特性。</p> + +<h4 id="getter_与_setter_中的_this">getter 与 setter 中的 <code>this</code></h4> + +<p>再次,相同的概念也适用于当函数在一个 <code>getter</code> 或者 <code>setter</code> 中被调用。用作 <code>getter</code> 或 <code>setter</code> 的函数都会把 <code>this</code> 绑定到设置或获取属性的对象。</p> + +<pre class="brush: js notranslate">function sum() { + return this.a + this.b + this.c; +} + +var o = { + a: 1, + b: 2, + c: 3, + get average() { + return (this.a + this.b + this.c) / 3; + } +}; + +Object.defineProperty(o, 'sum', { + get: sum, enumerable: true, configurable: true}); + +console.log(o.average, o.sum); // logs 2, 6 +</pre> + +<h3 id="作为构造函数">作为构造函数</h3> + +<p>当一个函数用作构造函数时(使用<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/new">new</a>关键字),它的<code>this</code>被绑定到正在构造的新对象。</p> + +<div class="note"> +<p><span style="line-height: 22.007999420166px;">虽然构造函数返回的默认值是 <code>this</code> 所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 <code>this</code> 对象)。</span></p> +</div> + +<pre class="brush: js notranslate">/* + * 构造函数这样工作: + * + * function MyConstructor(){ + * // 函数实体写在这里 + * // 根据需要在this上创建属性,然后赋值给它们,比如: + * this.fum = "nom"; + * // 等等... + * + * // 如果函数具有返回对象的return语句, + * // 则该对象将是 new 表达式的结果。 + * // 否则,表达式的结果是当前绑定到 this 的对象。 + * //(即通常看到的常见情况)。 + * } + */ + +function C(){ + this.a = 37; +} + +var o = new C(); +console.log(o.a); // logs 37 + + +function C2(){ + this.a = 37; + return {a:38}; +} + +o = new C2(); +console.log(o.a); // logs 38 +</pre> + +<p>在刚刚的例子中(<code>C2</code>),因为在调用构造函数的过程中,手动的设置了返回对象,与<code>this</code>绑定的默认对象被丢弃了。(这基本上使得语句 “<code>this.a = 37;</code>”成了“僵尸”代码,实际上并不是真正的“僵尸”,这条语句执行了,但是对于外部没有任何影响,因此完全可以忽略它)。</p> + +<h3 id="作为一个DOM事件处理函数">作为一个DOM事件处理函数</h3> + +<p>当函数被用作事件处理函数时,它的 <code>this</code> 指向触发事件的元素(一些浏览器在使用非 <code>addEventListener</code> 的函数动态地添加监听函数时不遵守这个约定)。</p> + +<pre class="brush:js notranslate">// 被调用时,将关联的元素变成蓝色 +function bluify(e){ + console.log(this === e.currentTarget); // 总是 true + + // 当 currentTarget 和 target 是同一个对象时为 true + console.log(this === e.target); + this.style.backgroundColor = '#A5D9F3'; +} + +// 获取文档中的所有元素的列表 +var elements = document.getElementsByTagName('*'); + +// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色 +for(var i=0 ; i<elements.length ; i++){ + elements[i].addEventListener('click', bluify, false); +}</pre> + +<h3 id="作为一个内联事件处理函数">作为一个内联事件处理函数</h3> + +<p>当代码被内联 <a href="/zh-CN/docs/Web/Guide/Events/Event_handlers">on-event 处理函数</a> 调用时,它的<code>this</code>指向监听器所在的DOM元素:</p> + +<pre class="brush: html notranslate"><button onclick="alert(this.tagName.toLowerCase());"> + Show this +</button> +</pre> + +<p>上面的 alert 会显示 <code>button</code>。注意只有外层代码中的 <code>this</code> 是这样设置的:</p> + +<pre class="brush: html notranslate"><button onclick="alert((function(){return this})());"> + Show inner this +</button> +</pre> + +<p>在这种情况下,没有设置内部函数的 <code>this</code>,所以它指向 global/window 对象(即非严格模式下调用的函数未设置 <code>this</code> 时指向的默认对象)。</p> + +<h3 id="类中的this">类中的this</h3> + +<p>和其他普通函数一样,方法中的 <code>this</code> 值取决于它们如何被调用。有时,改写这个行为,让类中的 <code>this</code> 值总是指向这个类实例会很有用。为了做到这一点,可在构造函数中绑定类方法:</p> + +<pre class="notranslate">class Car { + constructor() { + // Bind sayBye but not sayHi to show the difference + this.sayBye = this.sayBye.bind(this); + } + sayHi() { + console.log(`Hello from ${this.name}`); + } + sayBye() { + console.log(`Bye from ${this.name}`); + } + get name() { + return 'Ferrari'; + } +} + +class Bird { + get name() { + return 'Tweety'; + } +} + +const car = new Car(); +const bird = new Bird(); + +// The value of 'this' in methods depends on their caller +car.sayHi(); // Hello from Ferrari +bird.sayHi = car.sayHi; +bird.sayHi(); // Hello from Tweety + +// For bound methods, 'this' doesn't depend on the caller +bird.sayBye = car.sayBye; +bird.sayBye(); // Bye from Ferrari</pre> + +<div class="blockIndicator note"> +<p><strong>注意:</strong>类内部总是严格模式。调用一个 <code>this</code> 值为 undefined 的方法会抛出错误。</p> +</div> + +<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-this-keyword', 'The this keyword')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-this-keyword', 'The this keyword')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES3')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.1.1', 'The this keyword')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.0.</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.operators.this")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a></li> + <li><a href="http://rainsoft.io/gentle-explanation-of-this-in-javascript/">Gentle explanation of 'this' keyword in JavaScript</a></li> + <li>Getting the global context: {{jsxref("globalThis")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/typeof/index.html b/files/zh-cn/web/javascript/reference/operators/typeof/index.html new file mode 100644 index 0000000000..9ecc801903 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/typeof/index.html @@ -0,0 +1,286 @@ +--- +title: typeof +slug: Web/JavaScript/Reference/Operators/typeof +tags: + - JavaScript + - Operator + - Unary +translation_of: Web/JavaScript/Reference/Operators/typeof +--- +<p>{{jsSidebar("Operators")}}</p> + +<p><strong><code>typeof</code> </strong>操作符返回一个字符串,表示未经计算的操作数的类型。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-typeof.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<p><code>typeof</code> 运算符后接操作数:</p> + +<pre class="syntaxbox notranslate">typeof <em>operand +typeof(operand)</em> +</pre> + +<h3 id="参数" style="line-height: 24px; font-size: 1.71428571428571rem;">参数</h3> + +<p><strong><code>operand</code></strong></p> + +<dl> + <dd>一个表示对象或{{Glossary("Primitive", "原始值")}}的表达式,其类型将被返回。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>下表总结了 <code>typeof</code> 可能的返回值。有关类型和原始值的更多信息,可查看 <a href="/zh-CN/docs/Web/JavaScript/Data_structures">JavaScript 数据结构</a> 页面。</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">类型</th> + <th scope="col">结果</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{glossary("Undefined")}}</td> + <td><code>"undefined"</code></td> + </tr> + <tr> + <td>{{glossary("Null")}}</td> + <td><code>"object"</code> (见{{anch("null", "下文")}})</td> + </tr> + <tr> + <td>{{glossary("Boolean")}}</td> + <td><code>"boolean"</code></td> + </tr> + <tr> + <td>{{glossary("Number")}}</td> + <td><code>"number"</code></td> + </tr> + <tr> + <td>{{glossary("BigInt")}}(ECMAScript 2020 新增)</td> + <td><code>"bigint"</code></td> + </tr> + <tr> + <td>{{glossary("String")}}</td> + <td><code>"string"</code></td> + </tr> + <tr> + <td>{{glossary("Symbol")}} (ECMAScript 2015 新增)</td> + <td><code>"symbol"</code></td> + </tr> + <tr> + <td>宿主对象(由 JS 环境提供)</td> + <td><em>取决于具体实现</em></td> + </tr> + <tr> + <td>{{glossary("Function")}} 对象 (按照 ECMA-262 规范实现 [[Call]])</td> + <td><code>"function"</code></td> + </tr> + <tr> + <td>其他任何对象</td> + <td><code>"object"</code></td> + </tr> + </tbody> +</table> + +<h2 id="示例">示例</h2> + +<pre class="brush: js notranslate">// 数值 +typeof 37 === 'number'; +typeof 3.14 === 'number'; +typeof(42) === 'number'; +typeof Math.LN2 === 'number'; +typeof Infinity === 'number'; +typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写 +typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值 + +typeof 42n === 'bigint'; + + +// 字符串 +typeof '' === 'string'; +typeof 'bla' === 'string'; +typeof `template literal` === 'string'; +typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串 +typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串 +typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全 + + +// 布尔值 +typeof true === 'boolean'; +typeof false === 'boolean'; +typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换 +typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean() + + +// Symbols +typeof Symbol() === 'symbol'; +typeof Symbol('foo') === 'symbol'; +typeof Symbol.iterator === 'symbol'; + + +// Undefined +typeof undefined === 'undefined'; +typeof declaredButUndefinedVariable === 'undefined'; +typeof undeclaredVariable === 'undefined'; + + +// 对象 +typeof {a: 1} === 'object'; + +// 使用 Array.isArray 或者 Object.prototype.toString.call +// 区分数组和普通对象 +typeof [1, 2, 4] === 'object'; + +typeof new Date() === 'object'; +typeof /regex/ === 'object'; // 历史结果请参阅正则表达式部分 + + +// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。 +typeof new Boolean(true) === 'object'; +typeof new Number(1) === 'object'; +typeof new String('abc') === 'object'; + +// 函数 +typeof function() {} === 'function'; +typeof class C {} === 'function' +typeof Math.sin === 'function'; +</pre> + +<h3 id="typeof_null"><code>typeof null</code></h3> + +<pre class="brush: js notranslate"><code>// JavaScript 诞生以来便如此 +typeof null === 'object';</code></pre> + +<p>在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 <code>null</code> 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,<code>typeof null</code> 也因此返回 <code>"object"</code>。(<a href="http://www.2ality.com/2013/10/typeof-null.html">参考来源</a>)</p> + +<p>曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但<a href="http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null">被拒绝了</a>。该提案会导致 <code>typeof null === 'null'</code>。</p> + +<h3 id="使用_new_操作符">使用 <code>new</code> 操作符</h3> + +<pre class="brush: js notranslate">// 除 Function 外的所有构造函数的类型都是 'object' +var str = new String('String'); +var num = new Number(100); + +typeof str; // 返回 'object' +typeof num; // 返回 'object' + +var func = new Function(); + +typeof func; // 返回 'function'</pre> + +<h3 id="语法中的括号">语法中的括号</h3> + +<pre class="brush: js notranslate">// 括号有无将决定表达式的类型。 +var iData = 99; + +typeof iData + ' Wisen'; // 'number Wisen' +typeof (iData + ' Wisen'); // 'string'</pre> + +<h3 id="正则表达式">正则表达式</h3> + +<p>对正则表达式字面量的类型判断在某些浏览器中不符合标准:</p> + +<pre class="brush: js notranslate">typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1 +typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1 +</pre> + +<h3 id="错误">错误</h3> + +<p>在 ECMAScript 2015 之前,<code>typeof</code> 总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,<code>typeof</code> 也能返回 <code>'undefined'</code>。使用 <code>typeof</code> 永远不会抛出错误。</p> + +<p>但在加入了块级作用域的 <a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/let">let</a> 和 <a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/const">const</a> 之后,在其被声明之前对块中的 <code>let</code> 和 <code>const</code> 变量使用 <code>typeof</code> 会抛出一个 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError">ReferenceError</a>。块作用域变量在块的头部处于“<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let">暂存死区</a>”,直至其被初始化,在这期间,访问变量将会引发错误。</p> + +<pre class="brush: js notranslate">typeof undeclaredVariable === 'undefined'; + +typeof newLetVariable; // ReferenceError +typeof newConstVariable; // ReferenceError +typeof newClass; // ReferenceError + +let newLetVariable; +const newConstVariable = 'hello'; +class newClass{};</pre> + +<h3 id="例外">例外</h3> + +<p>当前所有的浏览器都暴露了一个类型为 <code>undefined</code> 的非标准宿主对象 {{domxref("document.all")}}。</p> + +<pre class="brush: js notranslate">typeof document.all === 'undefined'; +</pre> + +<p>尽管规范允许为非标准的外来对象自定义类型标签,但它要求这些类型标签与已有的不同。<code>document.all</code> 的类型标签为 <code>'undefined'</code> 的例子在 Web 领域中被归类为对原 ECMA JavaScript 标准的“故意侵犯”。</p> + +<h3 id="Real-world_usage">Real-world usage</h3> + +<p><code>typeof</code> is very useful, but it's not as versatile as might be required. For example, <code>typeof([])</code> , is <code>'object'</code>, as well as <code>typeof(new Date())</code>, <code>typeof(/abc/)</code>, etc.</p> + +<p>For greater specificity in checking types, a <code>typeof</code> wrapper for usage in production-level code would be as follows (provided <code>obj</code> exists):</p> + +<pre class="brush: js notranslate"> function type(obj, fullClass) { + + // get toPrototypeString() of obj (handles all types) + // Early JS environments return '[object Object]' for null, so it's best to directly check for it. + if (fullClass) { + return (obj === null) ? '[object Null]' : Object.prototype.toString.call(obj); + } + if (obj == null) { return (obj + '').toLowerCase(); } // implicit toString() conversion + + var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase(); + if (deepType === 'generatorfunction') { return 'function' } + + // Prevent overspecificity (for example, [object HTMLDivElement], etc). + // Account for functionish Regexp (Android <=2.3), functionish <object> element (Chrome <=57, Firefox <=52), etc. + // String.prototype.match is universally supported. + + return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType : + (typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj; + }</pre> + +<p>For checking non-existent variables that would otherwise throw a {{JSxRef("ReferenceError")}}, use <code>typeof nonExistentVar === 'undefined'</code>.</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-typeof-operator', 'The typeof Operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + +<div id="compat-desktop"> +<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.operators.typeof")}}</p> + +<h2 id="IE_特别提示">IE 特别提示</h2> + +<p>在 IE 6, 7 和 8 上,很多宿主对象是对象而不是函数。例如:</p> + +<pre class="brush: js notranslate">typeof alert === 'object'</pre> +</div> + +<div class="brush:js language-js line-number" style=""></div> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof">instanceof</a></code></li> + <li><a href="http://es-discourse.com/t/why-typeof-is-no-longer-safe/15">Why typeof is no longer "safe"</a></li> + <li><a href="https://github.com/tc39/ecma262/issues/668">document.all willful violation of the standard</a></li> + <li><a href="https://2ality.com/2013/10/typeof-null.html">The history of “typeof null”</a></li> +</ul> + +<div id="gtx-trans" style="position: absolute; left: 101px; top: 2989.43px;"> +<div class="gtx-trans-icon"></div> +</div> diff --git a/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html b/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html new file mode 100644 index 0000000000..2170b92c53 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unary_negation/index.html @@ -0,0 +1,73 @@ +--- +title: Unary negation (-) +slug: Web/JavaScript/Reference/Operators/Unary_negation +translation_of: Web/JavaScript/Reference/Operators/Unary_negation +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The unary negation operator (<code>-</code>) precedes its operand and negates it.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-unary-negation.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> -<var>x</var> +</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Negating_numbers">Negating numbers</h3> + +<pre class="brush: js notranslate">const x = 3; +const y = -x; + +// y = -3 +// x = 3 +</pre> + +<h3 id="Negating_non-numbers">Negating non-numbers</h3> + +<p>The unary negation operator can convert a non-number into a number.</p> + +<pre class="brush: js notranslate">const x = "4"; +const y = -x; + +// y = -4 +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-unary-minus-operator', 'Unary negation operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.unary_negation")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html b/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html new file mode 100644 index 0000000000..9f3b818df9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unary_plus/index.html @@ -0,0 +1,75 @@ +--- +title: Unary plus (+) +slug: Web/JavaScript/Reference/Operators/Unary_plus +translation_of: Web/JavaScript/Reference/Operators/Unary_plus +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The unary plus operator (<code>+</code>) precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-unary-plus.html", "taller")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> +<var>x</var> +</pre> + +<h2 id="Description">Description</h2> + +<p>Although unary negation (<code>-</code>) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It can convert string representations of integers and floats, as well as the non-string values <code>true</code>, <code>false</code>, and <code>null</code>. Integers in both decimal and hexadecimal (<code>0x</code>-prefixed) formats are supported. Negative numbers are supported (though not for hex). Using the operator on BigInt values throws a TypeError. If it cannot parse a particular value, it will evaluate to {{jsxref("NaN")}}.</p> + +<h2 id="Examples">Examples</h2> + +<h3 id="Usage_with_numbers">Usage with numbers</h3> + +<pre class="brush: js notranslate">const x = 1; +const y = -1; + +console.log(+x); +// 1 +console.log(+y); +// -1</pre> + +<h3 id="Usage_with_non-numbers">Usage with non-numbers</h3> + +<pre class="brush: js notranslate">+true // 1 ++false // 0 ++null // 0 ++function(val){ return val } // NaN ++1n // throws TypeError: Cannot convert BigInt value to number +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-unary-plus-operator', 'Unary plus operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.unary_plus")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html new file mode 100644 index 0000000000..f40a28e8b0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html @@ -0,0 +1,71 @@ +--- +title: Unsigned right shift (>>>) +slug: Web/JavaScript/Reference/Operators/Unsigned_right_shift +translation_of: Web/JavaScript/Reference/Operators/Unsigned_right_shift +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The <strong>unsigned right shift operator (<code>>>></code>)</strong> (zero-fill right shift) shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes <code>0</code>, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> >>> <var>b</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes <code>0</code>, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.</p> + +<p>For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, <code>9 >>> 2</code> yields 2, the same as <code>9 >> 2</code>:</p> + +<pre class="brush: js notranslate">. 9 (base 10): 00000000000000000000000000001001 (base 2) + -------------------------------- +9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10) +</pre> + +<p>However, this is not the case for negative numbers. For example, <code>-9 >>> 2</code> yields 1073741821, which is different than <code>-9 >> 2</code> (which yields <code>-3</code>):</p> + +<pre class="brush: js notranslate">. -9 (base 10): 11111111111111111111111111110111 (base 2) + -------------------------------- +-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10) +</pre> + +<h2 id="例子">例子</h2> + +<h3 id="Using_unsigned_right_shift">Using unsigned right shift</h3> + +<pre class="brush: js notranslate"> 9 >>> 2; // 2 +-9 >>> 2; // 1073741821 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.unsigned_right_shift")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment">Unsigned right shift assignment operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html new file mode 100644 index 0000000000..76379358c0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html @@ -0,0 +1,55 @@ +--- +title: Unsigned right shift assignment (>>>=) +slug: Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment +translation_of: Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The unsigned right shift assignment operator (<em><code>>>>=</code></em>) moves the specified amount of bits to the right and assigns the result to the variable.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift-assignment.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> x >>>= y +<strong>Meaning:</strong> x = x >>> y</pre> + +<h2 id="例子">例子</h2> + +<h3 id="Using_unsigned_right_shift_assignment">Using unsigned right shift assignment</h3> + +<pre class="brush: js notranslate">let a = 5; // (00000000000000000000000000000101) +a >>>= 2; // 1 (00000000000000000000000000000001) + +let b = -5; // (-00000000000000000000000000000101) +b >>>= 2; // 1073741822 (00111111111111111111111111111110)</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.unsigned_right_shift_assignment")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment">Assignment operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift">Unsigned right shift operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/void/index.html b/files/zh-cn/web/javascript/reference/operators/void/index.html new file mode 100644 index 0000000000..b67110459a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/void/index.html @@ -0,0 +1,114 @@ +--- +title: void 运算符 +slug: Web/JavaScript/Reference/Operators/void +tags: + - JavaScript + - Unary +translation_of: Web/JavaScript/Reference/Operators/void +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong><code>void</code> 运算符 </strong>对给定的表达式进行求值,然后返回 {{jsxref("Global_Objects/undefined", "undefined")}}。</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">void <em>expression</em></pre> + +<h2 id="描述">描述</h2> + +<p>这个运算符能向期望一个表达式的值是{{jsxref("Global_Objects/undefined", "undefined")}}的地方插入会产生副作用的表达式。</p> + +<p>void 运算符通常只用于获取 <code>undefined</code>的原始值,一般使用<code>void(0)</code>(等同于<code>void 0</code>)。在上述情况中,也可以使用全局变量{{jsxref("Global_Objects/undefined", "undefined")}} 来代替(假定其仍是默认值)。</p> + +<h2 id="立即调用的函数表达式">立即调用的函数表达式</h2> + +<p>在使用<a href="/zh-CN/docs/Glossary/IIFE">立即执行的函数表达式</a>时,可以利用 <code>void</code> 运算符让 JavaScript 引擎把一个<code>function</code>关键字识别成函数表达式而不是函数声明(语句)。</p> + +<pre class="brush: js">void function iife() { + var bar = function () {}; + var baz = function () {}; + var foo = function () { + bar(); + baz(); + }; + var biz = function () {}; + + foo(); + biz(); +}(); +</pre> + +<h2 id="JavaScript_URIs">JavaScript URIs</h2> + +<p>当用户点击一个以 <code>javascript:</code> URI 时,它会执行URI中的代码,然后用返回的值替换页面内容,除非返回的值是{{jsxref("Global_Objects/undefined", "undefined")}}。<code>void</code>运算符可用于返回{{jsxref("Global_Objects/undefined", "undefined")}}。例如:</p> + +<pre class="brush: html"><a href="javascript:void(0);"> + 这个链接点击之后不会做任何事情,如果去掉 void(), + 点击之后整个页面会被替换成一个字符 0。 +</a> +<p> chrome中即使<a href="javascript:0;">也没变化,firefox中会变成一个字符串0 </p> +<a href="javascript:void(document.body.style.backgroundColor='green');"> + 点击这个链接会让页面背景变成绿色。 +</a> +</pre> + +<p>注意,虽然这么做是可行的,但利用 <code>javascript:</code> 伪协议来执行 JavaScript 代码是不推荐的,推荐的做法是为链接元素绑定事件。</p> + +<h2 id="在箭头函数中避免泄漏">在箭头函数中避免泄漏</h2> + +<p>箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 <code>void</code> 运算符,来确保返回 {{jsxref("Global_Objects/undefined", "undefined")}}(如下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。</p> + +<pre class="brush: js">button.onclick = () => void doSomething();</pre> + +<p>确保了当 <code>doSomething</code> 的返回值从 {{jsxref("Global_Objects/undefined", "undefined")}} 变为 <code>true</code> 的时候,不会改变函数的行为</p> + +<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-void-operator', 'The void Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-void-operator', 'The void Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.4.2', 'The void Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.4.2', 'The void Operator')}}</td> + <td>{{Spec2('ES3')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.4.2', 'The void Operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.1</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + +<div class="hidden"> +<p>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.</p> +</div> + +<p>{{Compat("javascript.operators.void")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/yield/index.html b/files/zh-cn/web/javascript/reference/operators/yield/index.html new file mode 100644 index 0000000000..58e9adfc00 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/yield/index.html @@ -0,0 +1,104 @@ +--- +title: yield +slug: Web/JavaScript/Reference/Operators/yield +tags: + - ECMAScript 2015 + - Generators + - Iterator + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators/yield +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><code>yield</code> 关键字用来暂停和恢复一个生成器函数(({{jsxref("Statements/function*", "function*")}} 或<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">遗留的生成器函数</a>)。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox">[<em>rv</em>] = <strong>yield</strong> [<em>expression</em>];</pre> + +<dl> + <dt><code>expression</code></dt> + <dd>定义通过<a href="/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">迭代器协议</a>从生成器函数返回的值。如果省略,则返回<code>undefined</code>。</dd> + <dt><code>rv</code></dt> + <dd> + <p>返回传递给生成器的<code>next()</code>方法的可选值,以恢复其执行。</p> + </dd> +</dl> + +<h2 id="描述">描述</h2> + +<p><code>yield</code>关键字使生成器函数执行暂停,<code>yield</code>关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的<code>return</code>关键字。</p> + +<p><code>yield</code>关键字实际返回一个<code>IteratorResult</code>对象,它有两个属性,<code>value</code>和<code>done</code>。<code>value</code>属性是对<code>yield</code>表达式求值的结果,而<code>done</code>是<code>false</code>,表示生成器函数尚未完全完成。</p> + +<p>一旦遇到 <code>yield</code> 表达式,生成器的代码将被暂停运行,直到生成器的 <code>next()</code> 方法被调用。每次调用生成器的<code>next()</code>方法时,生成器都会恢复执行,直到达到以下某个值:</p> + +<ul> + <li><code>yield</code>,导致生成器再次暂停并返回生成器的新值。 下一次调用<code>next()</code>时,在<code>yield</code>之后紧接着的语句继续执行。</li> + <li>{{jsxref("Statements/throw", "throw")}}用于从生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,正如通常情况下抛出异常一样。</li> + <li>到达生成器函数的结尾;在这种情况下,生成器的执行结束,并且<code>IteratorResult</code>给调用者返回{{jsxref("undefined")}}并且<code>done</code>为<code>true</code>。</li> + <li>到达{{jsxref("Statements/return", "return")}} 语句。在这种情况下,生成器的执行结束,并将<code>IteratorResult</code>返回给调用者,其值是由<code>return</code>语句指定的,并且<code>done</code> 为<code>true</code>。</li> +</ul> + +<p>如果将参数传递给生成器的<code>next()</code>方法,则该值将成为生成器当前<code>yield</code>操作返回的值。</p> + +<p>在生成器的代码路径中的<code>yield</code>运算符,以及通过将其传递给{{jsxref("Generator.prototype.next()")}}指定新的起始值的能力之间,生成器提供了强大的控制力。</p> + +<h2 id="Examples" name="Examples">示例</h2> + +<p>以下代码是一个生成器函数的声明。</p> + +<pre class="brush: js">function* countAppleSales () { + var saleList = [3, 7, 5]; + for (var i = 0; i < saleList.length; i++) { + yield saleList[i]; + } +}</pre> + +<p>一旦生成器函数已定义,可以通过构造一个迭代器来使用它。</p> + +<pre class="brush: js">var appleStore = countAppleSales(); // Generator { } +console.log(appleStore.next()); // { value: 3, done: false } +console.log(appleStore.next()); // { value: 7, done: false } +console.log(appleStore.next()); // { value: 5, done: false } +console.log(appleStore.next()); // { value: undefined, done: true }</pre> + +<h2 id="Specifications" name="Specifications">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#', 'Yield')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#', 'Yield')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">浏览器兼容性</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.operators.yield")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol">The Iterator protocol</a></li> + <li>{{jsxref("Statements/function*", "function*")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("Operators/yield*", "yield*")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html b/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html new file mode 100644 index 0000000000..c53be56902 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/yield_star_/index.html @@ -0,0 +1,162 @@ +--- +title: yield* +slug: Web/JavaScript/Reference/Operators/yield* +tags: + - ECMAScript 2015 + - Generators + - Iterable + - Iterator + - JavaScript + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/yield* +--- +<div>{{jsSidebar("Operators")}}</div> + +<p> <strong><code>yield*</code> 表达式</strong>用于委托给另一个{{jsxref("Statements/function*", "generator")}} 或可迭代对象。</p> + +<h2 id="Syntax" name="Syntax">语法</h2> + +<pre class="syntaxbox"> yield* [[expression]];</pre> + +<dl> + <dt><code>expression</code></dt> + <dd>返回一个可迭代对象的表达式。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p><code>yield*</code> 表达式迭代操作数,并产生它返回的每个值。</p> + +<p><code>yield*</code> 表达式本身的值是当迭代器关闭时返回的值(即<code>done</code>为<code>true</code>时)。</p> + +<h2 id="Examples" name="Examples">示例</h2> + +<h3 id="委托给其他生成器">委托给其他生成器</h3> + +<p>以下代码中,<code>g1()</code> <code>yield</code> 出去的每个值都会在 <code>g2()</code> 的 <code>next()</code> 方法中返回,就像那些 <code>yield</code> 语句是写在 <code>g2()</code> 里一样。</p> + +<pre class="brush: js">function* g1() { + yield 2; + yield 3; + yield 4; +} + +function* g2() { + yield 1; + yield* g1(); + yield 5; +} + +var iterator = g2(); + +console.log(iterator.next()); // { value: 1, done: false } +console.log(iterator.next()); // { value: 2, done: false } +console.log(iterator.next()); // { value: 3, done: false } +console.log(iterator.next()); // { value: 4, done: false } +console.log(iterator.next()); // { value: 5, done: false } +console.log(iterator.next()); // { value: undefined, done: true } +</pre> + +<h3 id="委托给其他可迭代对象">委托给其他可迭代对象</h3> + +<p>除了生成器对象这一种可迭代对象,<code>yield*</code> 还可以 <code>yield</code> 其它任意的可迭代对象,比如说数组、字符串、<code>arguments</code> 对象等等。</p> + +<pre class="brush: js">function* g3() { + yield* [1, 2]; + yield* "34"; + yield* arguments; +} + +var iterator = g3(5, 6); + +console.log(iterator.next()); // { value: 1, done: false } +console.log(iterator.next()); // { value: 2, done: false } +console.log(iterator.next()); // { value: "3", done: false } +console.log(iterator.next()); // { value: "4", done: false } +console.log(iterator.next()); // { value: 5, done: false } +console.log(iterator.next()); // { value: 6, done: false } +console.log(iterator.next()); // { value: undefined, done: true } +</pre> + +<h3 id="yield*_表达式的值"><code>yield*</code> 表达式的值</h3> + +<p><code>yield*</code> 是一个表达式,不是语句,所以它会有自己的值。</p> + +<pre class="brush: js">function* g4() { + yield* [1, 2, 3]; + return "foo"; +} + +var result; + +function* g5() { + result = yield* g4(); +} + +var iterator = g5(); + +console.log(iterator.next()); // { value: 1, done: false } +console.log(iterator.next()); // { value: 2, done: false } +console.log(iterator.next()); // { value: 3, done: false } +console.log(iterator.next()); // { value: undefined, done: true }, + // 此时 g4() 返回了 { value: "foo", done: true } + +console.log(result); // "foo" +</pre> + +<h2 id="Specifications" name="Specifications">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#', 'Yield')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#', 'Yield')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">浏览器兼容</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.operators.yield_star")}}</p> + +<h2 id="Firefox_特别提示">Firefox 特别提示</h2> + +<ul> + <li>从 Gecko 33 {{geckoRelease(33)}} 开始,<code>yield</code>表达式的解析已被更新以符合ES2015规范({{bug(981599)}}): + + <ul> + <li>现在有行结束符限制。在 <code>yield</code> 和 <code>*</code> 之间不允许有换行符。如下代码会抛出{{jsxref("SyntaxError")}}: + + <pre class="brush: js">function* foo() { + yield + *[]; +}</pre> + </li> + </ul> + </li> +</ul> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> + <li><a href="/zh-CN/docs/Web/JavaScript/Guide/The_Iterator_protocol">迭代器协议</a></li> + <li>{{jsxref("Statements/function*", "function*")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("Operators/yield", "yield")}}</li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/取余/index.html b/files/zh-cn/web/javascript/reference/operators/取余/index.html new file mode 100644 index 0000000000..276296ccd7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/取余/index.html @@ -0,0 +1,81 @@ +--- +title: 取余 (%) +slug: Web/JavaScript/Reference/Operators/取余 +tags: + - JavaScript + - Language feature + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/Remainder +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-remainder.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>Operator:</strong> <var>var1</var> % <var>var2</var> +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="被除数为正数">被除数为正数</h3> + +<pre class="brush: js notranslate"> 12 % 5 // 2 + 1 % -2 // 1 + 1 % 2 // 1 + 2 % 3 // 2 +5.5 % 2 // 1.5 +</pre> + +<h3 id="被除数为负数">被除数为负数</h3> + +<pre class="brush: js notranslate">-12 % 5 // -2 +-1 % 2 // -1 +-4 % 2 // -0</pre> + +<h3 id="被除数为NaN">被除数为NaN</h3> + +<pre class="brush: js notranslate">NaN % 2 // NaN</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Remainder operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.remainder")}}</p> + +<h2 id="See_also" name="See_also">相关链接</h2> + +<ul> +</ul> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/可选链/index.html b/files/zh-cn/web/javascript/reference/operators/可选链/index.html new file mode 100644 index 0000000000..da2f04c775 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/可选链/index.html @@ -0,0 +1,202 @@ +--- +title: 可选链操作符 +slug: Web/JavaScript/Reference/Operators/可选链 +tags: + - '?.' + - JavaScript + - Optional chaining (?.) + - Reference + - 参考 + - 可选链 + - 语言特性 + - 运算符 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +<div>{{JSSidebar("Operators")}}</div> + +<p><strong>可选链</strong>操作符( <strong><code>?.</code></strong> )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。<code>?.</code> 操作符的功能类似于 <code>.</code> 链式操作符,不同之处在于,在引用为空(<a href="https://wiki.developer.mozilla.org/en-US/docs/Glossary/nullish">nullish</a> ) ({{JSxRef("null")}} 或者 {{JSxRef("undefined")}}) 的情况下不会引起错误,该表达式短路返回值是 <code>undefined</code>。与函数调用一起使用时,如果给定的函数不存在,则返回 <code>undefined</code>。</p> + +<p>当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><var>obj</var>?.<var>prop</var> +<var>obj</var>?.[<var>expr</var>] +<var>arr</var>?.[<var>index</var>] +<var>func</var>?.(<var>args</var>) +</pre> + +<h2 id="描述">描述</h2> + +<p>通过连接的对象的引用或函数可能是 <code>undefined</code> 或 <code>null</code> 时,可选链操作符提供了一种方法来简化被连接对象的值访问。</p> + +<p>比如,思考一个存在嵌套结构的对象 <code>obj</code>。不使用可选链的话,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first && obj.first.second;</pre> + +<p>为了避免报错,在访问<code>obj.first.second</code>之前,要保证 <code>obj.first</code> 的值既不是 <code>null</code>,也不是 <code>undefined</code>。如果只是直接访问 <code>obj.first.second</code>,而不对 <code>obj.first</code> 进行校验,则有可能抛出错误。</p> + +<p>有了可选链操作符(<code>?.</code>),在访问 <code>obj.first.second</code> 之前,不再需要明确地校验 <code>obj.first</code> 的状态,再并用短路计算获取最终结果:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first?.second;</pre> + +<p>通过使用 <code>?.</code> 操作符取代 <code>.</code> 操作符,JavaScript 会在尝试访问 <code>obj.first.second</code> 之前,先隐式地检查并确定 <code>obj.first</code> 既不是 <code>null</code> 也不是 <code>undefined</code>。如果<code>obj.first </code>是 <code>null</code> 或者 <code>undefined</code>,表达式将会短路计算直接返回 <code>undefined</code>。</p> + +<p>这等价于以下表达式,但实际上没有创建临时变量:</p> + +<pre class="brush: js notranslate">let temp = obj.first; +let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);</pre> + +<h3 id="可选链与函数调用">可选链与函数调用</h3> + +<p>当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。</p> + +<p>函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回<code>undefined</code>而不是抛出一个异常。</p> + +<pre class="brush: js notranslate">let result = someInterface.customMethod?.();</pre> + +<div class="blockIndicator note"> +<p><strong>注意:</strong> 如果存在一个属性名且不是函数, 使用 <code>?.</code> 仍然会产生一个 {{JSxRef("TypeError")}} 异常 (<code>x.y</code><code> is not a function</code>).</p> +</div> + +<div class="blockIndicator note"> +<p><strong>注意:</strong> 如果 <code>someInterface</code> 自身是 <code>null</code> 或者 <code>undefined</code> ,异常 {{JSxRef("TypeError")}} 仍会被抛出 <code>someInterface is null</code> 如果你希望允许 <code>someInterface</code> 也为 <code>null</code> 或者 <code>undefined</code> ,那么你需要像这样写 <code>someInterface?.customMethod?.()</code></p> +</div> + +<h4 id="处理可选的回调函数或者事件处理器">处理可选的回调函数或者事件处理器</h4> + +<p>如果使用<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">解构赋值</a>来解构的一个对象的回调函数或 fetch 方法,你可能得到不能当做函数直接调用的不存在的值,除非你已经校验了他们的存在性。使用<code>?.</code>的你可以忽略这些额外的校验:</p> + +<pre class="brush: js notranslate">// ES2019的写法 +function doSomething(onContent, onError) { + try { + // ... do something with the data + } + catch (err) { + if (onError) { // 校验onError是否真的存在 + onError(err.message); + } + } +} +</pre> + +<pre class="brush: js notranslate">// 使用可选链进行函数调用 +function doSomething(onContent, onError) { + try { + // ... do something with the data + } + catch (err) { + onError?.(err.message); // 如果onError是undefined也不会有异常 + } +} +</pre> + +<h3 id="可选链和表达式">可选链和表达式</h3> + +<p>当使用<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Property_Accessors#方括号表示法">方括号与属性名</a>的形式来访问属性时,你也可以使用可选链操作符:</p> + +<pre class="brush: js notranslate">let nestedProp = obj?.['prop' + 'Name'];</pre> + +<h3 id="可选链不能用于赋值">可选链不能用于赋值</h3> + +<pre class="notranslate"><code>let object = {}; +object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment</code></pre> + +<h3 id="可选链访问数组元素">可选链访问数组元素</h3> + +<pre class="notranslate">let arrayItem = arr?.[42];</pre> + +<h2 id="例子">例子</h2> + +<h3 id="基本例子">基本例子</h3> + +<p>如下的例子在一个不含 <code>bar</code> 成员的 Map 中查找 <code>bar</code> 成员的 <code>name</code> 属性,因此结果是 <code>undefined</code>。</p> + +<pre class="brush: js notranslate">let myMap = new Map(); +myMap.set("foo", {name: "baz", desc: "inga"}); + +let nameBar = myMap.get("bar")?.name;</pre> + +<h3 id="短路计算">短路计算</h3> + +<p>当在表达式中使用可选链时,如果左操作数是 <code>null</code> 或 <code>undefined</code>,表达式将不会被计算,例如:</p> + +<pre class="brush: js notranslate">let potentiallyNullObj = null; +let x = 0; +let prop = potentiallyNullObj?.[x++]; + +console.log(x); // x 将不会被递增,依旧输出 0 +</pre> + +<h3 id="连用可选链操作符">连用可选链操作符</h3> + +<p>可以连续使用可选链读取多层嵌套结构:</p> + +<pre class="brush: js notranslate">let customer = { + name: "Carl", + details: { + age: 82, + location: "Paradise Falls" // details 的 address 属性未有定义 + } +}; +let customerCity = customer.details?.address?.city; + +// … 可选链也可以和函数调用一起使用 +let duration = vacations.trip?.getTime?.(); +</pre> + +<h3 id="使用空值合并操作符">使用空值合并操作符</h3> + +<p>{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}可以在使用可选链时设置一个默认值:</p> + +<pre class="brush: js notranslate"><code>let customer = { + name: "Carl", + details: { age: 82 } +}; +let customerCity = customer?.city ?? "暗之城"; +console.log(customerCity); // “暗之城”</code></pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-OptionalExpression', 'optional expression')}}</td> + <td>Stage 4</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div> + + +<p>{{Compat("javascript.operators.optional_chaining")}}</p> + +<h3 id="Implementation_Progress">Implementation Progress</h3> + +<p>The following table provides a daily implementation status for this feature because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in <a href="https://github.com/tc39/test262">Test262</a>, the standard test suite of JavaScript, in the nightly build, or the latest release of each browser's JavaScript engine.</p> + +<p>{{EmbedTest262ReportResultsTable("optional-chaining")}}</p> +</div> + +<h2 id="参见">参见</h2> + +<ul> + <li>{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}</li> + <li><a href="https://github.com/tc39/proposals">TC39 提案</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/按位与/index.html b/files/zh-cn/web/javascript/reference/operators/按位与/index.html new file mode 100644 index 0000000000..20eece2691 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/按位与/index.html @@ -0,0 +1,106 @@ +--- +title: 按位与 (&) +slug: Web/JavaScript/Reference/Operators/按位与 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>按位与运算符 (<code>&</code>) 在每个位上返回 <code>1</code> ,这两个操作数对应的位都是 <code>1</code>.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-bitwise-and.html")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><code><var>a</var> & <var>b</var></code> +</pre> + +<h2 id="描述">描述</h2> + +<p>操作数被转换为32位整数,并由一系列位(0和1)表示。 超过32位的数字将丢弃其最高有效位。 例如,以下大于32位的整数将被转换为32位整数:</p> + +<pre class="brush: js notranslate">Before: 11100110111110100000000000000110000000000001 +After: 10100000000000000110000000000001</pre> + +<p>第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。</p> + +<p>将运算符应用于每对位,然后按位构造结果。</p> + +<p>与运算的真值表:</p> + +<table class="standard-table"> + <thead> + <tr> + <th class="header" scope="col">a</th> + <th class="header" scope="col">b</th> + <th class="header" scope="col">a AND b</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>0</td> + <td>1</td> + <td>0</td> + </tr> + <tr> + <td>1</td> + <td>0</td> + <td>0</td> + </tr> + <tr> + <td>1</td> + <td>1</td> + <td>1</td> + </tr> + </tbody> +</table> + +<pre class="brush: js notranslate">. 9 (base 10) = 00000000000000000000000000001001 (base 2) + 14 (base 10) = 00000000000000000000000000001110 (base 2) + -------------------------------- +14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10) +</pre> + +<p>将任何数字<code>x</code>与<code>0</code>进行按位与运算将得出<code>0</code>。</p> + +<h2 id="示例">示例</h2> + +<h3 id="使用按位与">使用按位与</h3> + +<pre class="brush: js notranslate">// 5: 00000000000000000000000000000101 +// 2: 00000000000000000000000000000010 +5 & 2; // 0</pre> + +<h2 id="规范说明">规范说明</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-BitwiseANDExpression', 'Bitwise AND expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.bitwise_and")}}</p> + +<h2 id="参阅">参阅</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise">Bitwise operators in the JS guide</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND_assignment">Bitwise AND assignment operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/相加/index.html b/files/zh-cn/web/javascript/reference/operators/相加/index.html new file mode 100644 index 0000000000..6da432b4e6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/相加/index.html @@ -0,0 +1,79 @@ +--- +title: 相加运算符 (+) +slug: Web/JavaScript/Reference/Operators/相加 +translation_of: Web/JavaScript/Reference/Operators/Addition +--- +<div>{{jsSidebar("相加运算符")}}</div> + +<p>相加运算符 (<code>+</code>) 用于对两个操作数进行相加运算,如果操作数为字符串则该运算符将两个操作数连接成一个字符串。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-addition.html")}}</div> + +<div></div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><strong>表达式:</strong> <var>x</var> + <var>y</var> +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="数字的相加运算">数字的相加运算</h3> + +<pre class="brush: js notranslate">// Number + Number -> addition +1 + 2 // 3 + +// Boolean + Number -> addition +true + 1 // 2 + +// Boolean + Boolean -> addition +false + false // 0 +</pre> + +<h3 id="字符串相加运算">字符串相加运算</h3> + +<pre class="brush: js notranslate">// String + String -> concatenation +'foo' + 'bar' // "foobar" + +// Number + String -> concatenation +5 + 'foo' // "5foo" + +// String + Boolean -> concatenation +'foo' + false // "foofalse"</pre> + +<p>注: '+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-addition-operator-plus', 'Addition operator')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.addition")}}</p> + +<h2 id="参考">参考</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement">Decrement operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/相等/index.html b/files/zh-cn/web/javascript/reference/operators/相等/index.html new file mode 100644 index 0000000000..e100ec1d2d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/相等/index.html @@ -0,0 +1,125 @@ +--- +title: 相等(==) +slug: Web/JavaScript/Reference/Operators/相等 +tags: + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/Equality +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>等于运算符(<code>==</code>)检查其两个操作数是否相等,并返回<code>Boolean</code>结果。与<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">严格相等</a>运算符(<code>===</code>)不同,它会尝试强制类型转换并且比较不同类型的操作数。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-equality.html")}}</div> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate">x == y +</pre> + +<h2 id="描述">描述</h2> + +<p>相等运算符(<code>==</code>和<code>!=</code>)使用<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3">抽象相等比较算法</a>比较两个操作数。可以大致概括如下:</p> + +<ul> + <li>如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回<code>true</code>。</li> + <li>如果一个操作数是<code>null</code>,另一个操作数是<code>undefined</code>,则返回<code>true</code>。</li> + <li>如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型: + <ul> + <li>当数字与字符串进行比较时,会尝试将字符串转换为数字值。</li> + <li>如果操作数之一是<code>Boolean</code>,则将布尔操作数转换为1或0。 + <ul> + <li>如果是<code>true</code>,则转换为<code>1</code>。</li> + <li>如果是 <code>false</code>,则转换为<code>0</code>。</li> + </ul> + </li> + <li>如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的<code>valueOf()</code>和<code>toString()</code>方法将对象转换为原始值。</li> + </ul> + </li> + <li>如果操作数具有相同的类型,则将它们进行如下比较: + <ul> + <li><code>String</code>:<code>true</code>仅当两个操作数具有相同顺序的相同字符时才返回。</li> + <li><code>Number</code>:<code>true</code>仅当两个操作数具有相同的值时才返回。<code>+0</code>并被<code>-0</code>视为相同的值。如果任一操作数为<code>NaN</code>,则返回<code>false</code>。</li> + <li><code>Boolean</code>:<code>true</code>仅当操作数为两个<code>true</code>或两个<code>false</code>时才返回<code>true</code>。</li> + </ul> + </li> +</ul> + +<p>此运算符与<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">严格等于</a>(<code>===</code>)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。</p> + +<h2 id="例子">例子</h2> + +<h3 id="没有类型转换的比较">没有类型转换的比较</h3> + +<pre class="brush: js notranslate">1 == 1; // true +"hello" == "hello"; // true</pre> + +<h3 id="与类型转换比较">与类型转换比较</h3> + +<pre class="brush: js notranslate">"1" == 1; // true +1 == "1"; // true +0 == false; // true +0 == null; // false +0 == undefined; // false +null == undefined; // true + +const number1 = new Number(3); +const number2 = new Number(3); +number1 == 3; // true +number1 == number2; // false</pre> + +<h3 id="对象比较">对象比较</h3> + +<pre class="brush: js notranslate">const object1 = {"key": "value"} +const object2 = {"key": "value"}; + +object1 == object2 // false +object2 == object2 // true</pre> + +<h3 id="比较字符串和String对象">比较字符串和String对象</h3> + +<p>请注意,使用构造的字符串<code>new String()</code>是对象。如果将其中之一与字符串文字进行比较,则该<code>String</code>对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是<code>String</code>对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:</p> + +<pre class="brush: js notranslate">const string1 = "hello"; +const string2 = String("hello"); +const string3 = new String("hello"); +const string4 = new String("hello"); + +console.log(string1 == string2); // true +console.log(string1 == string3); // true +console.log(string2 == string3); // true +console.log(string3 == string4); // false +console.log(string4 == string4); // true</pre> + +<h3 id="比较日期和字符串">比较日期和字符串</h3> + +<pre class="brush: js notranslate">const d = new Date('December 17, 1995 03:24:00'); +const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)" +console.log(d == s); //true</pre> + +<h2 id="技术指标">技术指标</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<p>{{Compat("javascript.operators.equality")}}</p> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Inequality">不等式运算符</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality">严格相等运算符</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Strict_inequality">严格的不等式运算符</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/管道操作符/index.html b/files/zh-cn/web/javascript/reference/operators/管道操作符/index.html new file mode 100644 index 0000000000..06ce40ad0b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/管道操作符/index.html @@ -0,0 +1,75 @@ +--- +title: 管道操作符 +slug: Web/JavaScript/Reference/Operators/管道操作符 +tags: + - Experimental + - JavaScript + - Operator + - 语法糖 + - 链式 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator +--- +<div>{{jsSidebar("Operators")}} {{SeeCompatTable}}</div> + +<p>试验性的管道操作符 <code>|></code> (目前其标准化流程处于 stage 1 阶段)允许以一种易读的方式去对函数链式调用。本质上来说,管道操作符是单参数函数调用的语法糖,它允许你像这样执行一个调用:</p> + +<pre class="brush: js">let url = "%21" |> decodeURI;</pre> + +<p>使用传统语法写的话,等效的代码是这样的:</p> + +<pre class="brush: js">let url = decodeURI("%21"); +</pre> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">expression |> function</pre> + +<h2 id="例子">例子</h2> + +<h3 id="函数链式调用">函数链式调用</h3> + +<p>当链式调用多个函数时,使用管道操作符可以改善代码的可读性。</p> + +<pre class="brush: js">const double = (n) => n * 2; +const increment = (n) => n + 1; + +// 没有用管道操作符 +double(increment(double(5))); // 22 + +// 用上管道操作符之后 +5 |> double |> increment |> double; // 22 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="http://tc39.github.io/proposal-pipeline-operator/">Pipeline operator draft</a></td> + <td>Stage 1</td> + <td>Not part of the ECMAScript specification yet.</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性Edit">浏览器兼容性<a class="button section-edit only-icon" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators$edit#浏览器兼容性" rel="nofollow, noindex"><span>Edit</span></a></h2> + +<div> + + +<p>{{Compat("javascript.operators.pipeline")}}</p> +</div> + +<h2 id="参见">参见</h2> + +<ul> + <li>GitHub 上的 <a href="https://github.com/tc39/proposals">TC39/proposals</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/自减/index.html b/files/zh-cn/web/javascript/reference/operators/自减/index.html new file mode 100644 index 0000000000..f405740df3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/自减/index.html @@ -0,0 +1,85 @@ +--- +title: 自减 (--) +slug: Web/JavaScript/Reference/Operators/自减 +tags: + - JavaScript + - 自减 + - 语法特性 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Decrement +--- +<div>{{jsSidebar("Operators")}}</div> + +<p> 自减运算符(<code>--</code>) 将它的操作数减一,然后返回操作数.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-decrement.html")}}</div> + +<div></div> + + + +<h2 id="语法"><br> + 语法</h2> + +<pre class="syntaxbox notranslate"><strong>操作符:</strong> <var>x</var>-- or --<var>x</var> +</pre> + +<h2 id="语法细节">语法细节</h2> + +<p>如果使用后缀式,即将操作符放在操作数的后面 (如,<code><var>x</var>--</code>),运算会减一,然后返回减一之前的值。</p> + +<p>如果使用前缀式,即将操作符放在操作数的前面 (如,<code>--<var>x</var></code>),运算会减一,然后返回减一之后的值。</p> + +<h2 id="示例">示例</h2> + +<h3 id="后缀式">后缀式</h3> + +<pre class="brush: js notranslate">let x = 3; +y = x--; + +// y = 3 +// x = 2 +</pre> + +<h3 id="前缀式">前缀式</h3> + +<pre class="brush: js notranslate">let a = 2; +b = --a; + +// a = 1 +// b = 1 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-postfix-decrement-operator', '自减运算符')}}</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性"><br> + 浏览器兼容性</h2> + + + +<p>{{Compat("javascript.operators.decrement")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition">Addition operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Subtraction">Subtraction operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division">Division operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication">Multiplication operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">Remainder operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation">Exponentiation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment">Increment operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">Unary negation operator</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus">Unary plus operator</a></li> +</ul> diff --git a/files/zh-cn/web/javascript/reference/operators/逻辑和/index.html b/files/zh-cn/web/javascript/reference/operators/逻辑和/index.html new file mode 100644 index 0000000000..de38317f42 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/逻辑和/index.html @@ -0,0 +1,137 @@ +--- +title: 逻辑与(&&) +slug: Web/JavaScript/Reference/Operators/逻辑和 +translation_of: Web/JavaScript/Reference/Operators/Logical_AND +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>The logical AND (<code>&&</code>) operator (logical conjunction) for a set of operands is true if and only if all of its operands are true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the <code>&&</code> operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-logical-and.html", "shorter")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate"><em>expr1</em> && <em>expr2</em> +</pre> + +<h2 id="Description">Description</h2> + +<p>If <code>expr<strong>1</strong></code> can be converted to <code>true</code>, returns <code>expr<strong>2</strong></code>; else, returns <code>expr<strong>1</strong></code>.</p> + +<p>If a value can be converted to <code>true</code>, the value is so-called {{Glossary("truthy")}}. If a value can be converted to <code>false</code>, the value is so-called {{Glossary("falsy")}}.</p> + +<p>Examples of expressions that can be converted to false are:</p> + +<ul> + <li><code>null</code>;</li> + <li><code>NaN</code>;</li> + <li><code>0</code>;</li> + <li>empty string (<code>""</code> or <code>''</code> or <code>``</code>);</li> + <li><code>undefined</code>.</li> +</ul> + +<p>Even though the <code>&&</code> operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a <a href="/en-US/docs/Web/JavaScript/Data_structures#Boolean_type">boolean primitive</a>. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">NOT operator</a> or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.</p> + +<h3 id="Short-circuit_evaluation">Short-circuit evaluation</h3> + +<p>The logical AND expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:</p> + +<p><code>(some falsy expression) && <em>expr</em></code> is short-circuit evaluated to the falsy expression;</p> + +<p>Short circuit means that the <code><em>expr</em></code> part above is <strong>not evaluated</strong>, hence any side effects of doing so do not take effect (e.g., if <code><em>expr</em></code> is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:</p> + +<pre class="brush: js notranslate">function A(){ console.log('called A'); return false; } +function B(){ console.log('called B'); return true; } + +console.log( A() && B() ); +// logs "called A" due to the function call, +// then logs false (which is the resulting value of the operator) +</pre> + +<h3 id="Operator_precedence">Operator precedence</h3> + +<p>The following expressions might seem equivalent, but they are not, because the <code>&&</code> operator is executed before the <code>||</code> operator (see <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">operator precedence</a>).</p> + +<pre class="brush: js notranslate">true || false && false // returns true, because && is executed first +(true || false) && false // returns false, because operator precedence cannot apply</pre> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_AND">Using AND</h3> + +<p>The following code shows examples of the <code>&&</code> (logical AND) operator.</p> + +<pre class="brush: js notranslate">a1 = true && true // t && t returns true +a2 = true && false // t && f returns false +a3 = false && true // f && t returns false +a4 = false && (3 == 4) // f && f returns false +a5 = 'Cat' && 'Dog' // t && t returns "Dog" +a6 = false && 'Cat' // f && t returns false +a7 = 'Cat' && false // t && f returns false +a8 = '' && false // f && f returns "" +a9 = false && '' // f && f returns false</pre> + +<h3 id="Conversion_rules_for_booleans">Conversion rules for booleans</h3> + +<h4 id="Converting_AND_to_OR">Converting AND to OR</h4> + +<p>The following operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 && bCondition2</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">!(!bCondition1 || !bCondition2)</pre> + +<h4 id="Converting_OR_to_AND">Converting OR to AND</h4> + +<p>The following operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 || bCondition2</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">!(!bCondition1 && !bCondition2)</pre> + +<h3 id="Removing_nested_parentheses">Removing nested parentheses</h3> + +<p>As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.</p> + +<p>The following composite operation involving <strong>booleans</strong>:</p> + +<pre class="brush: js notranslate">bCondition1 || (bCondition2 && bCondition3)</pre> + +<p>is always equal to:</p> + +<pre class="brush: js notranslate">bCondition1 || bCondition2 && bCondition3</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#prod-LogicalANDExpression', 'Logical AND expression')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.logical_and")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Boolean")}}</li> + <li>{{Glossary("Truthy")}}</li> + <li>{{Glossary("Falsy")}}</li> +</ul> |