“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”
preface
In this article you can learn about JS operators, some features, and some practical usage scenarios
Divided into primary > intermediate > Advanced
If you feel good or if you have anything to add, you can leave a comment
primary
Type conversion
String converts to nubmer
Number conversion some of you might write that
//before
const a = '123'
Number(a) / / 123
Copy the code
You can actually use either *1 or + to do implicit conversion
//after
const a = '123'
console.log(+a) / / 123
console.log(a * 1) / / 123
Copy the code
Additional examples of implicit conversions using +
'123' / / 123
'ds' // NaN
' ' / / 0
null / / 0
undefined // NaN
{ valueOf: () = >'3' } / / 3
Copy the code
The number type is changed to string
//before
const a = 123
String(a) / / '123'
Copy the code
You can use + ‘to do implicit conversion
//after
const a = 123
console.log(a + ' ') / / '123'
Copy the code
Turns a Boolean type
Double!!!!! If cast directly to a Boolean, the true value will be converted to true and the false value will be converted to false
//before
Boolean(1) //true
//after!!!!!123 //true
Copy the code
Use && to make logical decisions
In addition to making conditional judgment, because of its return value characteristics (if the first value is true, return the result of the next value, otherwise directly return the result of the previous value, the next value does not continue to evaluate), can also be used in logical judgment
// Conditional judgment
if(a === 1 && b ===2 ) {
//todo
}
Copy the code
In fact, if can also be used to replace if when the logic inside is not complicated
const arr - [1.2.3]
const index = arr.indexOf(1)
//before
if(index === -1) {
arr.splice(index, 1)}//after
index === -1 && arr.splice(index, 1)
// This can also be simplified by using the bit operator '~', which can be seen further down.
Copy the code
If the value is one of two values, you can also use this shorthand (this is the ES2020 syntax, be compatible).
// return b if a is true, otherwise return A
a &&= b
/ / is equivalent to
a = a && b
Copy the code
Using the | | do variable assignment
| | except for condition judgment, because the return value characteristics (the first value is true, it returns the result of the first value, if the first is false values, continued to check the results back, until the return true, return true, if there is value, not evaluated), can also be used in variable assignment
// Conditional judgment
if(a === 1 || b === 2) {
//todo
}
// Variable assignment
const a = null || 1
console.log(a) / / 1
Copy the code
This abbreviation can also be used when the value is used as the default value, but this is ES2020 writing, so be compatible
// If the box tag has a value, use this value. If it has no value, use the default value
document.getElementById('box').innerHTML ||= '
I'm the default text
'
/ / is equivalent to
document.getElementById('box').innerHTML = document.getElementById('box').innerHTML || '
I'm the default text
'
Copy the code
Optional link operators (? .).
Optional link operators? In phase 4 of the ES2020 proposal, use Babel compatibility
When we use? If the value is false, execution is stopped and undefined is returned
Usually we develop if there is a field in the data at the back end is an array, we need to operate it, in case we will generally make array judgment, to prevent the subsequent execution from being affected because of errors
//before
const data = []
if(data && data.length) {
//todo
}
//after
if(data? .length) {//todo
}
Copy the code
Or if the value of the object might be empty, so calling the method would report an error
constres = obj? .name()// This will not execute, and will not return error, just return undefined
Copy the code
Dynamic variable names and array values can also be followed
constres = datas? .data? .[arrName]? .0]
Copy the code
Null-value merge operator (??)
Null-value merge operator (??) Is a logical operator that returns the right-hand operand if the left-hand operand is null or undefined, otherwise returns the left-hand operand.
?? And | | is a bit like, but the | | is false value judgment,?????? Null and undefined
/ / true value
const a = 1 ?? 'Default value'
console.log(a) / / 1
/ / false values
const a = ' ' ?? 'Default value'
console.log(a) / /"
//null
const a = null ?? 'Default value'
console.log(a) // 'default'
//undefined
const a = undefined ?? 'Default value'
console.log(a) // 'default'
Copy the code
You can also abbreviate it
let a = 1a ?? ='Default value'
/ / is equivalent to
a = a ?? 'Default value'
console.log(a) / / 1
Copy the code
The intermediate
Bitwise non-operator (~)
A brief description of the bitwise non-operator ~
The bitwise non-operator ~ is the binary inverse symbol, the binary inverse symbol, the param 0 is 1,1 is 0,
And there’s a rule that if it’s positive, it’s minus x plus 1.
The following is a 32-bit binary example
1 = 0000 0000 0000 0000 0000 0000 0000 0001
~1 = 1111 1111 1111 1111 1111 1111 1111 1110
Copy the code
Now let’s talk about the situation in which this symbol is used
integer
You can use the two-bit operator ~~ to replace math.floor () for positive numbers and math.ceil () for negative numbers.
When the value is positive
const num = 6.6
//before
Math.floor(num) / / 6
//after
~~num / / 6
Copy the code
When the value is negative
const num = -6.6
//before
Math.ceil(num) / / - 6
//after
~~num / / - 6
Copy the code
Check whether it equals minus 1
The value 0 when ~-1 is used to determine the value of indexOf
const arr = [1.2.3.4.5]
const index = arr.indexOf(1)
// index is 0, ~index is -1, -1 is true
~index && arr.splice(index, 1)
console.log(arr); / / [2, 3, 4, 5]
Copy the code
The bitwise or operator (|)
Simple instructions under the bitwise or operator |
It requires at least two operands to compare, and returns 1 if only one of the counterpoints is 1, or 0 otherwise
Let’s take 10 and 18
10 = 0000 0000 0000 0000 0000 0000 0000 1010
18 = 0000 0000 0000 0000 0000 0000 0001 0010
---------------------------------------------
10 | 18 = 0000 0000 0000 0000 0000 0000 0001 1010 = 26
Copy the code
Here are some scenarios where the bitwise xor operator ^ can be used
integer
Can use or operator | integer
6.66 | 0 / / 6
-6.66 | 0 / / - 6
Copy the code
Instead of Math. The round ()
/ / positive
const a1 = 1.4
const a2 = 1.6
a1 + 0.5 | 0 / / 1
a2 + 0.5 | 0 / / 2
/ / negative
const b1 = -1.4
const b2 = -1.6
b1 + 0.5 | 0 / / - 0
b2 + 0.5 | 0 // -1
Copy the code
Bitwise and operator (&)
Using the bitwise and operator & is actually the result of an alignment of operands.
Returns 0 if one of the counterpoints is 0, or 1 otherwise
10 = 0000 0000 0000 0000 0000 0000 0000 1010
1 = 0000 0000 0000 0000 0000 0000 0000 0001
---------------------------------------------
10 | 1 = 0000 0000 0000 0000 0000 0000 000 0000 = 0
Copy the code
Here are the scenarios in which the bitwise and operator & can be used
Judge odd and even
8 & 1 / / 0
7 & 1 / / 1
// 8 &1 is an odd number, and num &2 is an even number
if(8 & 1) {
// If the logic is odd
}
Copy the code
Check if it is an integer power of 2
const a = 20;
const b = 32;
a & (a - 1) // 16 a is not an integer power of 2
b & (b - 1) // 0 b is an integer power of 2
Copy the code
Bitwise xOR operator (^)
Using the bitwise xor ^ is actually the result of an alignment of operands. Returns 1 if the alignment bits add up to 1, 0 otherwise
Take 32 bits as an example
10 = 0000 0000 0000 0000 0000 0000 0000 1010
18 = 0000 0000 0000 0000 0000 0000 0001 0010
--------------------------------------------
10 ^ 18 = 0000 0000 0000 0000 0000 0000 0001 1000 = 24
Copy the code
Here are the scenarios in which the lower xor operator ^ can be used
Toggle 0 and 1
When you switch on or off a class, you might use a variable to store 0 and 1, but you can toggle ^
//before
let toggle = 0
if(toggle) {
toggle = 1
} else {
toggle = 0
}
// Or use the ternary operator
toggle = toggle ? 0 : 1
Copy the code
It’s easier to do it the way you want to do it
let toggle = 0
toggle ^= 1
console.log(toggle) / / 1
Copy the code
Check whether two numbers have the same sign
const a = 1
const b = 2
const c = -1
const d = -2
(a ^ b) >= 0 // true
(a ^ c) >= 0 // false
(c ^ d) >= 0 // true
Copy the code
Determine whether the integer parts are equal
Because bitwise operators operate on positive numbers
// Both positive numbers
const a = 1
const b = 1
a ^ b / / 0
/ / the decimal point
const a = 1.1
const b = 1.6
a ^ b / / 0
Copy the code
Complete value exchange
We can also swap values of two variables using bitwise xor
let a = 1
let b = 2
a ^= b
b ^= a
a ^= b
console.log(a) / / 2
console.log(b) / / 1
Copy the code
However, this is actually a bit troublesome, in fact, using ES6 deconstruction is more convenient
let a = 1;
let b = 2;
[a, b] = [b, a]
console.log(a) / / 2
console.log(b) / / 1
Copy the code
The advanced
Shift left (<<)
The left shift is denoted by the symbol <<, which, as its name suggests, moves the binary of a numeric value to the left by the specified number of bits, then fills the space with 0, the sign bit unchanged (the highest bit is the sign bit)
2 = 0000 0000 0000 0000 0000 0000 0000 0010
// We move 2 to the left by 5
2 << 5 = 0000 0000 0000 0000 0000 0000 0100 0000 = 64
Copy the code
Left shift can also be used to round
1.66 << 0 / / 1
Copy the code
Move right (>>)
Represented by the symbol >>, the binary of a numeric value is moved to the right by the specified number of bits, with the signed bit unchanged and the empty space filled with 0, which is the opposite of the left shift
2 = 0000 0000 0000 0000 0000 0000 0000 0010
// We move 2 to the right by 2
2 >> 5 = 0000 0000 0000 0000 0000 0000 0000 0000 = 0
// For another example, we move 64 5 places to the right
64 = 0000 0000 0000 0000 0000 0000 0100 0000
64 >> 5 = 0000 0000 0000 0000 0000 0000 0000 0010 = 2
Copy the code
Unsigned right shift (>>>)
The >>> operator performs an unsigned right shift. It shifts all bits of an unsigned 32 – bit integer to the right. For an unsigned or positive right shift operation, the result of an unsigned right shift is the same as that of a signed right shift operation.
// Positive numbers are the same as >>
10 >> 2 / / 2
10 >>> 2 / / 2
// For negative numbers, the unsigned right shift will fill all Spaces with 0, and negative numbers will be treated as positive numbers, resulting in very large results so be careful when using the unsigned right shift operator to avoid accidental errors.
-1 >>> 0 / / 4294967295
Copy the code
Hexadecimal color values and RGB color values convert to each other
We mentioned left shift << and right shift >> earlier, now we show you how to use it
Hexadecimal color value to RGB:
function hexToRGB(hex){
var hex = hex.replace("#"."0x"),
r = hex >> 16,
g = hex >> 8 & 0xff,
b = hex & 0xff;
return "rgb("+r+","+g+","+b+")";
}
hexToRGB("#ffffff") / / RGB (255255255).
Copy the code
RGB to hexadecimal color value:
function RGBToHex(rgb){
var rgbArr = rgb.split(/[^\d]+/),
color = rgbArr[1] < <16 | rgbArr[2] < <8 | rgbArr[3];
return "#"+color.toString(16);
}
RGBToHex("RGB (255255255)") // #ffffff
Copy the code
Use bitwise operators for permission control
Assign permissions
Above we said that moving the binary code to the left << is to move the binary code to the corresponding digit
// The binary of 1 is 00000001
1 << 0 / / 00000001
1 << 1 / / 00000010
1 << 2 / / 00000100
1 << 3 / / 00001000
1 << 4 / / 00010000
1 << 5 / / 00100000.Copy the code
And you can see that there’s only one 1 in each of these numbers, and they’re all different, so if you combine them together, you’re actually going to be unique.
For example, in vuE-next’s PatchFlags. ts file, this section is the type mark of vNode in VisualDOM, which is used to update the DOM tree according to the different vNode type. Let’s look at the type definition
* Patch flags can be combined using the | bitwise operator and can be checked
* using the & operator, e.g.
*
* ` ``js * const flag = TEXT | CLASS * if (flag & TEXT) { ... } * `` `
*
* Check the `patchElement` function in'.. /.. /runtime-core/src/renderer.ts' to see how the
* flags are handled during diff. * /export const enum PatchFlags {
TEXT = 1./ / 1 < < 0
CLASS = 1 << 1,
STYLE = 1 << 2,
PROPS = 1 << 3,
FULL_PROPS = 1 << 4,
HYDRATE_EVENTS = 1 << 5,
STABLE_FRAGMENT = 1 << 6,
KEYED_FRAGMENT = 1 << 7,
UNKEYED_FRAGMENT = 1 << 8,
NEED_PATCH = 1 << 9,
DYNAMIC_SLOTS = 1 << 10.// SPECIAL FLAGS -------------------------------------------------------------
// Special flags are negative integers. They are never matched against using
// bitwise operators (bitwise matching should only happen in branches where
// patchFlag > 0), and are mutually exclusive. When checking for a special
// flag, simply check patchFlag === FLAG.
HOISTED = -1,
BAIL = -2
}
Copy the code
Here the author USES the < < is defined in addition to the type of features of 11 kinds of types, each of which is obtained by the left, the author comments on already gave tips, using | to permissions given, use & for permission to check
Permissions to
| we said above is for the operands are checked, contrapuntal digits only one is 1, it returns 1, otherwise it returns 0
Let’s create a permission and see
const permission = 0 // Initialize the role without permission
const permission1 = permission | TEXT | CLASS | PROPS
---------------------------------------------
// As defined in the file above
TEXT = 0000 0000 0000 0000 0000 0000 0000 0001
CLASS = 0000 0000 0000 0000 0000 0000 0000 0010
PROPS = 0000 0000 0000 0000 0000 0000 0000 1000
permission1 = permission | TEXT | CLASS | PROPS = 0000 0000 0000 0000 0000 0000 0000 1011 = 8
Copy the code
This grants a permission1 permission to manipulate TEXT, CLASS, and PROPS
Permission to check
We said that ampersand is used to compare the operands, and returns 0 if one of the counterpoints is 0, and 1 otherwise.
Now check permissions
// When permissions are granted
permission1 & TEXT
------------------------------------------------
permission1 = 0000 0000 0000 0000 0000 0000 0000 1011
TEXT = 0000 0000 0000 0000 0000 0000 0000 0001
permission1 & TEXT = 0000 0000 0000 0000 0000 0000 0000 0001 = 1 = true
// When there is no permission
permission1 & STYLE
------------------------------------------------
permission1 = 0000 0000 0000 0000 0000 0000 0000 1011
STYLE = 0000 0000 0000 0000 0000 0000 0000 0100
permission1 & STYLE = 0000 0000 0000 0000 0000 0000 0000 0000 = 0 = false
Copy the code
Remove permissions
The essence of a delete permission is to reset a 1 at a specified location to 0
We can use ^, ^ the rule is to return 1 if the alignment bits add up to 1, 0 otherwise
permission1 ^ TEXT
-------------------------------------------
permission1 = 0000 0000 0000 0000 0000 0000 0000 1011
TEXT = 0000 0000 0000 0000 0000 0000 0000 0001
permission1 ^ TEXT = 0000 0000 0000 0000 0000 0000 0000 1010
Copy the code
If you do not have this permission, using ^ will increase the permission
Can be deleted before the judgment, or use &~ to delete
// If the delete permission exists
permission1 & (~TEXT)
-------------------------------------------
permission1 = 0000 0000 0000 0000 0000 0000 0000 1011
~TEXT = 1111 1111 1111 1111 1111 1111 1111 1110
permission1 & (~TEXT) = 0000 0000 0000 0000 0000 0000 0000 1010
// Delete permission does not exist
permission1 & (~STYLE)
--------------------------------------------
permission1 = 0000 0000 0000 0000 0000 0000 0000 1011
~STYLE = 1111 1111 1111 1111 1111 1111 1111 1011
permission1 & (~STYLE) = 0000 0000 0000 0000 0000 0000 0000 1011
Copy the code
reference
# “hardcore JS” will confuse you with bit arithmetic
# js bitwise operator and its clever use