本文是 JavaScript 中各操作符相关的内容(ECMA 标准)。

位(&,|,^)

ECMA: 13.12.1 Runtime Semantics: Evaluation

& 位“与”操作。

| 位“或”操作。

^ 位“异或”操作。

INFO

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression

  1. Return ? EvaluateStringOrNumericBinaryExpression(BitwiseANDExpression, &, EqualityExpression).

    BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression

  2. Return ? EvaluateStringOrNumericBinaryExpression(BitwiseXORExpression, ^, BitwiseANDExpression).

    BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression

  3. Return ? EvaluateStringOrNumericBinaryExpression(BitwiseORExpression, |, BitwiseXORExpression).

EvaluateStringOrNumericBinaryExpression(leftOperand, opText, rightOperand):

1
2
3
4
5
6
7
function EvaluateStringOrNumericBinaryExpression(leftOperand, opText, rightOperand) {
  let lref = leftOperand()
  let lval = GetValue(lref)
  let rref = rightOperand()
  let rval = GetValue(rref)
  return ApplyStringOrNumericBinaryOperator(lval, opText, rval)
}

ApplyStringOrNumericBinaryOperator(lval, opText, rval)

opText 支持的 操作符类型(table-1):

opTextoperation
**T::exponentiate
*T::multiply
/T::divide
%T::remainder
+T::add
-T::subtract
<<T::leftShift
>>T::signedRightShift
>>>T::unsignedRightShift
&(与)T::bitwiseAND
^(异或)T::bitwiseXOR
T::bitwiseOR
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function ApplyStringOrNumericBinaryOperator(lval, opText, rval) {
  assert(opText in Table1)
  if (opText === '+') {
    let lprim = ToPrimitive(lval)
    let rprim = ToPrimitive(rval)
    if (isString(lprim) || isString(rprim)) {
      let lstr = ToString(lprim)
      let rstr = ToSring(rprim)
      return concat(lstr, rstr)
    }
    lval = lprim
    rval = rprim
  }

  // 到这里将只会是数字操作
  let lnum = ToNumeric(lval)
  let rnum = ToNumeric(rval)
  if (Type(lnum) !== Type(rnum)) {
    throw new TypeError('...')
  }
  let T = Type(lnum)
  let operation = ({
    '**': 'T::exponentiate',
    '*' : 'T::multiply',
    '/': 'T::divide',
    '%': 'T::remainder',
    '+': 'T::add',
    '-': 'T::subtract',
    '<<': 'T::leftShift',
    '>>': 'T::signedRightShift',
    '>>>': 'T::unsignedRightShift',
    '&': 'T::bitwiseAnd',
    '^': 'T::bitwiseXOR',
    '|': 'T::bitwiseOR',
  })[opText]

  return operation(lnum, rnum)
}