From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../operators/addition_assignment/index.html | 74 ++ .../operators/arithmetic_operators/index.html | 301 ++++++++ .../operators/array_comprehensions/index.html | 157 +++++ .../reference/operators/assignment/index.html | 62 ++ .../operators/assignment_operators/index.html | 412 +++++++++++ .../index.html" | 98 +++ .../reference/operators/await/index.html | 158 +++++ .../operators/bitwise_and_assignment/index.html | 59 ++ .../reference/operators/bitwise_not/index.html | 100 +++ .../operators/bitwise_operators/index.html | 755 +++++++++++++++++++++ .../reference/operators/bitwise_or/index.html | 108 +++ .../operators/bitwise_or_assignment/index.html | 57 ++ .../reference/operators/bitwise_xor/index.html | 108 +++ .../operators/bitwise_xor_assignment/index.html | 65 ++ .../reference/operators/class/index.html | 112 +++ .../reference/operators/comma_operator/index.html | 84 +++ .../operators/comparison_operators/index.html | 277 ++++++++ .../operators/conditional_operator/index.html | 126 ++++ .../reference/operators/delete/index.html | 298 ++++++++ .../operators/destructuring_assignment/index.html | 431 ++++++++++++ .../reference/operators/division/index.html | 76 +++ .../operators/division_assignment/index.html | 58 ++ .../reference/operators/exponentiation/index.html | 107 +++ .../operators/exponentiation_assignment/index.html | 59 ++ .../operators/expression_closures/index.html | 76 +++ .../reference/operators/function/index.html | 182 +++++ .../reference/operators/function_star_/index.html | 89 +++ .../operators/generator_comprehensions/index.html | 193 ++++++ .../reference/operators/greater_than/index.html | 95 +++ .../operators/greater_than_or_equal/index.html | 95 +++ .../reference/operators/grouping/index.html | 93 +++ .../javascript/reference/operators/in/index.html | 145 ++++ .../reference/operators/increment/index.html | 84 +++ .../web/javascript/reference/operators/index.html | 297 ++++++++ .../reference/operators/inequality/index.html | 104 +++ .../reference/operators/instanceof/index.html | 186 +++++ .../reference/operators/left_shift/index.html | 72 ++ .../operators/left_shift_assignment/index.html | 59 ++ .../reference/operators/less_than/index.html | 110 +++ .../operators/less_than_or_equal/index.html | 97 +++ .../operators/logical_and_assignment/index.html | 83 +++ .../reference/operators/logical_not/index.html | 104 +++ .../logical_nullish_assignment/index.html | 82 +++ .../operators/logical_operators/index.html | 237 +++++++ .../reference/operators/logical_or/index.html | 146 ++++ .../operators/logical_or_assignment/index.html | 87 +++ .../reference/operators/multiplication/index.html | 69 ++ .../operators/multiplication_assignment/index.html | 55 ++ .../reference/operators/new.target/index.html | 99 +++ .../javascript/reference/operators/new/index.html | 201 ++++++ .../nullish_coalescing_operator/index.html | 158 +++++ .../operators/object_initializer/index.html | 314 +++++++++ .../operators/operator_precedence/index.html | 351 ++++++++++ .../operators/property_accessors/index.html | 153 +++++ .../operators/remainder_assignment/index.html | 56 ++ .../reference/operators/right_shift/index.html | 75 ++ .../operators/right_shift_assignment/index.html | 59 ++ .../reference/operators/spread_syntax/index.html | 245 +++++++ .../reference/operators/strict_equality/index.html | 101 +++ .../operators/strict_inequality/index.html | 95 +++ .../reference/operators/subtraction/index.html | 67 ++ .../operators/subtraction_assignment/index.html | 59 ++ .../reference/operators/super/index.html | 184 +++++ .../javascript/reference/operators/this/index.html | 498 ++++++++++++++ .../reference/operators/typeof/index.html | 286 ++++++++ .../reference/operators/unary_negation/index.html | 73 ++ .../reference/operators/unary_plus/index.html | 75 ++ .../operators/unsigned_right_shift/index.html | 71 ++ .../unsigned_right_shift_assignment/index.html | 55 ++ .../javascript/reference/operators/void/index.html | 114 ++++ .../reference/operators/yield/index.html | 104 +++ .../reference/operators/yield_star_/index.html | 162 +++++ .../operators/\345\217\226\344\275\231/index.html" | 81 +++ .../index.html" | 202 ++++++ .../index.html" | 106 +++ .../operators/\347\233\270\345\212\240/index.html" | 79 +++ .../operators/\347\233\270\347\255\211/index.html" | 125 ++++ .../index.html" | 75 ++ .../operators/\350\207\252\345\207\217/index.html" | 85 +++ .../index.html" | 137 ++++ 80 files changed, 11527 insertions(+) create mode 100644 files/zh-cn/web/javascript/reference/operators/addition_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html create mode 100644 "files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" create mode 100644 files/zh-cn/web/javascript/reference/operators/await/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_and_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_not/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_or/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_or_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_xor/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_xor_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/class/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/delete/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/destructuring_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/division/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/division_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/exponentiation/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/exponentiation_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/expression_closures/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/function/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/function_star_/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/greater_than/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/greater_than_or_equal/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/grouping/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/in/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/increment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/inequality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/instanceof/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/left_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/left_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/less_than/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/less_than_or_equal/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_and_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_not/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_nullish_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_or/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_or_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/multiplication/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/multiplication_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/new.target/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/new/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/nullish_coalescing_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/object_initializer/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/operator_precedence/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/property_accessors/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/remainder_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/right_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/right_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/spread_syntax/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/strict_equality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/strict_inequality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/subtraction/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/subtraction_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/super/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/this/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/typeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unary_negation/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unary_plus/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unsigned_right_shift/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/unsigned_right_shift_assignment/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/void/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/yield/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/yield_star_/index.html create mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" create mode 100644 "files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" (limited to 'files/zh-cn/web/javascript/reference/operators') 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 +--- +
{{jsSidebar("Operators")}}
+ +

加法赋值操作符 (+=) 将右操作数的值添加到变量,并将结果分配给该变量。两个操作数的类型确定加法赋值运算符的行为。加法或串联是可能的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-addition-assignment.html")}}
+ +
+ + + +

Syntax

+ +
Operator: x += y
+Meaning:  x  = x + y
+ +

Examples

+ +

Using addition assignment

+ +
// 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"
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.addition_assignment")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

算术运算符以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法(-),乘法(*)和除法(/)。

+ +
{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}
+ + + +

加法 (+)

+ +

加法运算符的作用是数值求和,或者字符串拼接。

+ +

语法

+ +
运算符: x + y
+
+ +

示例

+ +
// 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"
+
+ +

减法 (-)

+ +

减法运算符使两个操作数相减,结果是它们的差值。

+ +

语法

+ +
运算符: x - y
+
+ +

示例

+ +
5 - 3 // 2
+3 - 5 // -2
+"foo" - 3 // NaN
+ +

除法 (/)

+ +

除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。

+ +

语法

+ +
运算符: x / y
+
+ +

示例

+ +
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
+ +

乘法 (*)

+ +

乘法运算符的结果是操作数的乘积。

+ +

语法

+ +
运算符: x * y
+
+ +

示例

+ +
2 * 2 // 4
+-2 * 2 // -4
+Infinity * 0 // NaN
+Infinity * Infinity // Infinity
+"foo" * 2 // NaN
+
+ +

求余 (%)

+ +

求余运算符返回第一个操作数对第二个操作数的模,即 var1 对 var2 取模,其中 var1 和 var2 是变量。取模功能就是 var1 除以 var2 的整型余数。

+ +

语法

+ +
运算符: var1 % var2
+
+ +

示例

+ +
12 % 5 // 2
+-1 % 2 // -1
+NaN % 2 // NaN
+1 % 2 // 1
+2 % 3 // 2
+-4 % 2 // -0
+5.5 % 2 // 1.5
+
+ +

幂 (**)

+ +

幂运算符返回第一个操作数做底数,第二个操作数做指数的乘方。即,var1var2,其中 var1var2 是其两个操作数。幂运算符是右结合的。a ** b ** c 等同于 a ** (b ** c)

+ +

语法

+ +
运算符: var1 ** var2
+
+ +

注解

+ +

包括 PHP 或 Python 等的大多数语言中,都包含幂运算符(一般来说符号是 ^ 或者 **)。这些语言中的幂运算符有着比其他的单目运算符(如一元 + 或一元 - )更高的优先级。但是作为例外,在 Bash 中,**  运算符被设计为比单目运算符优先级更低。在最新的 JavaScript(ES2016) 中,禁止使用带歧义的幂运算表达式。比如,底数前不能紧跟一元运算符(+/-/~/!/delete/void/typeof)。

+ +
-2 ** 2;
+// 在 Bash 中等于 4 ,而在其他语言中一般等于 -4
+// 在 JavaScript 中是错误的,因为这会有歧义
+
+-(2 ** 2);
+// -4 在 JavaScript 中能够明显体现出作者的意图
+ +

示例

+ +
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
+
+ +

如果要反转求幂表达式结果的符号,你可以采用这样的方式:

+ +
-(2 ** 2) // -4
+ +

强制求幂表达式的基数为负数:

+ +
(-2) ** 2 // 4
+ +

递增 (++)

+ +

递增运算符为其操作数增加1,返回一个数值。

+ + + +

语法

+ +
运算符: x++ 或者 ++x
+
+ +

示例

+ +
// 后置
+var x = 3;
+y = x++;
+// y = 3, x = 4
+
+// 前置
+var a = 2;
+b = ++a;
+// a = 3, b = 3
+
+ +

递减 (--)

+ +

递减运算符将其操作数减去1,并返回一个数值。

+ + + +

语法

+ +
运算符: x-- or --x
+
+ +

示例

+ +
// 后置
+var x = 3;
+y = x--; // y = 3, x = 2
+
+// 前置
+var a = 2;
+b = --a; // a = 1, b = 1
+
+ +

一元负号 (-)

+ +

一元负号运算符位于操作数前面,并转换操作数的符号。

+ +

语法

+ +
运算符: -x
+
+ +

示例

+ +
var x = 3;
+y = -x; // y = -3, x = 3
+
+ +

一元正号 (+)

+ +

一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。 尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值 truefalse  null。小数和十六进制格式字符串也可以转换成数值。负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 NaN

+ +

语法

+ +
运算符: +x
+
+ +

示例

+ +
+3     // 3
++"3"   // 3
++true  // 1
++false // 0
++null  // 0
++function(val){ return val;} //NaN
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Added Exponentiation operator.
{{SpecName('ES2017', '#sec-postfix-expressions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-additive-operators')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.arithmetic")}}

+ +

相关链接

+ + 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 +--- +
+

非标准。不要使用!
+ 数组推导是非标准的。以后应该用 {{jsxref("Array.prototype.map")}},{{jsxref("Array.prototype.filter")}},{{jsxref("Functions/Arrow_functions", "箭头函数", "", 1)}}和{{jsxref("Operators/Spread_operator", "展开语法", "", 1)}}.。

+
+ +

{{jsSidebar("Operators")}} 

+ +

数组推导式是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!

+ +

语法

+ +
[for (x of iterable) x]
+[for (x of iterable) if (condition) x]
+[for (x of iterable) for (y of iterable) x + y]
+
+ +

描述

+ +

在数组推导式内部,可以使用下面两种子语句:

+ + + +

每个 for-of 语句都放在与其配对的 if 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。

+ +

示例

+ +

基本的数组推导式写法

+ +
[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" ]
+ +

带有 if 语句的数组推导式

+ +
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]
+
+ +

用数组推导式比用数组的 mapfilter 方法更简洁

+ +

对比数组的 {{jsxref("Array.map", "map")}} 和 {{jsxref("Array.filter", "filter")}} 方法:

+ +
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 ]
+
+ +

带有两个数组的数组推导式

+ +

用两个 for-of 语句迭代两个不同的数组:

+ +
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"],和下面的写法等效:
+
+[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"]],和下面的写法不等效:
+
+[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
+// [[], ["2b", "2c"], ["3b", "3c"]]
+
+ +

规范

+ +

最初起草在ECMAScript 6草案中,但在第27版(2014年8月)中被移除。 请参阅ES 6的旧修订版的规范语义。

+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.array_comprehensions")}}

+ +

同旧版的JS1.7/JS1.8数组推导的不同之处

+ +

 

+ +
JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 ({{bug(1220564)}}).
+ +

旧版数组推导语法 (请不要再使用了!):

+ +
[X for (Y in Z)]
+[X for each (Y in Z)]
+[X for (Y of Z)]
+
+ +

不同点:

+ + + +

点击查看 Bug 1220564, comment 42 并提出建设性建议.

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

简单赋值操作符(=)用于为变量赋值。赋值表达式本身的值为其完成后被赋值的变量的值。为了给多个变量赋一个值,可以链式使用赋值操作符。

+ +
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x = y
+
+ +

示例

+ +

简单赋值和链式赋值

+ +
// 假设已经存在以下变量
+//  x = 5
+//  y = 10
+//  z = 25
+
+x = y     // x 为 10
+x = y = z // x, y 都为 25
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.operators.assignment")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

赋值运算符(assignment operator)基于右值(right operand)的值,给左值(left operand)赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
+ + + +

概述

+ +

基本的赋值运算符是等号(=),该运算符把它右边的运算值赋给左边。即,x = y 把 y 的值赋给 x。 其他的赋值运算符通常是标准运算符的简写形式,如下面的定义与示例。 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称简写形式含义
赋值(Assignment)x = yx = y
加赋值(Addition assignment)x += yx = x + y
减赋值(Subtraction assignment)x -= yx = x - y
乘赋值(Multiplication assigment)x *= yx = x * y
除赋值(Division assignment)x /= yx = x / y
模赋值(Remainder assignment)x %= yx = x % y
指数赋值(Exponentiation assignment)x **= yx = x ** y
左移赋值(Left shift assignment)x <<= yx = x << y
右移赋值(Right shift assignment)x >>= yx = x >> y
无符号右移赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y
+ +

赋值

+ +

简单的赋值运算符,把一个值赋给一个变量。为了把一个值赋给多个变量,可以以链式使用赋值运算符。参考下例:

+ +

语法

+ +
Operator: x = y
+
+ +

示例

+ +
// 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
+
+ +

加赋值(Addition assignment)

+ +

加赋值运算符把一个右值与一个变量相加,然后把相加的结果赋给该变量。两个操作数的类型决定了加赋值运算符的行为。算术相加或字符串连接都有可能。更多细节参考 {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}}。

+ +

语法

+ +
Operator: x += y
+Meaning:  x  = x + y
+
+ +

示例

+ +
// 定义下列变量
+//  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"
+
+ +

减赋值(Subtraction assignment)

+ +

减赋值运算符使一个变量减去右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} 。

+ +

语法

+ +
Operator: x -= y
+Meaning:  x  = x - y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar -= 2     // 3
+bar -= "foo" // NaN
+
+ +

乘赋值(Multiplication assignment)

+ +

乘赋值运算符使一个变量乘以右值,然后把相成的结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}}。

+ +

语法

+ +
Operator: x *= y
+Meaning:  x  = x * y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar *= 2     // 10
+bar *= 'foo' // NaN
+
+ +

除赋值(Division assignment)

+ +

除赋值运算符使一个变量除以右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}}。

+ +

语法

+ +
Operator: x /= y
+Meaning:  x  = x / y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= "foo" // NaN
+bar /= 0     // Infinity
+
+ +

模赋值(Remainder assignment)

+ +

模赋值运算符使一个变量除以右值,然后把余数赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}}。

+ +

语法

+ +
Operator: x %= y
+Meaning:  x  = x % y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar %= 2     // 1
+bar %= 'foo' // NaN
+bar %= 0     // NaN
+
+ +

指数赋值(Exponentiation assignment)

+ +

指数赋值运算符使一个变量为底数、以右值为指数的指数运算(乘方)结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "算术运算符", "#Exponentiation", 1)}}。

+ +

语法

+ +
语法: x **= y
+含义:  x  = x ** y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar **= 2     // 25
+bar **= 'foo' // NaN
+ +

左移赋值(Left shift assignment)

+ +

左移赋值运算符使变量向左移动指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}。

+ +

语法

+ +
Operator: x <<= y
+Meaning:  x   = x << y
+
+ +

示例

+ +
var bar = 5; //  (00000000000000000000000000000101)
+bar <<= 2; // 20 (00000000000000000000000000010100)
+
+ +

右移赋值(Right shift assignment)

+ +

右移赋值运算符使变量向右移指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>= y
+Meaning:  x   = x >> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>= 2;   // 1 (00000000000000000000000000000001)
+
+var bar = -5; //    (-00000000000000000000000000000101)
+bar >>= 2;  // -2 (-00000000000000000000000000000010)
+
+ +

无符号右移赋值(Unsigned right shift assignment)

+ +

无符号右移赋值运算符向右移动指定数量的比特位,然后把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>>= y
+Meaning:  x    = x >>> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>>= 2;  // 1 (00000000000000000000000000000001)
+
+var bar = -5; // (-00000000000000000000000000000101)
+bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
+ +

按位与赋值(Bitwise AND assignment)

+ +

按位与赋值运算符使用两个操作值的二进制表示,执行按位与运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}。

+ +

语法

+ +
Operator: x &= y
+Meaning:  x  = x & y
+
+ +

示例

+ +
var bar = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+bar &= 2; // 0
+
+ +

按位异或赋值(Bitwise XOR assignment)

+ +

按位异或赋值运算符使用两个操作值的二进制表示,执行二进制异或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}。

+ +

语法

+ +
Operator: x ^= y
+Meaning:  x  = x ^ y
+
+ +

示例

+ +
var bar = 5;
+bar ^= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

按位或赋值(Bitwise OR assignment)

+ +

按位或赋值运算符使用两个操作值的二进制表示,执行按位或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}。

+ +

语法

+ +
Operator: x |= y
+Meaning:  x  = x | y
+
+ +

示例

+ +
var bar = 5;
+bar |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

示例

+ +

带有赋值运算符的左值(Left operand)

+ +

在某些不常见的情况下,赋值运算符(如 x += y)并不等同于表达式( x = x + y)。当一个赋值运算符的左值包含有一个赋值运算符时,左值只会被求值一次。例如:

+ +
a[i++] += 5         // i 执行一次求值
+a[i++] = a[i++] + 5 // i 执行两次求值
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES1')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.assignment")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" "b/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" new file mode 100644 index 0000000000..eebfd13ca2 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/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 +--- +
{{jsSidebar("Operators")}}
+ +
 
+ +

async function 关键字用来在表达式中定义异步函数。当然,你也可以用 {{jsxref('Statements/async_function', '异步函数语句')}} 来定义。

+ +

语法

+ +
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
+ +

参数

+ +
+
name
+
此异步函数的名称,可省略。如果省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。
+
paramN
+
传入函数的形参名称。
+
statements
+
组成函数体的语句。
+
+ +

描述

+ +

异步函数表达式与 {{jsxref('Statements/async_function', '异步函数语句')}} 非常相似,语法也基本相同。它们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。另外,异步函数表达式还可以用在 {{Glossary("IIFE")}} (立即执行函数表达式,Immediately Invoked Function Expression) 中,更多信息见 {{jsxref('Reference/Functions', '函数')}}。

+ +

示例

+ +

一个简单例子

+ +
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
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}ES2017 中的初始定义
+ +

浏览器兼容性

+ +
{{Compat("javascript.operators.async_function_expression")}}
+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

await  操作符用于等待一个{{jsxref("Promise")}} 对象。它只能在异步函数 {{jsxref("Statements/async_function", "async function")}} 中使用。

+ +

语法

+ +
[返回值] = await 表达式;
+ +
+
表达式
+
一个 {{jsxref("Promise")}} 对象或者任何要等待的值。
+
返回值
+
+

返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。

+
+
+ +

描述

+ +

await 表达式会暂停当前 {{jsxref("Statements/async_function", "async function")}} 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 {{jsxref("Statements/async_function", "async function")}}。

+ +

若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。

+ +

另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。

+ +

例子

+ +

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

+ +
function resolveAfter2Seconds(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+}
+
+async function f1() {
+  var x = await resolveAfter2Seconds(10);
+  console.log(x); // 10
+}
+f1();
+
+
+ +

如果该值不是一个 Promise,await 会把该值转换为已正常处理的Promise,然后等待其处理结果。

+ +
async function f2() {
+  var y = await 20;
+  console.log(y); // 20
+}
+f2();
+
+ +

如果 Promise 处理异常,则异常值被抛出。

+ +
async function f3() {
+  try {
+    var z = await Promise.reject(30);
+  } catch (e) {
+    console.log(e); // 30
+  }
+}
+f3();
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Async Function', '#async-function-definitions', 'async function')}}{{Spec2('Async Function')}}提案
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerEdgeOperaSafari (WebKit)
基本支持{{CompatChrome(55)}}{{CompatGeckoDesktop("52.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatOpera(42)}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
 基本支持{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("52.0")}}{{CompatUnknown}}{{CompatOpera(42)}}{{CompatUnknown}}{{CompatChrome(55)}}
+
+ +

查看更多

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +
按位与赋值运算符(&=)表示两个操作数的二进制,对它们进行按位AND运算并将结果分配给变量。
+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x &= y
+Meaning:  x  = x & y
+
+ +

例子

+ +

按位与赋值运算

+ +
let a = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+a &= 2; // 0
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_and_assignment")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

按位非运算符(~),反转操作数的位。

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-not.html")}}
+ +
+ + + +

语法

+ +
~a
+
+ +

描述

+ +

操作数被转换为32位二进制表示(0和1)。超过32位的数字将丢弃其最高有效位。如下例子中,超过32位的整数转换为32位整数:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

+ +

将运算符应用于每对位,然后按位构造结果。

+ +

非运算的真值表:

+ + + + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +
 9 (base 10) = 00000000000000000000000000001001 (base 2)
+               --------------------------------
+~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
+
+ +

按位非运算时,任何数字x的运算结果都是-(x + 1)。例如,〜-5运算结果为4

+ +

Note that due to using 32-bit representation for numbers both ~-1 and ~4294967295 (232-1) results in 0.

+ +

请注意,由于对数字~-1~4294967295 (232-1) 使用32位表示形式,结果均为0。

+ +

例子

+ +

使用按位取反

+ +
~0;  // -1
+~-1; // 0
+~1;  // -2
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-operators', 'Unary NOT expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_not")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

概述

+ +

按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。

+ +

下面的表格总结了JavaScript中的按位操作符:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符用法描述
按位与( AND)a & b对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。
按位或(OR)a | b对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。
按位异或(XOR)a ^ b对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。
按位非(NOT)~ a反转操作数的比特位,即0变成1,1变成0。
左移(Left shift)a << b将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。
有符号右移a >> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。
无符号右移a >>> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。
+ +

有符号32位整数

+ +

所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:

+ +
00000000000000000000000100111010
+
+ +

下面编码 ~314,即 314 的反码:

+ +
11111111111111111111111011000101
+
+ +

最后,下面编码 -314,即 314 的反码再加1:

+ +
11111111111111111111111011000110
+
+ +

补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(sign bit)。

+ +

0 是所有比特数字0组成的整数。

+ +
0 (base 10) = 00000000000000000000000000000000 (base 2)
+
+ +

-1 是所有比特数字1组成的整数。

+ +
-1 (base 10) = 11111111111111111111111111111111 (base 2)
+
+ +

-2147483648(十六进制形式:-0x80000000)是除了最左边为1外,其他比特位都为0的整数。

+ +
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
+
+ +

2147483647(十六进制形式:0x7fffffff)是除了最左边为0外,其他比特位都为1的整数。

+ +
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
+
+ +

数字-21474836482147483647 是32位有符号数字所能表示的最小和最大整数。

+ +

按位逻辑操作符

+ +

从概念上讲,按位逻辑操作符按遵守下面规则:

+ + + +

& (按位与)

+ +

对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。与操作的真值表如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。

+ +

| (按位或)

+ +

对每一对比特位执行或(OR)操作。如果 a 或 b 为 1,则 a OR b 结果为 1。或操作的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
+
+ +

将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。

+ +

补充一些例子:

+ +
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
+ +

^ (按位异或)

+ +

对每一对比特位执行异或(XOR)操作。当 a 和 b 不相同时,a XOR b 的结果为 1。异或操作真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
+
+ +

将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。

+ +

~ (按位非)

+ +

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)。非操作的真值表:

+ + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +
 9 (base 10) = 00000000000000000000000000001001 (base 2)
+               --------------------------------
+~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
+
+ +

对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。

+ +

与 indexOf 一起使用示例:

+ +
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
+
+ +

按位移动操作符

+ +

按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。

+ +

按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。

+ +
注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,
+又称为"高位编址"。
+Big-Endian是最直观的字节序:
+①把内存地址从左到右按照由低到高的顺序写出;
+②把值按照通常的高位到低位的顺序写出;
+③两者对照,一个字节一个字节的填充进去。
+ +

<< (左移)

+ +

该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。

+ +

For example, 9 << 2 yields 36:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
+
+ +

在数字 x 上左移 y 比特得到 x * 2y.

+ +

>> (有符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

+ +

例如, 9 >> 2 得到 2:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

相比之下, -9 >> 2 得到 -3,因为符号被保留了。

+ +
     -9 (base 10): 11111111111111111111111111110111 (base 2)
+                   --------------------------------
+-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
+
+ +

>>> (无符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

+ +

对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 9 >>> 29 >> 2 一样返回 2:

+ +
      9 (base 10): 00000000000000000000000000001001 (base 2)
+                   --------------------------------
+9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

+ +
      -9 (base 10): 11111111111111111111111111110111 (base 2)
+                    --------------------------------
+-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
+
+ +

示例

+ +

例子:标志位与掩码

+ +

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。

+ +

例如,有 4 个标志位:

+ + + +

标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 flags 的二进制值为 0101:

+ +
var flags = 5;   // 二进制 0101
+
+ +

这个值表示:

+ + + +

因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。

+ +

掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

+ +
var FLAG_A = 1; // 0001
+var FLAG_B = 2; // 0010
+var FLAG_C = 4; // 0100
+var FLAG_D = 8; // 1000
+
+ +

新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:

+ +
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
+
+ +

某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:

+ +
// 如果我们有 cat
+if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
+   // do stuff
+}
+
+ +

一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:

+ +
// 如果我们有 bat 或者 cat 至少一个
+// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
+if ((flags & FLAG_B) || (flags & FLAG_C)) {
+   // do stuff
+}
+
+ +
// 如果我们有 bat 或者 cat 至少一个
+var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
+if (flags & mask) { // 0101 & 0110 => 0100 => true
+   // do stuff
+}
+
+ +

可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:

+ +
// 我们有 cat 和 duck
+var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
+flags |= mask;   // 0101 | 1100 => 1101
+
+ +

可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :

+ +
// 我们没有 ant 也没有 cat
+var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

如上的掩码同样可以通过 ~FLAG_A & ~FLAG_C 得到(德摩根定律):

+ +
// 我们没有 ant 也没有 cat
+var mask = ~FLAG_A & ~FLAG_C;
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:

+ +
// 如果我们以前没有 bat ,那么我们现在有 bat
+// 但是如果我们已经有了一个,那么现在没有了
+// 对 cat 也是相同的情况
+var mask = FLAG_B | FLAG_C;
+flags = flags ^ mask;   // 1100 ^ 0110 => 1010
+
+ +

最后,所有标志位可以通过非运算翻转:

+ +
// entering parallel universe...
+flags = ~flags;    // ~1010 => 0101
+
+ +

转换片段

+ +

将一个二进制数的 String 转换为十进制的 Number:

+ +
var sBinString = "1011";
+var nMyNumber = parseInt(sBinString, 2);
+alert(nMyNumber); // 打印 11
+
+ +

将一个十进制的 Number 转换为二进制数的 String:

+ +
var nMyNumber = 11;
+var sBinString = nMyNumber.toString(2);
+alert(sBinString); // 打印 1011
+
+ +

自动化掩码创建

+ +

如果你需要从一系列的 Boolean 值创建一个掩码,你可以:

+ +
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
+
+ +

逆算法:从掩码得到布尔数组

+ +

如果你希望从掩码得到得到 Boolean Array

+ +
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
+
+ +

你可以同时测试以上两个算法……

+ +
var nTest = 19; // our custom mask
+var nResult = createMask.apply(this, arrayFromMask(nTest));
+
+alert(nResult); // 19
+
+ +

仅仅由于教学目的 (因为有 Number.toString(2) 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:

+ +
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
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}
+ {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}
+ {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}
{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}
+ {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}
+ {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}
{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise OR operator (|) returns a 1 in each bit position for which the corresponding bits of either or both operands are 1s.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-or.html")}}
+ + + +

语法

+ +
a | b
+
+ +

描述

+ +

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:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

Each bit in the first operand is paired with the corresponding bit in the second operand: first bit to first bit, second bit to second bit, and so on.

+ +

The operator is applied to each pair of bits, and the result is constructed bitwise.

+ +

The truth table for the OR operation is:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
+
+ +

Bitwise ORing any number x with 0 yields x.

+ +

例子

+ +

Using bitwise OR

+ +
// 9  (00000000000000000000000000001001)
+// 14 (00000000000000000000000000001110)
+
+14 | 9;
+// 15 (00000000000000000000000000001111)
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseORExpression', 'Bitwise OR expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_or")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise OR assignment operator (|=) uses the binary representation of both operands, does a bitwise OR operation on them and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-or-assignment.html")}}
+ + + +

语法

+ +
Operator: x |= y
+Meaning:  x  = x | y
+ +

Examples

+ +

Using bitwise OR assignment

+ +
let a = 5;
+a |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.bitwise_or_assignment")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The bitwise XOR operator (^) returns a 1 in each bit position for which the corresponding bits of either but not both operands are 1s.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor.html")}}
+ + + +

语法

+ +
a ^ b
+
+ +

描述

+ +

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:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

Each bit in the first operand is paired with the corresponding bit in the second operand: first bit to first bit, second bit to second bit, and so on.

+ +

The operator is applied to each pair of bits, and the result is constructed bitwise.

+ +

The truth table for the XOR operation is:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
+
+ +

Bitwise XORing any number x with 0 yields x.

+ +

Examples

+ +

Using bitwise XOR

+ +
// 9  (00000000000000000000000000001001)
+// 14 (00000000000000000000000000001110)
+
+14 ^ 9;
+// 7  (00000000000000000000000000000111)
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseXORExpression', 'Bitwise XOR expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_xor")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

按位异或赋值操作符 (^=) 使用二进制表示操作数,进行一次按位异或操作并赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-xor-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x ^= y
+Meaning:  x  = x ^ y
+ +

例子

+ +

使用按位异或赋值

+ +
let a = 5;      // 00000000000000000000000000000101
+a ^= 3;         // 00000000000000000000000000000011
+
+console.log(a); // 00000000000000000000000000000110
+// 6
+
+let b = 5;      // 00000000000000000000000000000101
+b ^= 0;         // 00000000000000000000000000000000
+
+console.log(b); // 00000000000000000000000000000101
+// 5
+
+
+
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_xor_assignment")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

类表达式是用来定义类的一种语法。和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。JavaScript 的类也是基于原型继承的。

+ +

语法

+ +
const MyClass = class [className] [extends] {
+  // class body
+};
+ +

描述

+ +

类表达式的语法和类语句的语法很类似,只是在类表达式中,你可以省略掉类名,而类语句中不能。

+ +

和类声明一样,类表达式中的代码也是强制严格模式的。

+ +

示例

+ +

使用类表达式

+ +

下面的代码使用类表达式语法创建了一个匿名类,然后赋值给变量 Foo。

+ +
let Foo = class {
+  constructor() {}
+  bar() {
+    return "Hello World!";
+  }
+};
+
+let instance = new Foo();
+instance.bar();
+// "Hello World!"
+
+ +

命名类表达式

+ +

如果你想在类体内部也能引用这个类本身,那么你就可以使用命名类表达式,并且这个类名只能在类体内部访问。

+ +
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"
+
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.class")}}

+ +

相关链接

+ + 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 +--- +
+
{{jsSidebar("Operators")}}
+
+ +

逗号操作符  对它的每个操作数求值(从左到右),并返回最后一个操作数的值。

+ +

{{EmbedInteractiveExample("pages/js/expressions-commaoperators.html")}}

+ +

语法

+ +
expr1, expr2, expr3...
+ +

参数

+ +
+
expr1, expr2, expr3...
+
任一表达式。
+
+ +

描述

+ +

当你想要在期望一个表达式的位置包含多个表达式时,可以使用逗号操作符。这个操作符最常用的一种情况是:for 循环中提供多个参数。

+ +

示例

+ +

假设 a 是一个二维数组,每一维度包含10个元素,则下面的代码使用逗号操作符一次递增/递减两个变量。需要注意的是,var 语句中的逗号不是逗号操作符,因为它不是存在于一个表达式中。尽管从实际效果来看,那个逗号同逗号运算符的表现很相似。但确切地说,它是 var 语句中的一个特殊符号,用于把多个变量声明结合成一个。下面的代码打印一个二维数组中斜线方向的元素:

+ +
for (var i = 0, j = 9; i <= 9; i++, j--)
+  document.writeln("a[" + i + "][" + j + "] = " + a[i][j]);
+ +

处理后返回

+ +

另一个使用逗号操作符的例子是在返回值前处理一些操作。如同下面的代码,只有最后一个表达式被返回,其他的都只是被求值。

+ +
function myFunc () {
+  var x = 0;
+
+  return (x += 1, x); // the same of return ++x;
+}
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{Compat("javascript.operators.comma")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符。对于严格比较运算符(===)来说,仅当两个操作数的类型相同且值相等为 true,而对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。

+ +

字符串比较则是使用基于标准字典的 Unicode 值来进行比较的。

+ +

比较的特点:

+ + + +

相等运算符

+ +

相等(==)

+ +

比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。

+ +

语法

+ +
x == y
+
+ +

例子

+ +
 1   ==  1     // true
+"1"  ==  1     // true
+ 1   == '1'    // true
+ 0   == false  // true
+
+ +

不相等 (!=)

+ +

不等操作符仅当操作数不相等时返回true,如果两操作数不是同一类型,JavaScript会尝试将其转为一个合适的类型,然后进行比较。如果两操作数为对象类型,JavaScript会比较其内部引用地址,仅当他们在内存中引用不同对象时不相等。

+ +

语法

+ +
x != y
+ +

例子

+ +
1 !=   2     // true
+1 !=  "1"    // false
+1 !=  '1'    // false
+1 !=  true   // false
+0 !=  false  // false
+
+ +

一致/严格相等 (===)

+ +

一致运算符不会进行类型转换,仅当操作数严格相等时返回true

+ +

语法

+ +
x === y
+ +

例子

+ +
3 === 3   // true
+3 === '3' // false
+var object1 = {"value":"key"}, object2={"value":"key"};
+object1 === object2 //false
+ +

不一致/严格不相等 (!==)

+ +

不一致运算符当操作数不相等或不同类型时返回true

+ +

语法

+ +
x !== y
+ +

例子

+ +
3 !== '3' // true
+4 !== 3   // true
+
+ +

关系运算符

+ +

大于运算符 (>)

+ +

大于运算符仅当左操作数大于右操作数时返回true

+ +

语法

+ +
x > y
+ +

例子

+ +
4 > 3 // true
+
+ +

大于等于运算符 (>=)

+ +

大于等于运算符当左操作数大于或等于右操作数时返回true

+ +

语法

+ +
 x >= y
+ +

例子

+ +
4 >= 3 // true
+3 >= 3 // true
+
+ +

小于运算符 (<)

+ +

小于运算符仅当左操作数小于右操作数时返回true

+ +

语法

+ +
 x < y
+ +

例子

+ +
3 < 4 // true
+
+ +

小于等于运算符 (<=)

+ +

小于等于运算符当左操作数小于或等于右操作数时返回true

+ +

语法

+ +
 x <= y
+ +

例子

+ +
3 <= 4 // true
+
+ +

使用比较操作符

+ +

标准相等操作符(== and !=) 使用 Abstract Equality Comparison Algorithm 去比较两个操作数。当两个操作数类型不相等时,会在比较前尝试将其转换为相同类型。 e.g., 对于表达式 5 == '5', 在比较前会先将右边字符串类型的操作数 5 转换为数字。

+ +

严格相等操作符 (=== and !==) 使用 Strict Equality Comparison Algorithm 并尝试对两个相同操作数进行相等比较,如果它们的类型不相等,那么永远会返回false 所以 5 !== '5'。

+ +

当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。

+ +

当比较运算涉及类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:

+ + + +
注意: 字符串对象的类型是对象,不是字符串!字符串对象很少被使用,所以下面的结果也许会让你惊讶:
+ +
// 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' 
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
ECMAScript 3rd Edition.StandardAdds === and !== operators. Implemented in JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8', 'Relational Operators')}}
+ {{SpecName('ES5.1', '#sec-11.9', 'Equality Operators')}}
{{Spec2('ES5.1')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}
+ {{SpecName('ES6', '#sec-equality-operators', 'Equality Operators')}}
{{Spec2('ES6')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

条件(三元)运算符是 JavaScript 仅有的使用三个操作数的运算符。一个条件后面会跟一个问号(?),如果条件为 {{Glossary("truthy")}} ,则问号后面的表达式A将会执行;表达式A后面跟着一个冒号(:),如果条件为 {{Glossary("falsy")}} ,则冒号后面的表达式B将会执行。本运算符经常作为 if 语句的简捷形式来使用。

+ +
{{EmbedInteractiveExample("pages/js/expressions-conditionaloperators.html")}}
+ + + +

语法

+ +
condition ? exprIfTrue : exprIfFalse
+ +

参数

+ +
+
condition
+
计算结果用作条件的表达式
+
exprIfTrue
+
如果表达式 condition 的计算结果是 {{Glossary("truthy")}}(它和 true 相等或者可以转换成 true ),那么表达式 exprIfTrue 将会被求值。
+
exprIfFalse
+
如果表达式 condition 的计算结果是 {{Glossary("falsy")}}(它可以转换成 false ),那么表达式 exprIfFalse 将会被执行。
+
+ +

描述

+ +

除了 false,可能的假值表达式还有:nullNaN 、 + 0 、空字符串( "" )、和 undefined 。如果 condition 是以上中的任何一个, 那么条件表达式的结果就是 exprIfFalse 表达式执行的结果。

+ +

一个简单的例子:

+ +
var age = 26;
+var beverage = (age >= 21) ? "Beer" : "Juice";
+console.log(beverage); // "Beer"
+
+ +

一个常见的用法是处理可能为 null 的值:

+ +
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"
+
+ +
+

Note: The optional chaining operator 设计用来处理这种使用场景。在本文档写成的时候 (2019.01),这个运算符还处于实验阶段并且没有实现。

+
+ +

条件链

+ +

这个三元操作符是右结合的,也就是说你可以像这样把它链接起来, 和 if … else if … else if … else 链类似:

+
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; }
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.conditional")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

 delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。

+ +
+
{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}
+
+ + + +

语法

+ +
delete expression
+
+ +

 expression 的计算结果应该是某个属性的引用,例如:

+ +
delete object.property
+delete object['property']
+
+ +

参数

+ +
+
object
+
对象的名称,或计算结果为对象的表达式。
+
+ +
+
property
+
要删除的属性。
+
+ +

返回值

+ +

对于所有情况都是true,除非属性是一个{{jsxref("Object.hasOwnProperty", "自身的")}} {{jsxref("Errors/Cant_delete", "不可配置")}}的属性,在这种情况下,非严格模式返回 false

+ +

异常

+ +

严格模式下,如果是属性是一个自己不可配置的属性,会抛出{{jsxref("TypeError")}}。

+ +

描述

+ +

与通常的看法不同,delete操作符与直接释放内存无关。内存管理 通过断开引用来间接完成的,查看内存管理页可了解详情。

+ +

delete 操作符会从某个对象上移除指定属性。成功删除的时候会返回 true,否则返回 false

+ +

但是,以下情况需要重点考虑:

+ + + +

下面的代码块给出了一个简单的例子:

+ +
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
+ +

不可配置属性

+ +

当一个属性被设置为不可设置,delete操作将不会有任何效果,并且会返回false。在严格模式下会抛出语法错误({{jsxref("SyntaxError")}})。

+ +
var Employee = {};
+Object.defineProperty(Employee, 'name', {configurable: false});
+
+console.log(delete Employee.name);  // returns false
+ +

{{jsxref("Statements/var","var")}}, {{jsxref("Statements/let","let")}}以及{{jsxref("Statements/const","const")}}创建的不可设置的属性不能被delete操作删除。

+ +
var nameOther = 'XYZ';
+
+// 通过以下方法获取全局属性:
+Object.getOwnPropertyDescriptor(window, 'nameOther');
+
+// 输出: Object {value: "XYZ",
+//                  writable: true,
+//                  enumerable: true,
+//                  configurable: false}
+
+// 因为“nameOther”使用var关键词添加,
+// 它被设置为不可设置(non-configurable)
+delete nameOther;   // return false
+ +

在严格模式下,这样的操作会抛出异常。

+ +

严格模式与非严格模式的对比

+ +

在严格模式下,如果对一个变量的直接引用、函数的参数或者函数名使用delete操作,将会抛出语法错误({{jsxref("SyntaxError")}})。因此,为避免严格模式下的语法错误,必须以delete object.propertydelete object['property']的形式使用delete运算符。

+ +
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
+
+ +
function func(param) {
+  // SyntaxError in strict mode.
+  console.log(delete param); // false
+}
+
+// SyntaxError in strict mode.
+console.log(delete func); // false
+
+ +
+

下文在英文原版中已删除

+
+ +

任何使用var声明的变量都会被标记为不可设置的。在下面的例子中,salary是不可设置的以及不能被删除的。在非严格模式下,下面的delete操作将会返回false。

+ +
function Employee() {
+  delete salary;
+  var salary;
+}
+
+Employee();
+ +

让我们来看看相同的代码在严格模式下会有怎样的表现。会抛出一个语法错误( SyntaxError)而不是返回false。

+ +
"use strict";
+
+function Employee() {
+  delete salary;  // SyntaxError
+  var salary;
+}
+
+// 相似的,任何对任何函数
+// 直接使用delete操作将会抛出语法错误。
+
+function DemoFunction() {
+  //some code
+}
+
+delete DemoFunction; // SyntaxError
+ +

示例

+ +
// 在全局作用域创建 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
+}
+ +

delete 和原型链

+ +

在下面的示例中,我们删除一个对象的自己的属性,而原型链上具有相同名称的属性可用:

+ +
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
+
+ +

删除数组元素

+ +

当你删除一个数组元素时,数组的长度不受影响。即便你删除了数组的最后一个元素也是如此。

+ +

当用 delete 操作符删除一个数组元素时,被删除的元素已经不再属于该数组。下面的例子中用 delete 删除了 trees[3]

+ +
var trees = ["redwood","bay","cedar","oak","maple"];
+delete trees[3];
+if (3 in trees) {
+   // 这里不会执行
+}
+
+ +

如果你想让一个数组元素继续存在但是其值是 undefined,那么可以使用将 undefined 赋值给这个元素而不是使用 delete。下面的例子中,trees[3] 被赋值为 undefined,但该元素仍然存在。

+ +
var trees = ["redwood","bay","cedar","oak","maple"];
+trees[3] = undefined;
+if (3 in trees) {
+   // 这里会被执行
+}
+ +

如果你想通过改变数组的内容来移除一个数组元素,请使用{{jsxref("Array.splice()", "splice()")}} 方法。在下面的例子中,通过使用{{jsxref("Array.splice()", "splice()")}},将trees[3]从数组中移除。

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+trees.splice(3,1);
+console.log(trees); // ["redwood", "bay", "cedar", "maple"]
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.delete")}}

+ +

跨浏览器提示

+ +

尽管ECMAScript使得对象的迭代顺序依赖于实现,但似乎所有主流浏览器都支持基于最早添加的属性(至少对于不在原型上的属性)的迭代顺序(译注:ES5 标准取消了属性遍历的顺序的规定)。但是,在 IE 中,使用 delete 删除一个属性后,奇怪的事情发生了。在IE中,如果被删除的属性重新被添加,那么遍历时,该属性的顺序会在上次删除前的那个位置,而不是出现在遍历的最后一个。

+ +

如果您想在跨浏览器的环境中使用有序的关联数组,请使用{{jsxref("Map")}}对象(如果有),或使用两个单独的数组来模拟(一个用于键,另一个用于 值),或者建立一个由单一属性对象组成的数组等。

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。

+ +

{{EmbedInteractiveExample("pages/js/expressions-destructuringassignment.html")}}

+ + + +

语法

+ +
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}
+
+ +

描述

+ +

对象和数组逐个对应表达式,或称对象字面量和数组字面量,提供了一种简单的定义一个特定的数据组的方法。

+ +
var x = [1, 2, 3, 4, 5];
+ +

解构赋值使用了相同的语法,不同的是在表达式左边定义了要从原变量中取出什么变量。

+ +
var x = [1, 2, 3, 4, 5];
+var [y, z] = x;
+console.log(y); // 1
+console.log(z); // 2
+
+ +

JavaScript 中,解构赋值的作用类似于 Perl 和 Python 语言中的相似特性。

+ +

解构数组

+ +

变量声明并赋值时的解构

+ +
var foo = ["one", "two", "three"];
+
+var [one, two, three] = foo;
+console.log(one); // "one"
+console.log(two); // "two"
+console.log(three); // "three"
+ +

变量先声明后赋值时的解构

+ +

通过解构分离变量的声明,可以为一个变量赋值。

+ +
var a, b;
+
+[a, b] = [1, 2];
+console.log(a); // 1
+console.log(b); // 2
+ +

默认值

+ +

为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值。

+ +
var a, b;
+
+[a=5, b=7] = [1];
+console.log(a); // 1
+console.log(b); // 7
+ +

交换变量

+ +

在一个解构表达式中可以交换两个变量的值。

+ +

没有解构赋值的情况下,交换两个变量需要一个临时变量(或者用低级语言中的XOR-swap技巧)。

+ +
var a = 1;
+var b = 3;
+
+[a, b] = [b, a];
+console.log(a); // 3
+console.log(b); // 1
+ +

解析一个从函数返回的数组

+ +

从一个函数返回一个数组是十分常见的情况。解构使得处理返回值为数组时更加方便。

+ +

在下面例子中,要让 [1, 2] 成为函数的 f() 的输出值,可以使用解构在一行内完成解析。

+ +
function f() {
+  return [1, 2];
+}
+
+var a, b;
+[a, b] = f();
+console.log(a); // 1
+console.log(b); // 2
+
+ +

忽略某些返回值

+ +

你也可以忽略你不感兴趣的返回值:

+ +
function f() {
+  return [1, 2, 3];
+}
+
+var [a, , b] = f();
+console.log(a); // 1
+console.log(b); // 3
+ +

你也可以忽略全部返回值:

+ +
[,,] = f();
+
+ +

将剩余数组赋值给一个变量

+ +

当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。

+ +
var [a, ...b] = [1, 2, 3];
+console.log(a); // 1
+console.log(b); // [2, 3]
+ +

注意:如果剩余元素右侧有逗号,会抛出 {{jsxref("SyntaxError")}},因为剩余元素必须是数组的最后一个元素。

+ +
var [a, ...b,] = [1, 2, 3];
+// SyntaxError: rest element may not have a trailing comma
+ +

用正则表达式匹配提取值

+ +

用正则表达式的 exec() 方法匹配字符串会返回一个数组,该数组第一个值是完全匹配正则表达式的字符串,然后的值是匹配正则表达式括号内内容部分。解构赋值允许你轻易地提取出需要的部分,忽略完全匹配的字符串——如果不需要的话。

+ +
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"
+
+ +

解构对象

+ +

基本赋值

+ +
var o = {p: 42, q: true};
+var {p, q} = o;
+
+console.log(p); // 42
+console.log(q); // true
+
+ +

无声明赋值

+ +

一个变量可以独立于其声明进行解构赋值。

+ +
var a, b;
+
+({a, b} = {a: 1, b: 2});
+
+ +
+

注意:赋值语句周围的圆括号 ( ... ) 在使用对象字面量无声明解构赋值时是必须的。

+ +

{a, b} = {a: 1, b: 2} 不是有效的独立语法,因为左边的 {a, b} 被认为是一个块而不是对象字面量。

+ +

然而,({a, b} = {a: 1, b: 2}) 是有效的,正如 var {a, b} = {a: 1, b: 2}

+ +

你的 ( ... ) 表达式之前需要有一个分号,否则它可能会被当成上一行中的函数执行。

+
+ +

给新的变量名赋值

+ +

可以从一个对象中提取变量并赋值给和对象属性名不同的新的变量名。

+ +
var o = {p: 42, q: true};
+var {p: foo, q: bar} = o;
+
+console.log(foo); // 42
+console.log(bar); // true 
+ +

默认值

+ +

变量可以先赋予默认值。当要提取的对象没有对应的属性,变量就被赋予默认值。

+ +
var {a = 10, b = 5} = {a: 3};
+
+console.log(a); // 3
+console.log(b); // 5
+
+ +

给新的变量命名并提供默认值

+ +

一个属性可以同时 1)从一个对象解构,并分配给一个不同名称的变量 2)分配一个默认值,以防未解构的值是 undefined

+ +
var {a:aa = 10, b:bb = 5} = {a: 3};
+
+console.log(aa); // 3
+console.log(bb); // 5
+
+ +

函数参数默认值

+ +

ES5 版本

+ +
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
+});
+ +

ES2015 版本

+ +
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
+});
+ +
+

在上面的 drawES2015Chart 的函数签名中,解构的左手边被分配给右手边的空对象字面值:{size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}。你也可以在没有右侧分配的情况下编写函数。但是,如果你忽略了右边的赋值,那么函数会在被调用的时候查找至少一个被提供的参数,而在当前的形式下,你可以直接调用 drawES2015Chart() 而不提供任何参数。如果你希望能够在不提供任何参数的情况下调用该函数,则当前的设计非常有用,而另一种方法在您确保将对象传递给函数时非常有用。

+
+ +

解构嵌套对象和数组

+ +
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"
+ +

For of 迭代和解构

+ +
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"
+ +

从作为函数实参的对象中提取数据

+ +
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"
+ +

这段代码从user对象中提取并输出iddisplayName 和 firstName

+ +

对象属性计算名和解构

+ +

计算属性名,如 object literals,可以被解构。

+ +
let key = "z";
+let { [key]: foo } = { z: "bar" };
+
+console.log(foo); // "bar"
+
+ +

对象解构中的 Rest

+ +

Rest/Spread Properties for ECMAScript 提案(阶段 4)将 rest 语法添加到解构中。Rest 属性收集那些尚未被解构模式拾取的剩余可枚举属性键。

+ +
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
+a; // 10
+b; // 20
+rest; // { c: 30, d: 40 }
+ +

无效的 JavaScript 标识符作为属性名称

+ +

通过提供有效的替代标识符,解构可以与不是有效的JavaScript标识符的属性名称一起使用。

+ +
const foo = { 'fizz-buzz': true };
+const { 'fizz-buzz': fizzBuzz } = foo;
+
+console.log(fizzBuzz); // "true"
+
+ +

解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)

+ +
// 声明对象 和 自身 self 属性
+var obj = {self: '123'};
+// 在原型链中定义一个属性 prot
+obj.__proto__.prot = '456';
+// test
+const {self, prot} = obj;
+// self "123"
+// prot "456"(访问到了原型链)
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.destructuring")}}

+ +

相关链接

+ + + +

译者注:关于 42

+ +

为什么在示例代码中出现了那么多 42?如果有什么特别的原因的话,以下是译者的猜测。

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

除法运算符 (/) 计算了两个操作数的商,左边的数是被除数,右边的是除数

+ +
{{EmbedInteractiveExample("pages/js/expressions-division.html")}}
+ +
+ + + +

语法

+ +
Operator: x / y
+
+ +

例子

+ +

基本除法

+ +
1 / 2              // 0.5
+
+Math.floor(3 / 2) // 1
+
+1.0 / 2.0         // 0.5
+
+ +

除以0

+ +
2.0 / 0     // Infinity
+
+2.0 / 0.0   // Infinity, because 0.0 === 0
+
+2.0 / -0.0  // -Infinity
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Division operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.division")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The division assignment operator (/=) divides a variable by the value of the right operand and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-division-assignment.html")}}
+ + + +

语法

+ +
Operator: x /= y
+Meaning:  x  = x / y
+ +

Examples

+ +

Using division assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= 'foo' // NaN
+bar /= 0     // Infinity
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.division_assignment")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

求幂运算符(**)返回将第一个操作数加到第二个操作数的幂的结果。它等效于Math.pow,不同之处在于它也接受BigInts作为操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-exponentiation.html")}}
+ + + +

语法

+ +
Operator: var1 ** var2
+
+ +

简介

+ +

求幂运算符是是右结合的a ** b ** c 等于 a ** (b ** c).

+ +

在大多数语言里,比如PHP、Python等那些有一个幂运算符 (**) 的语言,幂运算符被定义有一个比一元运算符,比如一元的 + 和一元的 - 更高的运算顺序,但有一些例外。在Bash语言里,** 运算符被定义有一个比一元运算符更低的运算顺序。

+ +

在JavaScript里,你不可能写出一个不明确的求幂表达式。这就是说,你不能立刻将一个一元运算符(+/-/~/!/delete/void/typeof)放在基数前,这样做只会导致一个语法错误。

+ +
-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.
+
+ +

注意有些编程语言用扬抑符 ^ 做乘方运算,但是JavaScript将这个符号作为了XOR位逻辑运算符

+ +

例子

+ +

基本求幂

+ +
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
+ +

与一元运算符的用法

+ +

取求幂表达式的值的相反数:

+ +
-(2 ** 2) // -4
+
+ +

将求幂表达式的底数转化为一个负数:

+ +
(-2) ** 2 // 4
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-exp-operator', 'Exponentiation operator')}}
+ +

浏览器支持

+ + + +

{{Compat("javascript.operators.exponentiation")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

The exponentiation assignment operator (**=) raises the value of a variable to the power of the right operand.

+ +
{{EmbedInteractiveExample("pages/js/expressions-exponentiation-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x **= y
+Meaning:  x  = x ** y
+ +

Examples

+ +

Using exponentiation assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar **= 2     // 25
+bar **= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.exponentiation_assignment")}}

+ +

See also

+ + + +

+ +

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 +--- +
非标准,不要使用!
+闭包表达式语法是废弃的 SpiderMonkey 的特性,并且将被移除。为了长远使用,考虑使用箭头函数
+ +
{{jsSidebar("Operators")}}
+ +

表达式闭包是定义简单函数的一种便捷方式。

+ +

语法

+ +
function [name]([param1[, param2[, ..., paramN]]])
+   expression
+
+ +

参数

+ +
+
name
+
函数名。函数名可以省略不写,称为匿名函数。函数名仅在函数体有效。
+
paramN
+
形参名。一个函数最多可以有255个参数。
+
expression
+
构成函数体的表达式。
+
+ +

描述

+ +

这一附加特性只是编写简单函数的快捷方式,让语言更类似通常的 Lambda 标记

+ +

JavaScript 1.7 及之前版本:

+ +
function(x) { return x * x; }
+ +

JavaScript 1.8:

+ +
function(x) x * x
+ +

该语法支持省略花括号和'return'语句。使用这种编码的目的只是为了在句法上使得代码更加简化,但除此之外没有其他好处。

+ +

示例

+ +

一种绑定事件监听器的便捷方式:

+ +
 document.addEventListener("click", function() false, true);
+
+ +

在 JavaScript 1.6 中的一些数组函数中使用该标记:

+ +
elems.some(function(elem) elem.type == "text");
+
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.expression_closures")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

function 关键字可以用来在一个表达式中定义一个函数。

+ +

你也可以使用 Function 构造函数和一个函数声明来定义函数。

+ +

语法

+ +
let function_expression = function [name]([param1[, param2[, ..., paramN]]]) {
+   statements
+};
+ +

ES2015开始,你也可以使用箭头函数

+ +

参数

+ +
+
name
+
函数名称。可被省略,此种情况下的函数是匿名函数(anonymous)。 函数名称只是函数体中的一个本地变量。
+
paramN
+
被传递给函数的一个参数名称。一个函数至多拥有 255 个参数。
+
statements
+
构成函数体的语句。
+
+ +

描述

+ +

函数表达式(function expression)非常类似于函数声明(function statement)(详情查看函数声明,并且两者拥有几乎相同的语法。函数表达式与函数声明的最主要区别是函数名称(function name),在函数表达式中可省略它,从而创建匿名函数(anonymous functions)。一个函数表达式可以被用作一个IIFE(Immediately Invoked Function Expression,即时调用的函数表达式),它一旦定义就运行。更多信息请查看函数

+ +

 函数表达式提升 (Function expression hoisting)

+ +

JavaScript中的函数表达式没有提升,不像函数声明,你在定义函数表达式之前不能使用函数表达式:

+ +
 notHoisted(); // TypeError: notHoisted is not a function
+
+var notHoisted = function() {
+   console.log('bar');
+};
+ +

命名函数表达式(Named function expression)

+ +

如果你想在函数体内部引用当前函数,则需要创建一个命名函数表达式。然后函数名称将会(且只会)作为函数体(作用域内)的本地变量。这样也可以避免使用非标准的 arguments.callee 属性。

+ +
var math = {
+  'factorial': function factorial(n) {
+    if (n <= 1)
+      return 1;
+    return n * factorial(n - 1);
+  }
+};
+
+ +

被函数表达式赋值的那个变量会有一个name属性,如果你把这个变量赋值给另一个变量的话,这个name属性的值也不会改变。如果函数是一个匿名函数,那name属性的值就是被赋值的变量的名称(隐藏值)。如果函数不是匿名的话,那name属性的值就是这个函数的名称(显性值)。这对于箭头函数也同样适用(箭头函数没有名字,所以你只能赋予name属性一个隐性名)。

+ +
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)
+
+ +

示例

+ +

下面的例子定义了一个匿名函数并把它赋值给变量x。这个函数返回它参数的平方:

+ +
var x = function(y) {
+   return y * y;
+};
+ +

更多情况下被当作回调函数使用:

+ +
button.addEventListener('click', function(event) {
+    console.log('button is clicked!')
+})
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES3', '#sec-13', 'Function definition')}}Standard初始定义。JavaScript 1.5 实现。
{{SpecName('ES5.1', '#sec-13', 'Function definition')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-definitions', 'Function defintions')}}{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + 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* +--- +
{{jsSidebar("Operators")}}
+ +

function*关键字可以在表达式内部定义一个生成器函数。

+ +

{{EmbedInteractiveExample("pages/js/expressions-functionasteriskexpression.html")}}

+ +

语法

+ +
function* [name]([param1[, param2[, ..., paramN]]]) {
+   statements
+}
+ +

参数

+ +
+
name
+
函数名。在声明匿名函数时可以省略。函数名称只是函数体中的一个本地变量。
+
paramN
+
传入函数的一个参数名。一个函数最多有 255 个参数。
+
statements
+
函数体。
+
+ +

描述

+ +

function*表达式和{{jsxref('Statements/function*', 'function* 声明')}}比较相似,并具有几乎相同的语法。function*表达式和function*声明之间主要区别就是函数名,即在创建匿名函数时,function*表达式可以省略函数名。阅读{{jsxref('Function', '函数')}}章节了解更多信息。

+ +

示例

+ +

下面的示例定义了一个未命名的生成器函数并把它赋值给x。函数产出它的传入参数的平方:

+ +
var x = function*(y) {
+   yield y * y;
+};
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'function*')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'function*')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.function_star")}}

+ +

相关链接

+ + 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 +--- +
非标准的。不要使用!
+generator推导式是非标准的,而且它不太可能会被添加到ECMAScript。考虑到将来,请使用 {{jsxref("Statements/function*", "generator", "", 1)}}。 +

 

+
+ +

{{jsSidebar("Operators")}}

+ +

生成器推导语法是一种JavaScript表达式,它允许您基于现有的可迭代对象快速组合新的生成器函数。

+ +

许多编程语言中都存在推导。

+ +

看下面,原来Generator推导式语法在SpiderMonkey的不同之处,它是基于对ECMAScript4的提议。

+ +

语法

+ +
(for (x of iterable) x)
+(for (x of iterable) if (condition) x)
+(for (x of iterable) for (y of iterable) x + y)
+
+ +

描述

+ +

在Generator推导式中,这两种构成方式都是允许的:

+ + + +

for-of迭代器是构成的第一个部分。当由多重部分构成时,后面for-of和if构成方式都是被允许的。

+ +

示例

+ +

单个构成部分的 generator推导式:

+ +
(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"
+
+
+ +

有if伴随的多重构成的gennerator推导式:

+ +
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
+
+ +

Generator推导式与Generator函数对比

+ +

用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。

+ +

Example 1: 仅是 generator.

+ +
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 ]
+
+ +

Example 2: 在 generator 中用if.

+ +
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 ]
+ +

规范

+ +

Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{ CompatGeckoDesktop("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

SpiderMonkey的具体实现笔记

+ + + +

与旧的JS1.7 / JS1.8理解的区别

+ + + +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

当左边操作数大于右边的时候,大于(>) 运算符返回true,否则返回false

+ +
{{EmbedInteractiveExample("pages/js/expressions-greater-than.html")}}
+ + + +

语法

+ +
x > y
+ +

描述

+ +

操作数之间按照 Abstract Relational Comparison 算法进行比较。进一步了解该算法,请参考 小于 运算符的相关文档.

+ +

例子

+ +

字符串的比较

+ +
console.log("a" > "b");        // false
+console.log("a" > "a");        // false
+console.log("a" > "3");        // true
+ +

字符串和数字的比较

+ +
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
+ +

数字间的比较

+ +
console.log(5 > 3);            // true
+console.log(3 > 3);            // false
+console.log(3 > 5);            // false
+ +

数字和 BigInt 数据的比较

+ +
console.log(5n > 3);           // true
+console.log(3 > 5n);           // false
+ +

Boolean, null, undefined, NaN的比较

+ +
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
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.greater_than")}}

+ +

参考

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The greater than or equal operator (>=) returns true if the left operand is greater than or equal to the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-greater-than-or-equal.html")}}
+ + + +

Syntax

+ +
 x >= y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm. See the documentation for the Less than operator for a summary of this algorithm.

+ +

Examples

+ +

String to string comparison

+ +
console.log("a" >= "b");     // false
+console.log("a" >= "a");     // true
+console.log("a" >= "3");     // true
+
+ +

String to number comparison

+ +
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
+ +

Number to Number comparison

+ +
console.log(5 >= 3);         // true
+console.log(3 >= 3);         // true
+console.log(3 >= 5);         // false
+ +

Number to BigInt comparison

+ +
console.log(5n >= 3);        // true
+console.log(3 >= 3n);        // true
+console.log(3 >= 5n);        // false
+ +

Comparing Boolean, null, undefined, NaN

+ +
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
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.greater_than_or_equal")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

圆括号运算符 ( ) 用于控制表达式中的运算优先级。

+ +
{{EmbedInteractiveExample("pages/js/expressions-groupingoperator.html")}}
+ + + +

语法

+ +

译者:下列语法是 MDN 上已知的最简单的之一。

+ +
 ( )
+ +

说明

+ +

圆括号运算符由一对圆括号组成,包裹表达式和子表达式用来覆盖常规的运算符优先级,达到低优先级的表达式比高优先级的表达式更早运算。

+ +

示例

+ +

下面的代码展示了加法运算先于乘法运算的情况。

+ +
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
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-grouping-operator', 'The Grouping Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-grouping-operator', 'The Grouping Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.1.6', 'The Grouping Operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.1.4', 'The Grouping Operator')}}{{Spec2('ES1')}}初始化定义.在JavaScript1.0中生效
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.grouping")}}

+ +

相关链接

+ + 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 +--- +

{{jsSidebar("Operators")}}

+ +

如果指定的属性在指定的对象或其原型链中,则in 运算符返回true

+ +
{{EmbedInteractiveExample("pages/js/expressions-inoperator.html")}}
+ + + +

语法

+ +
prop in object
+ +

参数

+ +
+
prop
+
一个字符串类型或者 symbol 类型的属性名或者数组索引(非symbol类型将会强制转为字符串)。
+
+ +
+
objectName
+
检查它(或其原型链)是否包含具有指定名称的属性的对象。
+
+ +

描述

+ +

下面的例子演示了一些 in 运算符的用法。

+ +
// 数组
+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
+
+ +

in右操作数必须是一个对象值。例如,你可以指定使用String构造函数创建的字符串,但不能指定字符串文字。

+ +
var color1 = new String("green");
+"length" in color1 // 返回true
+var color2 = "coral";
+"length" in color2 // 报错(color2不是对象)
+
+ +

对被删除或值为 undefined 的属性使用in

+ +

如果你使用 delete 运算符删除了一个属性,则 in 运算符对所删除属性返回 false

+ +
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
+
+ +

如果你只是将一个属性的值赋值为{{jsxref("Global_Objects/undefined", "undefined")}},而没有删除它,则 in 运算仍然会返回true

+ +
var mycar = {make: "Honda", model: "Accord", year: 1998};
+mycar.make = undefined;
+"make" in mycar;  // 返回true
+
+ +
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+trees[3] = undefined;
+3 in trees; // 返回true
+
+ +

继承属性

+ +

如果一个属性是从原型链上继承来的,in 运算符也会返回 true

+ +
"toString" in {}; // 返回true
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.8.7', 'The in Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.8.7', 'The in Operator')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.in")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

自增运算符 (++) 将其操作数递增(加1)并返回一个值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-increment.html")}}
+ + + +

语法

+ +
Operator: x++ or ++x
+
+ +

描述

+ +

如使用后置(Postfix)自增,操作符在操作数后(例如  x++), 操作数将在自增前返回。

+ +

如使用前置(Prefix)自增,操作符在操作数前(例如 ++x), 操作数将先自增后返回。

+ +

示例

+ +

后置自增(Postfix increment)

+ +
let x = 3;
+y = x++;
+
+// y = 3
+// x = 4
+
+ +

前置自增(Prefix increment)

+ +
let a = 2;
+b = ++a;
+
+// a = 3
+// b = 3
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-postfix-increment-operator', 'Increment operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.increment")}}

+ +

相关链接

+ + + +
+
+
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 +--- +

{{jsSidebar("Operators")}}
+ 该章节说明了JavaScript语言所有的运算符,表达式和关键字。

+ +

表达式和运算符分类

+ +

左侧工具栏是按字母表排序的列表。

+ +

主要表达式

+ +

JavaScript中基本关键字和常用表达式。

+ +
+
{{jsxref("Operators/this", "this")}}
+
this 关键字指向函数的执行上下文。
+
{{jsxref("Operators/function", "function")}}
+
function 关键字定义了函数表达式。
+
{{jsxref("Operators/class", "class")}}
+
class 关键字定义了类表达式。
+
{{jsxref("Operators/function*", "function*")}}
+
function* 关键字定义了一个 generator 函数表达式。
+
{{jsxref("Operators/yield", "yield")}}
+
暂停和恢复 generator 函数。
+
{{jsxref("Operators/yield*", "yield*")}}
+
委派给另外一个generator函数或可迭代的对象。
+
{{jsxref("Operators/async_function", "async function")}}
+
async function 定义一个异步函数表达式。
+
{{jsxref("Operators/await", "await")}}
+
暂停或恢复执行异步函数,并等待promise的resolve/reject回调。
+
{{jsxref("Global_Objects/Array", "[]")}}
+
数组初始化/字面量语法。
+
{{jsxref("Operators/Object_initializer", "{}")}}
+
对象初始化/字面量语法。
+
{{jsxref("Global_Objects/RegExp", "/ab+c/i")}}
+
正则表达式字面量语法。
+
{{jsxref("Operators/Grouping", "( )")}}
+
分组操作符。
+
+ +

左表达式

+ +

左边的值是赋值的目标。

+ +
+
{{jsxref("Operators/Property_accessors", "属性访问符", "", 1)}}
+
成员运算符提供了对对象的属性或方法的访问
+ (object.property 和 object["property"]).
+
{{jsxref("Operators/new", "new")}}
+
new 运算符创建了构造函数实例。
+
{{JSxRef("Operators/new%2Etarget", "new.target")}}
+
在构造器中,new.target 指向{{jsxref("Operators/new", "new")}}调用的构造器。
+
{{jsxref("Operators/super", "super")}}
+
super 关键字调用父类的构造器.
+
{{jsxref("Operators/Spread_operator", "...obj")}}
+
展开运算符可以将一个可迭代的对象在函数调用的位置展开成为多个参数,或者在数组字面量中展开成多个数组元素。
+
+ +

自增和自减

+ +

前置/后置自增运算符和前置/后置自减运算符.

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "A++", "#Increment")}}
+
后置自增运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "A--", "#Decrement")}}
+
后置自减运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "++A", "#Increment")}}
+
前置自增运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "--A", "#Decrement")}}
+
前置自减运算符.
+
+ +

一元运算符

+ +

一元运算符只有一个操作数.

+ +
+
{{jsxref("Operators/delete", "delete")}}
+
delete 运算符用来删除对象的属性.
+
{{jsxref("Operators/void", "void")}}
+
void 运算符表示表达式放弃返回值.
+
{{jsxref("Operators/typeof", "typeof")}}
+
typeof 运算符用来判断给定对象的类型.
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}
+
一元加运算符将操作转换为Number类型.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}
+
一元减运算符将操作转换为Number类型并取反.
+
{{jsxref("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}
+
按位非运算符.
+
{{jsxref("Operators/Logical_Operators", "!", "#Logical_NOT")}}
+
逻辑非运算符.
+
+ +

算术运算符

+ +

算术运算符以二个数值(字面量或变量)作为操作数,并返回单个数值。

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Addition")}}
+
加法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Subtraction")}}
+
减法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "/", "#Division")}}
+
除法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "*", "#Multiplication")}}
+
乘法运算符.
+
{{jsxref("Operators/Arithmetic_Operators", "%", "#Remainder")}}
+
取模运算符.
+
+ +

关系运算符

+ +

比较运算符比较二个操作数并返回基于比较结果的Boolean值。

+ +
+
{{jsxref("Operators/in", "in")}}
+
in运算符用来判断对象是否拥有给定属性.
+
{{jsxref("Operators/instanceof", "instanceof")}}
+
instanceof 运算符判断一个对象是否是另一个对象的实例.
+
{{jsxref("Operators/Comparison_Operators", "<", "#Less_than_operator")}}
+
小于运算符
+
{{jsxref("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}
+
大于运算符.
+
{{jsxref("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}
+
小于等于运算符.
+
{{jsxref("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}
+
大于等于运算符。 
+
+ +
注意: => 不是运算符,而是{{jsxref("Functions/Arrow_functions", "箭头函数")}}的表示符。
+ +

相等运算符

+ +

如果相等,操作符返回的是Boolean(布尔)类型的true,否则是false。

+ +
+
{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}}
+
相等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "!=", "#Inequality")}}
+
不等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}}
+
全等 运算符.
+
{{jsxref("Operators/Comparison_Operators", "!==", "#Nonidentity")}}
+
非全等 运算符.
+
+ +

位移运算符

+ +

在二进制的基础上对数字进行移动操作

+ +
+
{{jsxref("Operators/Bitwise_Operators", "<<", "#Left_shift")}}
+
按位左移运算符。
+
{{jsxref("Operators/Bitwise_Operators", ">>", "#Right_shift")}}
+
按位右移运算符。
+
{{jsxref("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}
+
按位无符号右移运算符。
+
+ +

二进制位运算符

+ +

二进制运算符将它们的操作数作为32个二进制位(0或1)的集合,并返回标准的JavaScript数值。

+ +
+
{{jsxref("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}
+
二进制位与(AND)。
+
{{jsxref("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}
+
二进制位或(OR)。
+
{{jsxref("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}
+
二进制位异或(XOR)。
+
+ +

二元逻辑运算符

+ +

逻辑运算符典型的用法是用于boolean(逻辑)值运算, 它们返回boolean值。

+ +
+
{{jsxref("Operators/Logical_Operators", "&&", "#Logical_AND")}}
+
逻辑与.
+
{{jsxref("Operators/Logical_Operators", "||", "#Logical_OR")}}
+
逻辑或.
+
{{JSxRef("Operators/Nullish_coalescing_operator", "??")}}
+
空值合并运算符 , 如果 ?? 前面是 null 或 undefined ,取后面的默认值
+
+ +

条件(三元)运算符

+ +
+
{{jsxref("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}
+
+

条件元素运算符把两个结果中其中一个符合运算逻辑的值返回。

+
+
+ +

赋值运算符

+ +

赋值元素符会将右边的操作数的值分配给左边的操作数,并将其值修改为右边操作数相等的值。

+ +
+
{{jsxref("Operators/Assignment_Operators", "=", "#Assignment")}}
+
赋值运算符。
+
{{jsxref("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}
+
赋值乘积。
+
{{jsxref("Operators/Assignment_Operators", "/=", "#Division_assignment")}}
+
赋值商。
+
{{jsxref("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}
+
赋值求余。
+
{{jsxref("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}
+
赋值求和。
+
{{jsxref("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}
+
赋值求差。
+
{{jsxref("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}
+
左位移。
+
{{jsxref("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}
+
右位移。
+
{{jsxref("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}
+
无符号右位移。
+
{{jsxref("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}
+
赋值与。
+
{{jsxref("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}
+
赋值按位异或。
+
{{jsxref("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}
+
赋值或。
+
{{jsxref("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}
+ {{jsxref("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}
+
+

解构赋值允许你分配数组或者对象变量的属性通过使用规定的语法,其看起来和数组和对象字面量很相似。

+
+
+

逗号操作符

+
+
{{jsxref("Operators/Comma_Operator", ",")}}
+
逗号操作符允许在一个判断状态中有多个表达式去进行运算并且最后返回最后一个表达式的值。
+
+

非标准化特性

+
+
{{JSxRef("Operators/Expression_closures", "Expression closures", "", 1)}} {{non-standard_inline}}{{obsolete_inline(60)}}
+
闭包表达式语法是一个缩写简单的函数。
+
{{JSxRef("Operators/Legacy_generator_function", "Legacy generator function", "", 1)}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
function关键字能用来定义表达式内部未执行完的function的余下功能。 为了能执行function内部余下的代码, 这个function的内部至少包含一个{{jsxref("Operators/yield", "yield")}} 表达式。
+
{{JSxRef("Operators/Array_comprehensions", "[for (x of y) x]")}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
数组解析
+
{{JSxRef("Operators/Generator_comprehensions", "(for (x of y) y)")}} {{non-standard_inline}}{{obsolete_inline(58)}}
+
生成器解析
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1', '#sec-11', 'Expressions')}}{{Spec2('ES1')}}Initial definition
{{SpecName('ES5.1', '#sec-11', 'Expressions')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ES6')}}New: Spread syntax, rest syntax, destructuring assignment, super keyword.
{{SpecName('ESDraft', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

不等于运算符 (!=) 检查其两个操作数是否不相等,并返回布尔结果。 与严格的不等式运算符不同,它尝试转换和比较不同类型的操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-inequality.html")}}
+ + + +

语法

+ +
x != y
+ +

描述

+ +

不等式运算符检查其操作数是否不相等。这是等于运算符的取反,因此以下两行将始终给出相同的结果: 

+ +
x != y
+
+!(x == y)
+ +

有关比较算法的详细信息,请参见等于运算符的页面

+ +

与等于运算符一样,不等于运算符将尝试转换和比较不同类型的操作数:

+ +
3 != "3"; // false
+ +

为避免这种情况,并要求将不同类型视为不同,请使用严格的不等于运算符:

+ +
3 !== "3"; // true
+ +

例子

+ +

没有类型转换的比较

+ +
1 != 2;              // true
+"hello" != "hola";   // true
+
+1 != 1;              // false
+"hello" != "hello";  // false
+ +

与类型转换比较

+ +
"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
+ +

对象比较

+ +
const object1 = {"key": "value"}
+const object2 = {"key": "value"};
+
+object1 != object2 // true
+object2 != object2 // false
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.inequality")}}

+ +

参见

+ + + +
+
+
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 +--- +
{{jsSidebar("Operators")}}
+ +

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

+ +
{{EmbedInteractiveExample("pages/js/expressions-instanceof.html")}}
+ + + +

语法

+ +
object instanceof constructor
+ +

参数

+ +
+
object
+
某个实例对象
+
+ +
+
constructor
+
某个构造函数
+
+ +

描述

+ +

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

+ +
// 定义构造函数
+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 的原型链上
+
+ +

需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。比如执行 obj.__proto__ = {} 之后,obj instanceof Foo 就会返回 false 了。

+ +

instanceof 和多全局对象(例如:多个 frame 或多个 window 之间的交互)

+ +

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回 false,因为 Array.prototype !== window.frames[0].Array.prototype,并且数组从前者继承。

+ +

起初,你会认为这样并没有意义,但是当你在你的脚本中开始处理多个 frame 或多个 window 以及通过函数将对象从一个窗口传到另一个窗口时,这就是一个有效而强大的话题。比如,实际上你可以通过使用Array.isArray(myObj) 或者Object.prototype.toString.call(myObj) === "[object Array]" 来安全的检测传过来的对象是否是一个数组。

+ +

比如检测一个 Nodes 在另一个窗口中是不是 SVGElement,你可以使用myNode instanceof myNode.ownerDocument.defaultView.SVGElement

+ +
Mozilla开发者注意:
+在代码中使用 XPCOM instanceof 有特殊影响: 如果查询接口成功执行后,obj instanceof xpcomInterface (e.g. Components.interfaces.nsIFile) 调用obj.QueryInterface(xpcomInterface) 并且返回 true 。这种调用的副作用是在一次成功的 instanceof 测试后,你可以在 obj 上使用xpcomInterface 的属性。这与标准的 JavaScript 全局变量不同,即使 obj 来自不同的作用域,obj instanceof xpcomInterface 也可以按预期产生作用。
+ +

示例

+ +

演示 String 对象和 Date 对象都属于 Object 类型和一些特殊情况

+ +

下面的代码使用了 instanceof 来证明:String 和 Date 对象同时也属于Object 类型(他们是由 Object 类派生出来的)。

+ +

但是,使用对象文字符号创建的对象在这里是一个例外:虽然原型未定义,但 instanceof Object 返回 true

+ +
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
+ +

演示 mycar 属于 Car 类型的同时又属于 Object 类型

+ +

下面的代码创建了一个类型 Car,以及该类型的对象实例 mycar. instanceof 运算符表明了这个 mycar 对象既属于 Car 类型,又属于 Object 类型。

+ +
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
+
+
+ +

不是...的实例

+ +

要检测对象不是某个构造函数的实例时,你可以这样做

+ +
if (!(mycar instanceof Car)) {
+  // Do something, like mycar = new Car(mycar)
+}
+ +

这和以下代码完全不同

+ +
if (!mycar instanceof Car)
+ +

这段代码永远会得到 false!mycar 将在 instanceof 之前被处理,所以你总是在验证一个布尔值是否是 Car 的一个实例)。

+ +

相关规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.8.6', 'The instanceof operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.8.6', 'The instanceof operator')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.4.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.instanceof")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

左移操作符 (<<) 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。

+ +
{{EmbedInteractiveExample("pages/js/expressions-left-shift.html")}}
+ + + +

语法

+ +
a << b
+
+ +

描述

+ +

左移操作符将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零。

+ +

例如, 9 << 2 得出 36:

+ +
.    9 (十进制): 00000000000000000000000000001001 (二进制)
+                  --------------------------------
+9 << 2 (十进制): 00000000000000000000000000100100 (二进制) = 36 (十进制)
+
+ +

移动任意数字 x 至左边 y 位,得出 x * 2 ** y 。
+ 所以例如:9 << 3 等价于 9 * 2³ = 9 * 8 = 72

+ +

例子

+ +

使用左移

+ +
9 << 3; // 72
+
+// 9 * 2³ = 9 * 8 = 72
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.left_shift")}}

+ +

参见

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

The left shift assignment operator (<<=) moves the specified amount of bits to the left and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-left-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x <<= y
+Meaning:  x   = x << y
+ +

Examples

+ +

Using left shift assignment

+ +
let a = 5;
+// 00000000000000000000000000000101
+
+a <<= 2; // 20
+// 00000000000000000000000000010100
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.left_shift_assignment")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

The less than operator (<) returns true if the left operand is less than the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-less-than.html")}}
+ + + +

语法

+ +
 x < y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm, which is roughly summarised below:

+ + + +

Examples

+ +

String to string comparison

+ +
console.log("a" < "b");        // true
+console.log("a" < "a");        // false
+console.log("a" < "3");        // false
+ +

String to number comparison

+ +
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
+ +

Number to Number comparison

+ +
console.log(5 < 3);            // false
+console.log(3 < 3);            // false
+console.log(3 < 5);            // true
+ +

Number to BigInt comparison

+ +
console.log(5n < 3);           // false
+console.log(3 < 5n);           // true
+ +

Comparing Boolean, null, undefined, NaN

+ +
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
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.less_than")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The less than or equal operator (<=) returns true if the left operand is less than or equal to the right operand, and false otherwise.

+ +
{{EmbedInteractiveExample("pages/js/expressions-less-than-or-equal.html")}}
+ + + +

Syntax

+ +
 x <= y
+ +

Description

+ +

The operands are compared using the Abstract Relational Comparison algorithm. See the documentation for the Less than operator for a summary of this algorithm.

+ +

Examples

+ +

String to string comparison

+ +
console.log("a" <= "b");     // true
+console.log("a" <= "a");     // true
+console.log("a" <= "3");     // false
+
+ +

String to number comparison

+ +
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
+ +

Number to Number comparison

+ +
console.log(5 <= 3);         // false
+console.log(3 <= 3);         // true
+console.log(3 <= 5);         // true
+ +

Number to BigInt comparison

+ +
console.log(5n <= 3);        // false
+console.log(3 <= 3n);        // true
+console.log(3 <= 5n);        // true
+ +

Comparing Boolean, null, undefined, NaN

+ +
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
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.less_than_or_equal")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The logical AND assignment (x &&= y) operator only assigns if x is {{Glossary("truthy")}}.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-and-assignment.html")}}
+ + + +

语法

+ +
expr1 &&= expr2
+
+ +

描述

+ +

Short-circuit evaluation

+ +

The logical AND operator is evaluated left to right, it is tested for possible short-circuit evaluation using the following rule:

+ +

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place).

+ +

Logical AND assignment short-circuits as well meaning that x &&= y is equivalent to:

+ +
x && (x = y);
+ +

And not equivalent to the following which would always perform an assignment:

+ +
x = x && y;
+
+ +

例子

+ +

Using logical AND assignment

+ +
let x = 0;
+let y = 1;
+
+x &&= 0; // 0
+x &&= 1; // 0
+y &&= 1; // 1
+y &&= 0; // 0
+
+ +

规范

+ + + + + + + + + + + + + + +
Specification
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_and_assignment")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The logical NOT (!) 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 false if its single operand can be converted to true; otherwise, returns true.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-not.html", "shorter")}}
+ + + +

语法

+ +
!expr
+
+ +

Description

+ +

Returns false if its single operand can be converted to true; otherwise, returns true.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the ! 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 boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Examples

+ +

Using NOT

+ +

The following code shows examples of the ! (logical NOT) operator.

+ +
n1 = !true               // !t returns false
+n2 = !false              // !f returns true
+n3 = !''                 // !f returns true
+n4 = !'Cat'              // !t returns false
+ +

Double NOT (!!)

+ +

It is possible to use a couple of NOT operators in series to explicitly force the conversion of any value to the corresponding boolean primitive. The conversion is based on the "truthyness" or "falsyness" of the value (see {{Glossary("truthy")}} and {{Glossary("falsy")}}).

+ +

The same conversion can be done through the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} function.

+ +
n1 = !!true                   // !!truthy returns true
+n2 = !!{}                     // !!truthy returns true: any object is truthy...
+n3 = !!(new Boolean(false))   // ...even Boolean objects with a false .valueOf()!
+n4 = !!false                  // !!falsy returns false
+n5 = !!""                     // !!falsy returns false
+n6 = !!Boolean(false)         // !!falsy returns false
+ +

Converting between NOTs

+ +

The following operation involving booleans:

+ +
!!bCondition
+ +

is always equal to:

+ +
bCondition
+ +

Specifications

+ + + + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-logical-not-operator', 'Logical NOT expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_not")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

逻辑空赋值运算符 (x ??= y) 仅在 x 是 {{Glossary("nullish")}} (null 或 undefined) 时对其赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-nullish-assignment.html")}}
+ + + +

语法

+ +
expr1 ??= expr2
+
+ +

描述

+ +

语法短路求值

+ +

空值合并运算符从左至右求值,其使用以下规则测试是否可能进行语法短路求值:

+ +

(结果非 null 或 undefined 的表达式) ?? expr 被短路求值为左侧表达式,当左侧证明为既非 null 也非 undefined.

+ +

语法短路意味着 expr 部分尚未被求值,因此任何与其求值产生的相关副作用都不会生效(例如,如果 expr 是一个函数调用,则该调用将不会发生)。

+ +

逻辑空赋值的语法短路也意味着 x ??= y 等价于:

+ +
x ?? (x = y);
+ +

而不等价于如下的表达式,因为其一定会发生赋值:

+ +
x = x ?? y;
+
+ +

例子

+ +

使用逻辑空赋值

+ +
function config(options) {
+  options.duration ??= 100;
+  options.speed ??= 25;
+  return options;
+}
+
+config({ duration: 125 }); // { duration: 125, speed: 25 }
+config({}); // { duration: 100, speed: 25 }
+
+ +

规范

+ + + + + + + + + + + + + + +
规范
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_nullish_assignment")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&&|| 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}
+ + + +

描述

+ +

逻辑运算符如下表所示 (其中expr可能是任何一种类型, 不一定是布尔值):

+ + + + + + + + + + + + + + + + + + + + + + + + +
运算符语法说明
逻辑与,AND(&&expr1 && expr2expr1 可转换为 true,则返回 expr2;否则,返回 expr1
逻辑或,OR(||expr1 || expr2expr1 可转换为 true,则返回 expr1;否则,返回 expr2
逻辑非,NOT(!!exprexpr 可转换为 true,则返回 false;否则,返回 true
+ +

如果一个值可以被转换为 true,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 false,那么这个值就是所谓的 {{Glossary("falsy")}}。

+ +

会被转换为 false 的表达式有:

+ + + +

尽管 &&|| 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用双重非运算符(即!!)或者Boolean构造函数。

+ +

短路计算

+ +

由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:

+ + + +

短路意味着上述表达式中的expr部分不会被执行,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:

+ +
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)
+
+ +

Operators precedence

+ +

请注意,由于运算符优先级的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。

+ +
false &&  true || true      // 结果为 true
+false && (true || true)     // 结果为 false
+
+ +

逻辑与(&&

+ +

下面的代码是 && (逻辑与) 运算符的示例.

+ +
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
+
+ +

逻辑或(||

+ +

下面的代码是 || (逻辑或) 运算符的示例。

+ +
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 返回 ""
+
+ +

逻辑非(!

+ +

下面的代码是 ! (逻辑非) 运算符的示例.

+ +
n1 = !true              // !t 返回 false
+n2 = !false             // !f 返回 true
+n3 = !''                // !f 返回 true
+n4 = !'Cat'             // !t 返回 false
+
+ +

双重非(!!)运算符

+ +

可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的布尔值。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。

+ +

同样的转换可以通过 Boolean 函数完成。

+ +
n1 = !!true                   // !!truthy 返回 true
+n2 = !!{}                     // !!truthy 返回 true: 任何 对象都是 truthy 的…
+n3 = !!(new Boolean(false))   // …甚至 .valueOf() 返回 false 的布尔值对象也是!
+n4 = !!false                  // !!falsy 返回 false
+n5 = !!""                     // !!falsy 返回 false
+n6 = !!Boolean(false)         // !!falsy 返回 false
+
+ +

布尔值转换规则

+ +

将 AND 转换为 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && bCondition2
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2)
+ +

将 OR 转换为 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || bCondition2
+ +

总是等于:

+ +
!(!bCondition1 && !bCondition2)
+ +

删除嵌套的小括号

+ +

由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。

+ +

删除嵌套的 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

总是等于:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

删除嵌套的 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.11')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ES6', '#sec-binary-logical-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ESDraft', '#sec-binary-logical-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The logical OR (||) 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 || 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.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-or.html", "shorter")}}
+ + + +

语法

+ +
expr1 || expr2
+
+ +

Description

+ +

If expr1 can be converted to true, returns expr1; else, returns expr2.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the || 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 boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Short-circuit evaluation

+ +

The logical OR expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

+ +

(some truthy expression) || expr is short-circuit evaluated to the truthy expression.

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr 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:

+ +
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)
+
+ +

Operator precedence

+ +

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

+ +
true || false && false      // returns true, because && is executed first
+(true || false) && false    // returns false, because operator precedence cannot apply
+ +

Examples

+ +

Using OR

+ +

The following code shows examples of the || (logical OR) operator.

+ +
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
+
+ +
+

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out {{jsxref("null")}} or {{jsxref("undefined")}}, consider using the nullish coalescing operator.

+
+ +

Conversion rules for booleans

+ +

Converting AND to OR

+ +

The following operation involving booleans:

+ +
bCondition1 && bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2)
+ +

Converting OR to AND

+ +

The following operation involving booleans:

+ +
bCondition1 || bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 && !bCondition2)
+ +

Removing nested parentheses

+ +

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

+ +

The following composite operation involving booleans:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

Specifications

+ + + + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-LogicalORExpression', 'Logical OR expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_or")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The logical OR assignment (x ||= y) operator only assigns if x is {{Glossary("falsy")}}.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-or-assignment.html")}}
+ + + +

 语法

+ +
expr1 ||= expr2
+
+ +

描述

+ +

Short-circuit evaluation

+ +

The logical OR operator works like this:

+ +
x || y;
+// returns x when x is truthy
+// returns y when x is not truthy
+ +

The logical OR operator short-circuits: the second operand is only evaluated if the first operand doesn’t already determine the result.

+ +

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, x ||= y is equivalent to:

+ +
x || (x = y);
+
+ +

And not equivalent to the following which would always perform an assignment:

+ +
x = x || y;
+
+ +

Note that this behavior is different to mathematical and bitwise assignment operators.

+ +

例子

+ +

Setting default content

+ +

If the "lyrics" element is empty, set the innerHTML to a default value:

+ +
document.getElementById('lyrics').innerHTML ||= '<i>No lyrics.</i>'
+ +

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.

+ +

Note: Pay attention to the value returned by the API you're checking against. If an empty string is returned (a {{Glossary("falsy")}} value), ||= must be used, otherwise you want to use the ??= operator (for {{jsxref("null")}} or {{jsxref("undefined")}} return values).

+ +

规范

+ + + + + + + + + + + + + + +
Specification
{{SpecName('Logical Assignment', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical_or_assignment")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

乘法运算符 (*) 计算操作数的乘积。

+ +
{{EmbedInteractiveExample("pages/js/expressions-multiplication.html")}}
+ +
+ + + +

语法

+ +
Operator: x * y
+
+ +

例子

+ +

使用数字相乘

+ +
 2 * 2      // 4
+-2 * 2     // -4
+
+ +

使用 Infinity 相乘

+ +
Infinity * 0         // NaN
+Infinity * Infinity  // Infinity
+ +

使用非数字相乘

+ +
'foo' * 2 // NaN
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Multiplication operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.multiplication")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The multiplication assignment operator (*=) multiplies a variable by the value of the right operand and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-multiplication-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x *= y
+Meaning:  x  = x * y
+ +

Examples

+ +

Using multiplication assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar *= 2     // 10
+bar *= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.multiplication_assignment")}}

+ +

See also

+ + 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 +--- +
{{JSSidebar("Operators")}}
+ +
new.target属性允许你检测函数或构造方法是否是通过new运算符被调用的。在通过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target 的值是{{jsxref("undefined")}}。
+ +

语法

+ +
new.target
+ +

描述

+ +

new.target语法由一个关键字"new",一个点,和一个属性名"target"组成。通常"new."作用是提供属性访问的上下文,但这里"new."其实不是一个真正的对象。不过在构造方法调用中,new.target指向被new调用的构造函数,所以"new."成为了一个虚拟上下文。

+ +

new.target属性适用于所有函数访问的元属性。在  arrow functions 中,new.target 指向最近的外层函数的new.target(An arrow function expression does not have its own this, arguments, super , or new.target) 。

+ +

示例

+ +

函数调用中的 new.target

+ +

在普通的函数调用中(和作为构造函数来调用相对),new.target的值是{{jsxref("undefined")}}。这使得你可以检测一个函数是否是作为构造函数通过new被调用的。

+ +
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"
+
+ +

构造方法中的 new.target

+ +

在类的构造方法中,new.target指向直接被new执行的构造函数。并且当一个父类构造方法在子类构造方法中被调用时,情况与之相同。

+ +
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();}}
+
+ +

从上面类 C 和 D 的例子可以看出来,new.target 指向的是初始化类的类定义。比如当 D 通过 new 初始化的时候,打印出了 D 的类定义,C 的例子与之类似,打印出的是 C 的类定义。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-built-in-function-objects', 'Built-in Function Objects')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-built-in-function-objects', 'Built-in Function Objects')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.new_target")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

+ +
    +
+ +

{{EmbedInteractiveExample("pages/js/expressions-newoperator.html")}}

+ +

语法

+ +
new constructor[([arguments])]
+ +

参数

+ +
+
constructor
+
一个指定对象实例的类型的类或函数。
+
+ +
+
arguments
+
一个用于被 constructor 调用的参数列表。
+
+ +

描述

+ +

new 关键字会进行如下的操作:

+ +
    +
  1. 创建一个空的简单JavaScript对象(即{});
  2. +
  3. 链接该对象(设置该对象的constructor)到另一个对象 ;
  4. +
  5. 将步骤1新创建的对象作为this的上下文 ;
  6. +
  7. 如果该函数没有返回对象,则返回this
  8. +
+ +

(译注:关于对象的 constructor,参见 Object.prototype.constructor

+ +

创建一个用户自定义的对象需要两步:

+ +
    +
  1. 通过编写函数来定义对象类型。
  2. +
  3. 通过 new 来创建对象实例。
  4. +
+ +

创建一个对象类型,需要创建一个指定其名称和属性的函数;对象的属性可以指向其他对象,看下面的例子:

+ +

当代码 new Foo(...) 执行时,会发生以下事情:

+ +
    +
  1. 一个继承自 Foo.prototype 的新对象被创建。
  2. +
  3. 使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
  4. +
  5. 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)
  6. +
+ +

你始终可以对已定义的对象添加新的属性。例如,car1.color = "black" 语句给 car1 添加了一个新的属性 color,并给这个属性赋值 "black"。但是,这不会影响任何其他对象。要将新属性添加到相同类型的所有对象,你必须将该属性添加到 Car 对象类型的定义中。

+ +

你可以使用 Function.prototype 属性将共享属性添加到以前定义的对象类型。这定义了一个由该函数创建的所有对象共享的属性,而不仅仅是对象类型的其中一个实例。下面的代码将一个值为 nullcolor 属性添加到 car 类型的所有对象,然后仅在实例对象 car1 中用字符串 "black" 覆盖该值。详见 prototype

+ +
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
+
+ +
+

如果你没有使用 new 运算符, 构造函数会像其他的常规函数一样被调用,不会创建一个对象在这种情况下, this 的指向也是不一样的。

+
+ +

示例

+ +

对象类型和对象实例

+ +

假设你要创建一个汽车的对象类型。你希望这个类型叫做car,这个类型具备make, model, year等属性,要做到这些,你需要写这样一个函数:

+ +
function Car(make, model, year) {
+   this.make = make;
+   this.model = model;
+   this.year = year;
+}
+
+ +

现在,你可以如下所示创建一个 mycar 的对象:

+ +
var mycar = new Car("Eagle", "Talon TSi", 1993);
+ +

这段代码创建了 mycar 并给他的属性指定值,于是 mycar.make 的值为"Eagle", mycar.year 的值为1993,以此类推。

+ +

你可以通过调用 new 来创建任意个汽车对象。例如:

+ +
var kenscar = new Car("Nissan", "300ZX", 1992);
+ +

对象属性为其他对象

+ +

假设你定义了一个对象叫做 person

+ +
function Person(name, age, sex) {
+   this.name = name;
+   this.age = age;
+   this.sex = sex;
+}
+
+ +

然后实例化两个新的 person 对象如下:

+ +
var rand = new Person("Rand McNally", 33, "M");
+var ken = new Person("Ken Jones", 39, "M");
+
+ +

然后你可以重写 car 的定义,添加一个值为 person 对象的 owner 属性,如下:

+ +
function Car(make, model, year, owner) {
+   this.make = make;
+   this.model = model;
+   this.year = year;
+   this.owner = owner;
+}
+
+ +

为了实例化新的对象,你可以用如下代码:

+ +
var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
+var car2 = new Car("Nissan", "300ZX", 1992, ken);
+
+ +

创建对象时,并没有传字符串或数字给owner,而是传了对象 randken 。这个时候,你可以这样来获取 car2 的owner的name:

+ +
car2.owner.name
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ESDraft', '#sec-new-operator', 'The new Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-new-operator', 'The new Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.2.2', 'The new Operator')}}{{Spec2('ES1')}}初始定义。JavaScript 1.0实现。
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.new")}}

+ +

参见

+ + 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 +--- +
{{JSSidebar("Operators")}}
+ +

空值合并操作符??)是一个逻辑操作符,当左侧的操作数为 {{jsxref("null")}} 或者 {{jsxref("undefined")}} 时,返回其右侧操作数,否则返回左侧操作数。

+ +

逻辑或操作符(||不同,逻辑或操作符会在左侧操作数为{{Glossary("Falsy", "假值")}}时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。

+ +
{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}
+ + + +

语法

+ +
leftExpr ?? rightExpr
+
+ +

示例

+ +

使用空值合并操作符

+ +

在这个例子中,我们使用空值合并操作符为常量提供默认值,保证常量不为 null 或者 undefined

+ +
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
+ +

为变量赋默认值

+ +

以前,如果想为一个变量赋默认值,通常的做法是使用逻辑或操作符(||):

+ +
let foo;
+
+//  foo is never assigned any value so it is still undefined
+let someDummyText = foo || 'Hello!';
+ +

然而,由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(0, '', NaN, null, undefined)都不会被返回。这导致如果你使用0''NaN作为有效值,就会出现不可预料的后果。

+ +
let count = 0;
+let text = "";
+
+let qty = count || 42;
+let message = text || "hi!";
+console.log(qty);     // 42,而不是 0
+console.log(message); // "hi!",而不是 ""
+ +

空值合并操作符可以避免这种陷阱,其只在第一个操作数为null 或 undefined 时(而不是其它假值)返回第二个操作数:

+ +
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)
+
+ +

短路

+ +

与 OR 和 AND 逻辑操作符相似,当左表达式不为 null 或 undefined 时,不会对右表达式进行求值。

+ +
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)
+// 所以右侧表达式没有被执行
+
+ +

不能与 AND 或 OR 操作符共用

+ +

将 ?? 直接与 AND(&&)和 OR(||)操作符组合使用是不可取的。(译者注:应当是因为空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的)这种情况下会抛出 SyntaxError

+ +
null || undefined ?? "foo"; // 抛出 SyntaxError
+true || undefined ?? "foo"; // 抛出 SyntaxError
+ +

但是,如果使用括号来显式表明运算优先级,是没有问题的:

+ +
(null || undefined ) ?? "foo"; // 返回 "foo"
+
+ +

与可选链式操作符(?.)的关系

+ +

空值合并操作符针对 undefined 与 null 这两个值,可选链式操作符(?. 也是如此。在这访问属性可能为 undefined 与 null 的对象时,可选链式操作符非常有用。

+ +
let foo = { someFooProp: "hi" };
+
+console.log(foo.someFooProp?.toUpperCase()); // "HI"
+console.log(foo.someBarProp?.toUpperCase()); // undefined
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#prod-Nulli', 'nullish coalescing expression')}}Stage 4
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.nullish_coalescing")}}

+ +

Implementation Progress

+ +

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 Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

+ +
{{EmbedTest262ReportResultsTable("coalesce-expression")}}
+ +

参见

+ + + +
+
+
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 +--- +
{{JsSidebar("Operators")}}
+ +

可以通过new Object() Object.create()方法,或者使用字面量标记(初始化标记)初始化对象。 一个对象初始化器,由花括号/大括号 ({}) 包含的一个由零个或多个对象属性名和其关联值组成的一个逗号分隔的列表构成。

+ +

语法

+ +
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) {}
+};
+ +

ECMAScript 2015 的新标记

+ +

请参考兼容性表格获取这些标记的支持信息。在不被支持的环境中,这些标记将造成语法错误。

+ +
// 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'
+};
+ +

描述

+ +

对象初始化是一个描述{{jsxref("Object","对象")}}初始化过程的表达式。对象初始化是由一组描述对象的属性组成。属性的值可以是{{Glossary("primitive","原始")}}类型,也可以是其他对象。

+ +

创建对象

+ +

没有属性的空对象可以用以下方式创建:

+ +
let obj = {};
+ +

不过,字面 初始化 标记的优势在于,可以用内含属性的花括号快速创建对象。简单地编写一个逗号分隔的键值对的类别。如下代码创建了一个含三个属性的对象,键分别为 "foo", "age" 和 "baz"。这些键对应的值,分别是字符串“bar”,数字42和另一个对象。

+ +
let obj = {
+  foo: "bar",
+  age: 42,
+  baz: { myProp: 12 },
+}
+ +

属性访问

+ +

创建对象后,可以读取或者修改它。对象属性可以用下标小圆点标记或者方括号标记访问。参考属性访问 获取更多信息。

+ +
object.foo; // "bar"
+object["age"]; // 42
+
+object.foo = "baz";
+
+ +

属性定义

+ +

上面学习了如何用初始化标记对象属性。经常能遇到希望将代码中的变量放到对象中的情况。可能遇到如下代码:

+ +
var a = "foo",
+    b = 42,
+    c = {};
+
+var o = {
+  a: a,
+  b: b,
+  c: c
+};
+ +

在 ECMAScript 2015 中,有更简短的标记可以实现同样的效果:

+ +
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
+ +

重复属性名

+ +

属性使用了同样的名称时,后面的属性会覆盖前面的属性。

+ +
var a = {x: 1, x: 2};
+console.log(a); // { x: 2}
+
+ +

在 ECMAScript 5 严格模式的代码中, 重复的属性名会被当做{{jsxref("SyntaxError")}}。引入计算的属性名以后,属性名会在运行时出现重复。ECMAScript 2015 移除了这个限制。

+ +
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;
+  }
+}
+ +

方法定义

+ +

对象属性也可以是一个函数gettersetter方法。

+ +
var o = {
+  property: function ([parameters]) {},
+  get property() {},
+  set property(value) {},
+};
+ +

ECMAScript 2015引入了一种简短写法, "function" 关键字也可以丢掉。

+ +
// Shorthand method names (ES6)
+var o = {
+  property([parameters]) {},
+  get property() {},
+  set property(value) {},
+  * generator() {}
+};
+ +

ECMAScript 2015 提供了一种简明地定义以生成器函数作为值的属性的方法。

+ +
var o = {
+  * generator() {
+    ...........
+  }
+};
+ +

ECMAScript 5 中可以这样书写(需要注意的是 ES5 没有生成器):

+ +
var o = {
+  generatorMethod: function *() {
+    ...........
+  }
+};
+ +

获取更多信息和范例,请参考 method definitions

+ +

计算属性名

+ +

从ECMAScript 2015开始,对象初始化语法开始支持计算属性名。其允许在[]中放入表达式,计算结果可以当做属性名。这种用法和用方括号访问属性非常类似,也许你已经用来读取和设置属性了。现在同样的语法也可以用于对象字面值了:

+ +
// 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 }
+ +

扩展属性

+ +

 

+ +

ECMAScript 提案(第3阶段)的剩余/扩展属性扩展属性添加到对象文字。它将自己提供的对象的枚举属性复制到一个新的对象上。

+ +

使用比{{jsxref("Object.assign()")}}更短的语法,可以轻松克隆(不包括原型)或合并对象。

+ +

 

+ +
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 }
+
+ +

请注意,{{jsxref("Object.assign()")}}会触发setter,而展开操作符则不会。

+ +

变更原型

+ +

定义属性为__proto__: 值"__proto__": 值 时,不会创建名为__proto__属性。如果给出的值是对象或者null,那么对象的[[Prototype]]会被设置为给出的值。(如果给出的值不是对象也不是null,那么对象的原型不会改变。)

+ +
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__"));
+
+ +

在对象字面值中,仅有一次变更原型的机会;多次变更原型,会被视为语法错误。

+ +

不使用冒号标记的属性定义,不会变更对象的原型;而是和其他具有不同名字的属性一样是普通属性定义。

+ +
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);
+
+ +

对象字面量表示法与JSON

+ +

对象字面量表示法和 JavaScript Object Notation(JSON)是不同的。虽然他们看起来相似,不同点有:

+ + + +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}initial definition.
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}getter and setter added.
{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ES2015')}}Shorthand method/property names and computed property names added.
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ESDraft')}} 
Rest/Spread Properties for ECMAScript DraftStage 3 draft.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.object_initializer")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。

+ +
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
+ + + +

关联性

+ +

关联性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:

+ +
a OP b OP c;
+
+ +

左关联(左到右)相当于把左边的子表达式加上小括号(a OP b) OP c,右关联(右到左)相当于a OP (b OP c)。赋值运算符是右关联的,所以你可以这么写:

+ +
a = b = 5; 
+ +

结果 a 和 b 的值都会成为5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:b被赋值为5,然后a也被赋值为 b=5 的返回值,也就是5。

+ +

示例

+ +
3 > 2 && 2 > 1
+// return true
+
+3 > 2 > 1
+// 返回 false,因为 3 > 2 是 true,并且 true > 1 is false
+// 加括号可以更清楚:(3 > 2) > 1
+
+ +

汇总表

+ +

下面的表将所有运算符按照优先级的不同从高(20)到低(1)排列。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
优先级运算类型关联性运算符
21{{jsxref("Operators/Grouping", "圆括号")}}n/a(不相关)( … )
20{{jsxref("Operators/Property_Accessors","成员访问", "#点符号表示法")}}从左到右… . …
{{jsxref("Operators/Property_Accessors","需计算的成员访问", "#括号表示法")}}从左到右… [ … ]
{{jsxref("Operators/new","new")}} (带参数列表)n/anew … ( … )
函数调用从左到右… ( … )
可选链(Optional chaining)从左到右?.
19new (无参数列表)从右到左new …
18后置递增(运算符在后)n/a
+  
… ++
后置递减(运算符在后)… --
17逻辑非从右到左! …
按位非~ …
一元加法+ …
一元减法- …
前置递增++ …
前置递减-- …
typeoftypeof …
voidvoid …
deletedelete …
awaitawait …
16从右到左… ** …
15乘法从左到右
+  
… * …
除法… / …
取模… % …
14加法从左到右
+  
… + …
减法… - …
13按位左移从左到右… << …
按位右移… >> …
无符号右移… >>> …
12小于从左到右… < …
小于等于… <= …
大于… > …
大于等于… >= …
in… in …
instanceof… instanceof …
11等号从左到右
+  
… == …
非等号… != …
全等号… === …
非全等号… !== …
10按位与从左到右… & …
9按位异或从左到右… ^ …
8按位或从左到右… | …
7逻辑与从左到右… && …
6逻辑或从左到右… || …
5空值合并从左到右… ?? …
4条件运算符从右到左… ? … : …
3赋值从右到左… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
2yield从右到左yield …
yield*yield* …
1展开运算符n/a... …
0逗号从左到右… , …
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 +--- +
{{jsSidebar("Operators")}}
+ +

属性访问器提供了两种方式用于访问一个对象的属性,它们分别是点号和方括号。

+ +
{{EmbedInteractiveExample("pages/js/expressions-propertyaccessors.html")}}
+ + + +

语法

+ +
object.property
+object['property']
+
+ +

描述

+ +

我们可以将对象看做是一个关联数组(或者:映射字典哈希表查询表)。这个数组中的键就是这个对象中属性的名称。通常,当我们提及一个对象的属性时,会对属性与方法之间做个对比。然而,属性与方法之间的区别并不大。一个方法就是一个可以被调用的属性而已,例如一个指向函数 Function 实例的引用可以作为对象属性的值。

+ +

访问对象属性有两种方式:点号表示法和方括号表示法。

+ +

点号表示法

+ +
get = object.property;
+object.property = set;
+
+ +

以上代码中,property必须是一个有效的 JavaScript 标识符,例如,一串字母数字字符,也包括下划线及美元符号,但不能以数字作为开头。比如,object.$1是合法的,而 object.1是无效不合法的。

+ +
document.createElement('pre');
+
+ +

在上述代码块中,document中存在一个名为"createElement"的方法并且被调用了。

+ +

如果对数字字面量使用方法,并且数字文字没有指数且没有小数点,请在方法调用之前的点之前留出空格,以防止点被解释为小数点。

+ +
77 .toExponential();
+// 或
+77
+.toExponential();
+// 或
+(77).toExponential();
+// 或
+77..toExponential();
+// 或
+77.0.toExponential();
+// 因为 77. === 77.0,没有歧义(no ambiguity)
+
+ +

方括号表示法

+ +
get = object[property_name];
+object[property_name] = set;
+
+ +

property_name 是一个字符串。该字符串不一定是一个合法的标识符;它可以是任意值,例如,"1foo","!bar!",甚至是 " "(一个空格)。

+ +
document['createElement']('pre');
+
+ +

这里的代码的功能跟上一个例子的作用是相同的。

+ +

括号之前允许有空格。

+ +
document ['createElement']('pre');
+
+ +

属性名称

+ +

属性名称必须是字符串或符号 Symbol。这意味着非字符串对象不能用来作为一个对象属性的键。任何非字符串对象,包括 Number,都会通过 toString 方法,被转换成一个字符串。

+ +
var object = {};
+object['1'] = 'value';
+console.log(object[1]);
+
+ +

上述代码的输出为"value",因为 1 被类型转换为'1'。

+ +
var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
+object[foo] = 'value';
+console.log(object[bar]);
+
+ +

上述的代码的输出也是 "value",由于对象 foo 和 bar 都会被转成相同的字符串。在SpiderMonkey JavaScript 引擎中,这个字符串是 "[object Object]"。

+ +

方法绑定

+ +

一个方法没有绑定到对象上,那就意味着这个方法是不起作用的。特别要注意的是,在一个方法中this对象并不是固定的,例如,this不需要指向包含当前方法的对象。this可通过函数调用被传递过去的值所替换。详见方法绑定

+ +

注意eval

+ +

在那些可通过方括号表示法替换的场景下,JavaScript 新手在使用eval 经常会犯错。例如,下面的语法经常在很多代码中找到。

+ +
x = eval('document.forms.form_name.elements.' + strFormControl + '.value');
+
+ +

eval 的性能较差,且有安全风险。在任何时候都应该避免使用。而且,此时 strFormControl 必须是一个合法的标识符, 这在一些表单控件的 name、ID 值之中并不是必要的。所以,使用括号来代替会更好一些:

+ +
x = document.forms["form_name"].elements[strFormControl].value;
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#sec-property-accessors', 'Property Accessors')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-property-accessors', 'Property Accessors')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.2.1', 'Property Accessors')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.2.1', 'Property Accessors')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.property_accessors")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The remainder assignment operator (%=) divides a variable by the value of the right operand and assigns the remainder to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-remainder-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x %= y
+Meaning:  x  = x % y
+ +

Examples

+ +

Using remainder assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar %= 2     // 1
+bar %= 'foo' // NaN
+bar %= 0     // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.remainder_assignment")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The right shift 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".

+ +
{{EmbedInteractiveExample("pages/js/expressions-right-shift.html")}}
+ + + +

语法

+ +
a >> b
+
+ +

Description

+ +

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".

+ +

For example, 9 >> 2 yields 2:

+ +
.    9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

Likewise, -9 >> 2 yields -3, because the sign is preserved:

+ +
.    -9 (base 10): 11111111111111111111111111110111 (base 2)
+                   --------------------------------
+-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
+
+ +

Examples

+ +

Using right shift

+ +
 9 >> 2; //  2
+-9 >> 2; // -3
+
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.right_shift")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

The right shift assignment operator (>>=) moves the specified amount of bits to the right and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-right-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x >>= y
+Meaning:  x   = x >> y
+ +

Examples

+ +

Using right shift assignment

+ +
let a = 5; //   (00000000000000000000000000000101)
+a >>= 2;   // 1 (00000000000000000000000000000001)
+
+let b = -5; //  (-00000000000000000000000000000101)
+b >>= 2;  // -2 (-00000000000000000000000000000010)
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.right_shift_assignment")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +
展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。(译者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)
+ +
{{EmbedInteractiveExample("pages/js/expressions-spreadsyntax.html")}}
+ + + +

语法

+ +

函数调用:

+ +
myFunction(...iterableObj);
+ +

字面量数组构造或字符串:

+ +
[...iterableObj, '4', ...'hello', 6];
+ +

构造字面量对象时,进行克隆或者属性拷贝(ECMAScript 2018规范新增特性):

+ +
let objClone = { ...obj };
+ +

示例

+ +

在函数调用时使用展开语法

+ +

等价于apply的方式

+ +

如果想将数组元素迭代为函数参数,一般使用{{jsxref( "Function.prototype.apply")}} 的方式进行调用

+ +
function myFunction(x, y, z) { }
+var args = [0, 1, 2];
+myFunction.apply(null, args);
+ +

有了展开语法,可以这样写:

+ +
function myFunction(x, y, z) { }
+var args = [0, 1, 2];
+myFunction(...args);
+ +

所有参数都可以通过展开语法来传值,也不限制多次使用展开语法。

+ +
function myFunction(v, w, x, y, z) { }
+var args = [0, 1];
+myFunction(-1, ...args, 2, ...[3]);
+ +

在 new 表达式中应用

+ +

使用 new 关键字来调用构造函数时,不能直接使用数组+ apply 的方式(apply 执行的是调用 [[Call]] , 而不是构造 [[Construct]])。当然, 有了展开语法, 将数组展开为构造函数的参数就很简单了:

+ +
var dateFields = [1970, 0, 1]; // 1970年1月1日
+var d = new Date(...dateFields);
+
+ +

如果不使用展开语法, 想将数组元素传给构造函数, 实现方式可能是这样的

+ +
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"}
+ +

构造字面量数组时使用展开语法

+ +

构造字面量数组时更给力!

+ +

没有展开语法的时候,只能组合使用 push, splice, concat 等方法,来将已有数组元素变成新数组的一部分。有了展开语法,  通过字面量方式, 构造新数组会变得更简单、更优雅:

+ +
var parts = ['shoulders', 'knees'];
+var lyrics = ['head', ...parts, 'and', 'toes']; 
+// ["head", "shoulders", "knees", "and", "toes"]
+
+ +

和参数列表的展开类似,  ... 在构造字面量数组时, 可以在任意位置多次使用.

+ +

数组拷贝(copy)

+ +
var arr = [1, 2, 3];
+var arr2 = [...arr]; // like arr.slice()
+arr2.push(4);
+
+// arr2 此时变成 [1, 2, 3, 4]
+// arr 不受影响
+
+ +

提示: 实际上, 展开语法和 {{jsxref("Object.assign()")}} 行为一致, 执行的都是浅拷贝(只遍历一层)。如果想对多维数组进行深拷贝, 下面的示例就有些问题了。

+ +
var a = [[1], [2], [3]];
+var b = [...a];
+b.shift().shift(); // 1
+// Now array a is affected as well: [[2], [3]]
+
+ +

连接多个数组

+ +

{{jsxref("Array.concat")}} 函数常用于将一个数组连接到另一个数组的后面。如果不使用展开语法, 代码可能是下面这样的:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+// 将 arr2 中所有元素附加到 arr1 后面并返回
+var arr3 = arr1.concat(arr2);
+ +

使用展开语法:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+var arr3 = [...arr1, ...arr2];
+
+ +

{{jsxref("Array.unshift")}} 方法常用于在数组的开头插入新元素/数组.  不使用展开语法, 示例如下:

+ +
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]
+ +

如果使用展开语法, 代码如下:  [请注意, 这里使用展开语法创建了一个新的 arr1 数组,  {{jsxref("Array.unshift")}} 方法则是修改了原本存在的 arr1 数组]:

+ +
var arr1 = [0, 1, 2];
+var arr2 = [3, 4, 5];
+arr1 = [...arr2, ...arr1]; // arr1 现在为 [3, 4, 5, 0, 1, 2]
+
+ +

构造字面量对象时使用展开语法

+ +

Rest/Spread Properties for ECMAScript 提议(stage 4) 对 字面量对象 增加了展开特性。其行为是, 将已有对象的所有可枚举(enumerable)属性拷贝到新构造的对象中.

+ +

浅拷贝(Shallow-cloning, 不包含 prototype) 和对象合并, 可以使用更简短的展开语法。而不必再使用 {{jsxref("Object.assign()")}} 方式.

+ +
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 }
+
+ +

提示: {{jsxref("Object.assign()")}} 函数会触发 setters,而展开语法则不会。

+ + + +

提示: 不能替换或者模拟 {{jsxref("Object.assign()")}} 函数:

+ +
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 } }
+ +

在这段代码中, 展开操作符(spread operator)并没有按预期的方式执行:  而是先将多个解构变为剩余参数(rest parameter), 然后再将剩余参数展开为字面量对象.

+ + + +

只能用于可迭代对象

+ +

在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象

+ +
var obj = {'key1': 'value1'};
+var array = [...obj]; // TypeError: obj is not iterable
+
+ +

展开多个值

+ +

在函数调用时使用展开语法,请注意不能超过 JavaScript 引擎限制的最大参数个数。更多详细信息,请参考: apply()

+ +

剩余语法(剩余参数)

+ +

剩余语法(Rest syntax) 看起来和展开语法完全相同,不同点在于, 剩余参数用于解构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。 请参考: 剩余参数

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-array-initializer')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Array Initializer, Argument Lists
{{SpecName('ESDraft', '#sec-array-initializer')}}{{Spec2('ESDraft')}}No changes.
{{SpecName('ESDraft', '#sec-object-initializer')}}{{Spec2('ESDraft')}}Defined in Object Initializer
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.spread")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

全等运算符 (===) 会检查它的两个操作数是否相等,并且返回一个布尔值结果。与相等运算符不同,全等运算符总是认为不同类型的操作数是不同的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}
+ + + +

语法

+ +
x === y
+ +

描述

+ +

全等运算符(===!==)使用全等比较算法来比较两个操作数。

+ + + +

全等运算符与相等运算符==)最显著的区别是,如果操作数的类型不同,== 运算符会在比较之前尝试将它们转换为相同的类型。

+ +

例子

+ +

比较相同类型的操作数

+ +
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
+ +

比较不同类型的操作数

+ +
console.log("3" === 3);           // false
+
+console.log(true === 1);          // false
+
+console.log(null === undefined);  // false
+ +

比较对象

+ +
const object1 = {
+  name: "hello"
+}
+
+const object2 = {
+  name: "hello"
+}
+
+console.log(object1 === object2);  // false
+console.log(object1 === object1);  // true
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.strict_equality")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

严格不等式操作符(!==)检查它的两个对象是否不相等,返回一个布尔结果。与不等式运算符不同,严格不等式运算符总是认为不同类型的对象是不同的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-strict-equality.html")}}
+ + + +

语法

+ +
x !== y
+ +

描述

+ +

严格不等式运算符检查其对象是否不相等。它是严格相等运算符的否定,因此下面两行总是会给出相同的结果:

+ +
x !== y
+
+!(x === y)
+ +

有关比较算法的详细信息,请参阅严格相等运算符的页面。

+ +

与严格相等运算符一样,严格不等运算符始终认为不同类型的对象是不同的:

+ +
3 !== "3"; // true
+ +

示例

+ +

比较相同类型的对象

+ +
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
+ +

比较不同类型的对象

+ +
console.log("3" !== 3);           // true
+
+console.log(true !== 1);          // true
+
+console.log(null !== undefined);  // true
+ +

比较Object对象

+ +
const object1 = {
+  name: "hello"
+}
+
+const object2 = {
+  name: "hello"
+}
+
+console.log(object1 !== object2);  // true
+console.log(object1 !== object1);  // false
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.strict_inequality")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The subtraction operator (-) subtracts the two operands, producing their difference.

+ +
{{EmbedInteractiveExample("pages/js/expressions-subtraction.html")}}
+ +
+ + + +

语法

+ +
Operator: x - y
+
+ +

Examples

+ +

Subtraction with numbers

+ +
5 - 3     // 2
+3 - 5     // -2
+ +

Subtraction with non-numbers

+ +
'foo' - 3 // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-subtraction-operator-minus', 'Subtraction operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.subtraction")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

The subtraction assignment operator (-=) subtracts the value of the right operand from a variable and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-subtraction-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x -= y
+Meaning:  x  = x - y
+ +

Examples

+ +

Using subtraction assignment

+ +
// Assuming the following variable
+//  bar = 5
+
+bar -= 2     // 3
+bar -= 'foo' // NaN
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.subtraction_assignment")}}

+ +

See also

+ + + +

+ +

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 +--- +
{{jsSidebar("Operators")}}
+ +

super关键字用于访问和调用一个对象的父对象上的函数。

+ +

super.propsuper[expr]表达式在对象字面量任何方法定义中都是有效的。

+ +

语法

+ +
super([arguments]);
+// 调用 父对象/父类 的构造函数
+
+super.functionOnParent([arguments]);
+// 调用 父对象/父类 上的方法
+
+ +

描述

+ +

在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。super关键字也可以用来调用父对象上的函数。

+ +

示例

+ +

在类中使用super

+ +

以下代码片段来自于 classes sample

+ +
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';
+  }
+}
+
+ +

调用父类上的静态方法

+ +

你也可以用 super 调用父类的静态方法

+ +
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'
+ +

删除 super 上的属性将抛出异常

+ +

你不能使用 delete 操作符 加 super.prop 或者 super[expr] 去删除父类的属性,这样做会抛出 {{jsxref("ReferenceError")}}。

+ +
class Base {
+  constructor() {}
+  foo() {}
+}
+class Derived extends Base {
+  constructor() {}
+  delete() {
+    delete super.foo; // this is bad
+  }
+}
+
+new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
+ +

super.prop 不能覆写不可写属性

+ +

当使用 {{jsxref("Object.defineProperty")}} 定义一个属性为不可写时,super将不能重写这个属性的值。

+ +
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
+ +

在对象字面量中使用super.prop

+ +

Super也可以在object initializer / literal 符号中使用。在下面的例子中,两个对象各定义了一个方法。在第二个对象中, 我们使用super调用了第一个对象中的方法。 当然,这需要我们先利用 {{jsxref("Object.setPrototypeOf()")}} 设置obj2的原型为obj1,然后才能够使用super调用 obj1上的method1

+ +
var obj1 = {
+  method1() {
+    console.log("method 1");
+  }
+}
+
+var obj2 = {
+  method2() {
+   super.method1();
+  }
+}
+
+Object.setPrototypeOf(obj2, obj1);
+obj2.method2(); // logs "method 1"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-super-keyword', 'super')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.super")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

与其他语言相比,函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。

+ +

在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。ES5 引入了 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。

+ +

{{EmbedInteractiveExample("pages/js/expressions-this.html")}}

+ +

语法

+ +
this
+ +

+ +

当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。

+ +

描述

+ +

全局上下文

+ +

无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

+ +
// 在浏览器中, 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"
+ +
+

Note: 你可以使用 {{jsxref("globalThis")}} 获取全局对象,无论你的代码是否在当前上下文运行。

+
+ +

函数上下文

+ +

在函数内部,this的值取决于函数被调用的方式。

+ +

因为下面的代码不在严格模式下,且 this 的值不是由该调用设置的,所以 this 的值默认指向全局对象,浏览器中就是 {{domxref("Window", "window")}}。

+ +
function f1(){
+  return this;
+}
+//在浏览器中:
+f1() === window;   //在浏览器中,全局对象是window
+
+//在Node中:
+f1() === globalThis;
+
+ +

然而,在严格模式下,如果进入执行环境时没有设置 this 的值,this 会保持为 undefined,如下:

+ +
function f2(){
+  "use strict"; // 这里是严格模式
+  return this;
+}
+
+f2() === undefined; // true
+
+ +
在第二个例子中,this 应是 undefined,因为 f2 是被直接调用的,而不是作为对象的属性或方法调用的(如 window.f2())。有一些浏览器最初在支持严格模式时没有正确实现这个功能,于是它们错误地返回了window对象。
+ +

如果要想把 this 的值从一个环境传到另一个,就要用 call 或者apply 方法,如下方的示例所示。

+ +

类上下文

+ +

this 在  中的表现与在函数中类似,因为类本质上也是函数,但也有一些区别和注意事项。

+ +

在类的构造函数中,this 是一个常规对象。类中所有非静态的方法都会被添加到 this 的原型中:

+ +
class Example {
+  constructor() {
+    const proto = Object.getPrototypeOf(this);
+    console.log(Object.getOwnPropertyNames(proto));
+  }
+  first(){}
+  second(){}
+  static third(){}
+}
+
+new Example(); // ['constructor', 'first', 'second']
+ +
+

注意:静态方法不是 this 的属性,它们只是类自身的属性。

+
+ +

派生类

+ +

不像基类的构造函数,派生类的构造函数没有初始的 this 绑定。在构造函数中调用 {{jsxref("Operators/super", "super()")}} 会生成一个 this 绑定,并相当于执行如下代码,Base为基类:

+ +
this = new Base();
+ +
+

警告:在调用 super() 之前引用 this 会抛出错误。

+
+ +

派生类不能在调用 super() 之前返回,除非其构造函数返回的是一个对象,或者根本没有构造函数。

+ +
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
+ +

示例

+ +

函数上下文中的 this

+ +
// 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
+
+ +

this 和对象转换

+ +
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
+
+ +

在非严格模式下使用 call 和 apply 时,如果用作 this 的值不是对象,则会被尝试转换为对象。null 和 undefined 被转换为全局对象。原始值如 7 或 'foo' 会使用相应构造函数转换为对象。因此 7 会被转换为 new Number(7) 生成的对象,字符串 'foo' 会转换为 new String('foo') 生成的对象。

+ +
function bar() {
+  console.log(Object.prototype.toString.call(this));
+}
+
+bar.call(7);     // [object Number]
+bar.call('foo'); // [object String]
+bar.call(undefined); // [object global]
+ +

bind方法

+ +

ECMAScript 5 引入了 {{jsxref("Function.prototype.bind()")}}。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。

+ +
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
+
+ +

箭头函数

+ +

箭头函数中,this与封闭词法环境的this保持一致。在全局代码中,它将被设置为全局对象:

+ +
var globalObject = this;
+var foo = (() => this);
+console.log(foo() === globalObject); // true
+ +
+

注意:如果将this传递给callbind、或者apply来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null

+
+ +
// 接着上面的代码
+// 作为对象的一个方法调用
+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
+ +

无论如何,foo 的 this 被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法环境的。

+ +
// 创建一个含有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
+ +

在上面的例子中,一个赋值给了 obj.bar的函数(称为匿名函数 A),返回了另一个箭头函数(称为匿名函数 B)。因此,在 A 调用时,函数B的this被永久设置为obj.bar(函数A)的this。当返回的函数(函数B)被调用时,它this始终是最初设置的。在上面的代码示例中,函数B的this被设置为函数A的this,即obj,所以即使被调用的方式通常将其设置为 undefined 或全局对象(或者如前面示例中的其他全局执行环境中的方法),它的 this 也仍然是 obj 。

+ +

作为对象的方法

+ +

当函数作为对象里的方法被调用时,this 被设置为调用该函数的对象。

+ +

下面的例子中,当 o.f() 被调用时,函数内的 this 将绑定到 o 对象。

+ +
var o = {
+  prop: 37,
+  f: function() {
+    return this.prop;
+  }
+};
+
+console.log(o.f()); // 37
+
+ +

请注意,这样的行为完全不会受函数定义方式或位置的影响。在前面的例子中,我们在定义对象o的同时,将其中的函数定义为成员 f 。但是,我们也可以先定义函数,然后再将其附属到o.f。这样做的结果是一样的:

+ +
var o = {prop: 37};
+
+function independent() {
+  return this.prop;
+}
+
+o.f = independent;
+
+console.log(o.f()); // 37
+
+ +

这表明函数是从 o 的 f 成员调用的才是重点。

+ +

同样,this 的绑定只受最接近的成员引用的影响。在下面的这个例子中,我们把一个方法g当作对象o.b的函数调用。在这次执行期间,函数中的this将指向o.b。事实证明,这与他是对象 o 的成员没有多大关系,最近的引用才是最重要的。

+ +
o.b = {g: independent, prop: 42};
+console.log(o.b.g()); // 42
+ +

原型链中的 this

+ +

对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 this 指向的是调用这个方法的对象,就像该方法就在这个对象上一样。

+ +
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
+
+ +

在这个例子中,对象 p 没有属于它自己的 f 属性,它的 f 属性继承自它的原型。虽然最终是在 o 中找到 f 属性的,这并没有关系;查找过程首先从 p.f 的引用开始,所以函数中的 this 指向p。也就是说,因为f是作为p的方法调用的,所以它的this指向了p。这是 JavaScript 的原型继承中的一个有趣的特性。

+ +

getter 与 setter 中的 this

+ +

再次,相同的概念也适用于当函数在一个 getter 或者 setter 中被调用。用作 getter 或 setter 的函数都会把 this 绑定到设置或获取属性的对象。

+ +
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
+
+ +

作为构造函数

+ +

当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。

+ +
+

虽然构造函数返回的默认值是 this 所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 this 对象)。

+
+ +
/*
+ * 构造函数这样工作:
+ *
+ * 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
+
+ +

在刚刚的例子中(C2),因为在调用构造函数的过程中,手动的设置了返回对象,与this绑定的默认对象被丢弃了。(这基本上使得语句 “this.a = 37;”成了“僵尸”代码,实际上并不是真正的“僵尸”,这条语句执行了,但是对于外部没有任何影响,因此完全可以忽略它)。

+ +

作为一个DOM事件处理函数

+ +

当函数被用作事件处理函数时,它的 this 指向触发事件的元素(一些浏览器在使用非 addEventListener 的函数动态地添加监听函数时不遵守这个约定)。

+ +
// 被调用时,将关联的元素变成蓝色
+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);
+}
+ +

作为一个内联事件处理函数

+ +

当代码被内联 on-event 处理函数 调用时,它的this指向监听器所在的DOM元素:

+ +
<button onclick="alert(this.tagName.toLowerCase());">
+  Show this
+</button>
+
+ +

上面的 alert 会显示 button。注意只有外层代码中的 this 是这样设置的:

+ +
<button onclick="alert((function(){return this})());">
+  Show inner this
+</button>
+
+ +

在这种情况下,没有设置内部函数的 this,所以它指向 global/window 对象(即非严格模式下调用的函数未设置 this 时指向的默认对象)。

+ +

类中的this

+ +

和其他普通函数一样,方法中的 this 值取决于它们如何被调用。有时,改写这个行为,让类中的 this 值总是指向这个类实例会很有用。为了做到这一点,可在构造函数中绑定类方法:

+ +
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
+ +
+

注意:类内部总是严格模式。调用一个 this 值为 undefined 的方法会抛出错误。

+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-this-keyword', 'The this keyword')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-this-keyword', 'The this keyword')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.1.1', 'The this keyword')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.this")}}

+ +

相关链接

+ + 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 +--- +

{{jsSidebar("Operators")}}

+ +

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

+ +
{{EmbedInteractiveExample("pages/js/expressions-typeof.html")}}
+ + + +

语法

+ +

typeof 运算符后接操作数:

+ +
typeof operand
+typeof(operand)
+
+ +

参数

+ +

operand

+ +
+
一个表示对象或{{Glossary("Primitive", "原始值")}}的表达式,其类型将被返回。
+
+ +

描述

+ +

下表总结了 typeof 可能的返回值。有关类型和原始值的更多信息,可查看 JavaScript 数据结构 页面。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
类型结果
{{glossary("Undefined")}}"undefined"
{{glossary("Null")}}"object" (见{{anch("null", "下文")}})
{{glossary("Boolean")}}"boolean"
{{glossary("Number")}}"number"
{{glossary("BigInt")}}(ECMAScript 2020 新增)"bigint"
{{glossary("String")}}"string"
{{glossary("Symbol")}} (ECMAScript 2015 新增)"symbol"
宿主对象(由 JS 环境提供)取决于具体实现
{{glossary("Function")}} 对象 (按照 ECMA-262 规范实现 [[Call]])"function"
其他任何对象"object"
+ +

示例

+ +
// 数值
+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';
+
+ +

typeof null

+ +
// JavaScript 诞生以来便如此
+typeof null === 'object';
+ +

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。(参考来源

+ +

曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但被拒绝了。该提案会导致 typeof null === 'null'

+ +

使用 new 操作符

+ +
// 除 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'
+ +

语法中的括号

+ +
// 括号有无将决定表达式的类型。
+var iData = 99;
+
+typeof iData + ' Wisen'; // 'number Wisen'
+typeof (iData + ' Wisen'); // 'string'
+ +

正则表达式

+ +

对正则表达式字面量的类型判断在某些浏览器中不符合标准:

+ +
typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1
+typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1
+
+ +

错误

+ +

在 ECMAScript 2015 之前,typeof 总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,typeof 也能返回 'undefined'。使用 typeof 永远不会抛出错误。

+ +

但在加入了块级作用域的 let 和 const 之后,在其被声明之前对块中的 let 和 const 变量使用 typeof 会抛出一个 ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。

+ +
typeof undeclaredVariable === 'undefined';
+
+typeof newLetVariable; // ReferenceError
+typeof newConstVariable; // ReferenceError
+typeof newClass; // ReferenceError
+
+let newLetVariable;
+const newConstVariable = 'hello';
+class newClass{};
+ +

例外

+ +

当前所有的浏览器都暴露了一个类型为 undefined 的非标准宿主对象 {{domxref("document.all")}}。

+ +
typeof document.all === 'undefined';
+
+ +

尽管规范允许为非标准的外来对象自定义类型标签,但它要求这些类型标签与已有的不同。document.all 的类型标签为 'undefined' 的例子在 Web 领域中被归类为对原 ECMA JavaScript 标准的“故意侵犯”。

+ +

Real-world usage

+ +

typeof is very useful, but it's not as versatile as might be required. For example, typeof([]) , is 'object', as well as typeof(new Date()), typeof(/abc/), etc.

+ +

For greater specificity in checking types, a typeof wrapper for usage in production-level code would be as follows (provided obj exists):

+ +
  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;
+  }
+ +

For checking non-existent variables that would otherwise throw a {{JSxRef("ReferenceError")}}, use typeof nonExistentVar === 'undefined'.

+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-typeof-operator', 'The typeof Operator')}}
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.operators.typeof")}}

+ +

IE 特别提示

+ +

在 IE 6, 7 和 8 上,很多宿主对象是对象而不是函数。例如:

+ +
typeof alert === 'object'
+
+ +
+ +

相关链接

+ + + +
+
+
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 +--- +
{{jsSidebar("Operators")}}
+ +

The unary negation operator (-) precedes its operand and negates it.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unary-negation.html")}}
+ + + +

语法

+ +
Operator: -x
+
+ +

Examples

+ +

Negating numbers

+ +
const x = 3;
+const y = -x;
+
+// y = -3
+// x = 3
+
+ +

Negating non-numbers

+ +

The unary negation operator can convert a non-number into a number.

+ +
const x = "4";
+const y = -x;
+
+// y = -4
+
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-minus-operator', 'Unary negation operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.unary_negation")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The unary plus operator (+) precedes its operand and evaluates to its operand but attempts to convert it into a number, if it isn't already.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unary-plus.html", "taller")}}
+ + + +

语法

+ +
Operator: +x
+
+ +

Description

+ +

Although unary negation (-) 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 true, false, and null. Integers in both decimal and hexadecimal (0x-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")}}.

+ +

Examples

+ +

Usage with numbers

+ +
const x = 1;
+const y = -1;
+
+console.log(+x);
+// 1
+console.log(+y);
+// -1
+ +

Usage with non-numbers

+ +
+true  // 1
++false // 0
++null  // 0
++function(val){ return val } // NaN
++1n    // throws TypeError: Cannot convert BigInt value to number
+
+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-unary-plus-operator', 'Unary plus operator')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.unary_plus")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The unsigned right shift operator (>>>) (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 0, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift.html")}}
+ + + +

语法

+ +
a >>> b
+
+ +

描述

+ +

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 0, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.

+ +

For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, 9 >>> 2 yields 2, the same as 9 >> 2:

+ +
.     9 (base 10): 00000000000000000000000000001001 (base 2)
+                   --------------------------------
+9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

However, this is not the case for negative numbers. For example, -9 >>> 2 yields 1073741821, which is different than -9 >> 2 (which yields -3):

+ +
.     -9 (base 10): 11111111111111111111111111110111 (base 2)
+                    --------------------------------
+-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
+
+ +

例子

+ +

Using unsigned right shift

+ +
 9 >>> 2; // 2
+-9 >>> 2; // 1073741821
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.unsigned_right_shift")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

The unsigned right shift assignment operator (>>>=) moves the specified amount of bits to the right and assigns the result to the variable.

+ +
{{EmbedInteractiveExample("pages/js/expressions-unsigned-right-shift-assignment.html")}}
+ +
+ + + +

语法

+ +
Operator: x >>>= y
+Meaning:  x    = x >>> y
+ +

例子

+ +

Using unsigned right shift assignment

+ +
let a = 5; //   (00000000000000000000000000000101)
+a >>>= 2;  // 1 (00000000000000000000000000000001)
+
+let b = -5; // (-00000000000000000000000000000101)
+b >>>= 2;   // 1073741822 (00111111111111111111111111111110)
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.unsigned_right_shift_assignment")}}

+ +

参见

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

void 运算符 对给定的表达式进行求值,然后返回 {{jsxref("Global_Objects/undefined", "undefined")}}。

+ +

语法

+ +
void expression
+ +

描述

+ +

这个运算符能向期望一个表达式的值是{{jsxref("Global_Objects/undefined", "undefined")}}的地方插入会产生副作用的表达式。

+ +

void 运算符通常只用于获取 undefined的原始值,一般使用void(0)(等同于void 0)。在上述情况中,也可以使用全局变量{{jsxref("Global_Objects/undefined", "undefined")}} 来代替(假定其仍是默认值)。

+ +

立即调用的函数表达式

+ +

在使用立即执行的函数表达式时,可以利用 void 运算符让 JavaScript 引擎把一个function关键字识别成函数表达式而不是函数声明(语句)。

+ +
void function iife() {
+    var bar = function () {};
+    var baz = function () {};
+    var foo = function () {
+        bar();
+        baz();
+     };
+    var biz = function () {};
+
+    foo();
+    biz();
+}();
+
+ +

JavaScript URIs

+ +

当用户点击一个以 javascript: URI 时,它会执行URI中的代码,然后用返回的值替换页面内容,除非返回的值是{{jsxref("Global_Objects/undefined", "undefined")}}。void运算符可用于返回{{jsxref("Global_Objects/undefined", "undefined")}}。例如:

+ +
<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>
+
+ +

注意,虽然这么做是可行的,但利用 javascript: 伪协议来执行 JavaScript 代码是不推荐的,推荐的做法是为链接元素绑定事件。

+ +

在箭头函数中避免泄漏

+ +

箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 void 运算符,来确保返回 {{jsxref("Global_Objects/undefined", "undefined")}}(如下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。

+ +
button.onclick = () => void doSomething();
+ +

确保了当 doSomething 的返回值从 {{jsxref("Global_Objects/undefined", "undefined")}} 变为 true 的时候,不会改变函数的行为

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-void-operator', 'The void Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-void-operator', 'The void Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.4.2', 'The void Operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.void")}}

+ +

相关链接

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

yield 关键字用来暂停和恢复一个生成器函数(({{jsxref("Statements/function*", "function*")}} 或遗留的生成器函数)。

+ +

语法

+ +
[rv] = yield [expression];
+ +
+
expression
+
定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined
+
rv
+
+

返回传递给生成器的next()方法的可选值,以恢复其执行。

+
+
+ +

描述

+ +

yield关键字使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

+ +

yield关键字实际返回一个IteratorResult对象,它有两个属性,valuedonevalue属性是对yield表达式求值的结果,而donefalse,表示生成器函数尚未完全完成。

+ +

一旦遇到 yield 表达式,生成器的代码将被暂停运行,直到生成器的 next() 方法被调用。每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值:

+ + + +

如果将参数传递给生成器的next()方法,则该值将成为生成器当前yield操作返回的值。

+ +

在生成器的代码路径中的yield运算符,以及通过将其传递给{{jsxref("Generator.prototype.next()")}}指定新的起始值的能力之间,生成器提供了强大的控制力。

+ +

示例

+ +

以下代码是一个生成器函数的声明。

+ +
function* countAppleSales () {
+  var saleList = [3, 7, 5];
+  for (var i = 0; i < saleList.length; i++) {
+    yield saleList[i];
+  }
+}
+ +

一旦生成器函数已定义,可以通过构造一个迭代器来使用它。

+ +
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 }
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'Yield')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'Yield')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.yield")}}

+ +

相关链接

+ + 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* +--- +
{{jsSidebar("Operators")}}
+ +

 yield* 表达式用于委托给另一个{{jsxref("Statements/function*", "generator")}} 或可迭代对象。

+ +

语法

+ +
 yield* [[expression]];
+ +
+
expression
+
返回一个可迭代对象的表达式。
+
+ +

描述

+ +

yield* 表达式迭代操作数,并产生它返回的每个值。

+ +

yield* 表达式本身的值是当迭代器关闭时返回的值(即donetrue时)。

+ +

示例

+ +

委托给其他生成器

+ +

以下代码中,g1() yield 出去的每个值都会在 g2() 的 next() 方法中返回,就像那些 yield 语句是写在 g2() 里一样。

+ +
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 }
+
+ +

委托给其他可迭代对象

+ +

除了生成器对象这一种可迭代对象,yield* 还可以 yield 其它任意的可迭代对象,比如说数组、字符串、arguments 对象等等。

+ +
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 }
+
+ +

yield* 表达式的值

+ +

yield* 是一个表达式,不是语句,所以它会有自己的值。

+ +
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"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#', 'Yield')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#', 'Yield')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.operators.yield_star")}}

+ +

Firefox 特别提示

+ + + +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" new file mode 100644 index 0000000000..276296ccd7 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/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 +--- +
{{jsSidebar("Operators")}}
+ +

当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。

+ +
{{EmbedInteractiveExample("pages/js/expressions-remainder.html")}}
+ +
+ + + +

语法

+ +
Operator: var1 % var2
+
+ +

示例

+ +

被除数为正数

+ +
 12 % 5  //  2
+ 1 % -2 //  1
+ 1 % 2  //  1
+ 2 % 3  //  2
+5.5 % 2 // 1.5
+
+ +

被除数为负数

+ +
-12 % 5 // -2
+-1 % 2  // -1
+-4 % 2  // -0
+ +

被除数为NaN

+ +
NaN % 2 // NaN
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Remainder operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.remainder")}}

+ +

相关链接

+ + + + diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" new file mode 100644 index 0000000000..da2f04c775 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/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 +--- +
{{JSSidebar("Operators")}}
+ +

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) ({{JSxRef("null")}} 或者 {{JSxRef("undefined")}}) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

+ +

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}
+ + + +

语法

+ +
obj?.prop
+obj?.[expr]
+arr?.[index]
+func?.(args)
+
+ +

描述

+ +

通过连接的对象的引用或函数可能是 undefinednull 时,可选链操作符提供了一种方法来简化被连接对象的值访问。

+ +

比如,思考一个存在嵌套结构的对象 obj。不使用可选链的话,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:

+ +
let nestedProp = obj.first && obj.first.second;
+ +

为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出错误。

+ +

有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:

+ +
let nestedProp = obj.first?.second;
+ +

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.first null 或者 undefined,表达式将会短路计算直接返回 undefined

+ +

这等价于以下表达式,但实际上没有创建临时变量:

+ +
let temp = obj.first;
+let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
+ +

可选链与函数调用

+ +

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。

+ +

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

+ +
let result = someInterface.customMethod?.();
+ +
+

注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 {{JSxRef("TypeError")}} 异常 (x.y is not a function).

+
+ +
+

注意: 如果 someInterface 自身是 null 或者 undefined ,异常 {{JSxRef("TypeError")}} 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写 someInterface?.customMethod?.()

+
+ +

处理可选的回调函数或者事件处理器

+ +

如果使用解构赋值来解构的一个对象的回调函数或 fetch 方法,你可能得到不能当做函数直接调用的不存在的值,除非你已经校验了他们的存在性。使用?.的你可以忽略这些额外的校验:

+ +
//  ES2019的写法
+function doSomething(onContent, onError) {
+  try {
+    // ... do something with the data
+  }
+  catch (err) {
+    if (onError) { // 校验onError是否真的存在
+      onError(err.message);
+    }
+  }
+}
+
+ +
// 使用可选链进行函数调用
+function doSomething(onContent, onError) {
+  try {
+   // ... do something with the data
+  }
+  catch (err) {
+    onError?.(err.message); // 如果onError是undefined也不会有异常
+  }
+}
+
+ +

可选链和表达式

+ +

当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:

+ +
let nestedProp = obj?.['prop' + 'Name'];
+ +

可选链不能用于赋值

+ +
let object = {};
+object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
+ +

可选链访问数组元素

+ +
let arrayItem = arr?.[42];
+ +

例子

+ +

基本例子

+ +

如下的例子在一个不含 bar 成员的 Map 中查找 bar 成员的 name 属性,因此结果是 undefined

+ +
let myMap = new Map();
+myMap.set("foo", {name: "baz", desc: "inga"});
+
+let nameBar = myMap.get("bar")?.name;
+ +

短路计算

+ +

当在表达式中使用可选链时,如果左操作数是 nullundefined,表达式将不会被计算,例如:

+ +
let potentiallyNullObj = null;
+let x = 0;
+let prop = potentiallyNullObj?.[x++];
+
+console.log(x); // x 将不会被递增,依旧输出 0
+
+ +

连用可选链操作符

+ +

可以连续使用可选链读取多层嵌套结构:

+ +
let customer = {
+  name: "Carl",
+  details: {
+    age: 82,
+    location: "Paradise Falls" // details 的 address 属性未有定义
+  }
+};
+let customerCity = customer.details?.address?.city;
+
+// … 可选链也可以和函数调用一起使用
+let duration = vacations.trip?.getTime?.();
+
+ +

使用空值合并操作符

+ +

{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}可以在使用可选链时设置一个默认值:

+ +
let customer = {
+  name: "Carl",
+  details: { age: 82 }
+};
+let customerCity = customer?.city ?? "暗之城";
+console.log(customerCity); // “暗之城”
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#prod-OptionalExpression', 'optional expression')}}Stage 4
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.operators.optional_chaining")}}

+ +

Implementation Progress

+ +

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 Test262, the standard test suite of JavaScript, in the nightly build, or the latest release of each browser's JavaScript engine.

+ +

{{EmbedTest262ReportResultsTable("optional-chaining")}}

+
+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" "b/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" new file mode 100644 index 0000000000..20eece2691 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" @@ -0,0 +1,106 @@ +--- +title: 按位与 (&) +slug: Web/JavaScript/Reference/Operators/按位与 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND +--- +
{{jsSidebar("Operators")}}
+ +

按位与运算符 (&) 在每个位上返回 1 ,这两个操作数对应的位都是 1.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and.html")}}
+ + + +

语法

+ +
a & b
+
+ +

描述

+ +

操作数被转换为32位整数,并由一系列位(0和1)表示。 超过32位的数字将丢弃其最高有效位。 例如,以下大于32位的整数将被转换为32位整数:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

+ +

将运算符应用于每对位,然后按位构造结果。

+ +

与运算的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任何数字x0进行按位与运算将得出0

+ +

示例

+ +

使用按位与

+ +
// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+5 & 2; // 0
+ +

规范说明

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseANDExpression', 'Bitwise AND expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_and")}}

+ +

参阅

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" new file mode 100644 index 0000000000..6da432b4e6 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" @@ -0,0 +1,79 @@ +--- +title: 相加运算符 (+) +slug: Web/JavaScript/Reference/Operators/相加 +translation_of: Web/JavaScript/Reference/Operators/Addition +--- +
{{jsSidebar("相加运算符")}}
+ +

相加运算符 (+) 用于对两个操作数进行相加运算,如果操作数为字符串则该运算符将两个操作数连接成一个字符串。

+ +
{{EmbedInteractiveExample("pages/js/expressions-addition.html")}}
+ +
+ + + +

语法

+ +
表达式: x + y
+
+ +

示例

+ +

数字的相加运算

+ +
// Number + Number -> addition
+1 + 2 // 3
+
+// Boolean + Number -> addition
+true + 1 // 2
+
+// Boolean + Boolean -> addition
+false + false // 0
+
+ +

字符串相加运算

+ +
// String + String -> concatenation
+'foo' + 'bar' // "foobar"
+
+// Number + String -> concatenation
+5 + 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+'foo' + false // "foofalse"
+ +

注: '+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换

+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-addition-operator-plus', 'Addition operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.addition")}}

+ +

参考

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" new file mode 100644 index 0000000000..e100ec1d2d --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" @@ -0,0 +1,125 @@ +--- +title: 相等(==) +slug: Web/JavaScript/Reference/Operators/相等 +tags: + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/Equality +--- +
{{jsSidebar("Operators")}}
+ +

等于运算符(==)检查其两个操作数是否相等,并返回Boolean结果。与严格相等运算符(===)不同,它会尝试强制类型转换并且比较不同类型的操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-equality.html")}}
+ +

语法

+ +
x == y
+
+ +

描述

+ +

相等运算符(==!=)使用抽象相等比较算法比较两个操作数。可以大致概括如下:

+ + + +

此运算符与严格等于===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。

+ +

例子

+ +

没有类型转换的比较

+ +
1 == 1;              // true
+"hello" == "hello";  // true
+ +

与类型转换比较

+ +
"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
+ +

对象比较

+ +
const object1 = {"key": "value"}
+const object2 = {"key": "value"};
+
+object1 == object2 // false
+object2 == object2 // true
+ +

比较字符串和String对象

+ +

请注意,使用构造的字符串new String()是对象。如果将其中之一与字符串文字进行比较,则该String对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是String对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:

+ +
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
+ +

比较日期和字符串

+ +
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
+ +

技术指标

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.operators.equality")}}

+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" new file mode 100644 index 0000000000..06ce40ad0b --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" @@ -0,0 +1,75 @@ +--- +title: 管道操作符 +slug: Web/JavaScript/Reference/Operators/管道操作符 +tags: + - Experimental + - JavaScript + - Operator + - 语法糖 + - 链式 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator +--- +
{{jsSidebar("Operators")}} {{SeeCompatTable}}
+ +

试验性的管道操作符 |> (目前其标准化流程处于 stage 1 阶段)允许以一种易读的方式去对函数链式调用。本质上来说,管道操作符是单参数函数调用的语法糖,它允许你像这样执行一个调用:

+ +
let url = "%21" |> decodeURI;
+ +

使用传统语法写的话,等效的代码是这样的:

+ +
let url = decodeURI("%21");
+
+ +

语法

+ +
expression |> function
+ +

例子

+ +

函数链式调用

+ +

当链式调用多个函数时,使用管道操作符可以改善代码的可读性。

+ +
const double = (n) => n * 2;
+const increment = (n) => n + 1;
+
+// 没有用管道操作符
+double(increment(double(5))); // 22
+
+// 用上管道操作符之后
+5 |> double |> increment |> double; // 22
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
Pipeline operator draftStage 1Not part of the ECMAScript specification yet.
+ +

浏览器兼容性Edit

+ +
+ + +

{{Compat("javascript.operators.pipeline")}}

+
+ +

参见

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" "b/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" new file mode 100644 index 0000000000..f405740df3 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" @@ -0,0 +1,85 @@ +--- +title: 自减 (--) +slug: Web/JavaScript/Reference/Operators/自减 +tags: + - JavaScript + - 自减 + - 语法特性 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Decrement +--- +
{{jsSidebar("Operators")}}
+ +

 自减运算符(--) 将它的操作数减一,然后返回操作数.

+ +
{{EmbedInteractiveExample("pages/js/expressions-decrement.html")}}
+ +
+ + + +


+ 语法

+ +
操作符: x-- or --x
+
+ +

语法细节

+ +

如果使用后缀式,即将操作符放在操作数的后面 (如,x--),运算会减一,然后返回减一之前的值。

+ +

如果使用前缀式,即将操作符放在操作数的前面 (如,--x),运算会减一,然后返回减一之后的值。

+ +

示例

+ +

后缀式

+ +
let x = 3;
+y = x--;
+
+// y = 3
+// x = 2
+
+ +

前缀式

+ +
let a = 2;
+b = --a;
+
+// a = 1
+// b = 1
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-postfix-decrement-operator', '自减运算符')}}
+ +


+ 浏览器兼容性

+ + + +

{{Compat("javascript.operators.decrement")}}

+ +

相关链接

+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" "b/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" new file mode 100644 index 0000000000..de38317f42 --- /dev/null +++ "b/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" @@ -0,0 +1,137 @@ +--- +title: 逻辑与(&&) +slug: Web/JavaScript/Reference/Operators/逻辑和 +translation_of: Web/JavaScript/Reference/Operators/Logical_AND +--- +
{{jsSidebar("Operators")}}
+ +

The logical AND (&&) 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 && 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.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-and.html", "shorter")}}
+ + + +

Syntax

+ +
expr1 && expr2
+
+ +

Description

+ +

If expr1 can be converted to true, returns expr2; else, returns expr1.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ + + +

Even though the && 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 boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Short-circuit evaluation

+ +

The logical AND expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

+ +

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr 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:

+ +
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)
+
+ +

Operator precedence

+ +

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

+ +
true || false && false      // returns true, because && is executed first
+(true || false) && false    // returns false, because operator precedence cannot apply
+ +

Examples

+ +

Using AND

+ +

The following code shows examples of the && (logical AND) operator.

+ +
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
+ +

Conversion rules for booleans

+ +

Converting AND to OR

+ +

The following operation involving booleans:

+ +
bCondition1 && bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2)
+ +

Converting OR to AND

+ +

The following operation involving booleans:

+ +
bCondition1 || bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 && !bCondition2)
+ +

Removing nested parentheses

+ +

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

+ +

The following composite operation involving booleans:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

is always equal to:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-LogicalANDExpression', 'Logical AND expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_and")}}

+ +

See also

+ + -- cgit v1.2.3-54-g00ecf