1.new 操作符
- 1-1.定义:new 操作符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
- 1-2.new 操作会执行以下几步:
- ①堆内存中创建一个空对象。
- ②将新建的空对象的原型指向构造函数的原型。
- ③执行构造函数的函数体,创建相关的属性和方法。
- ④判断执行结果是否返回了新的对象,如果有返回新对象,就是用返回的新对象,没有的话,返回原来创建的对象(obj)。
- 1-3.示例:
function constructorFunction(name, age){
this.name = name;
this.age = age;
}
constructorFunction.prototype.say = function(){
return 'Hello '+ this.name
}
let obj = new constructorFunction('willian', 18)
console.log(obj.name, obj.age); // 'willian', 18
console.log(obj.say()); // Hello willian
2.指数操作符
- 2-1.Math.pow()指数操作:console.log(Math.pow(3, 2)) // 9
- 2-3.指数赋值操作符:
let squared = 3;
squared **= 2;
console.log(squared) // 9
let sqrt = 16;
sqrt **= 0.5;
console.log(sqrt) // 4
3.赋值操作符:使用它们不会带来任何性能的提升。
- 3-1.乘/赋值(*=);
- 3-2.除/赋值(/=);
- 3-3.模/赋值(%=);
- 3-4.加/赋值(+=);
- 3-5.减/赋值(-=);
- 3-6.左移/赋值(<<=);
- 3-7.有符号右移/赋值(>>=);
- 3-8.无符号右移/赋值(>>>=);
4.逗号操作符:在用于赋值时,逗号操作符总会返回表达式中的后一项:
var num = (5, 1, 4, 8, 0); // num 的值为 0。
5.关系操作符(<、>、<=、>=)
- 5-1.返回布尔值。
- 5-2.如果两个操作数都是数值,则执行数值比较。
- 5-3.如果两个操作数都是字符串,则逐个比较两个字符串对应的字符编码值。
- 5-4.如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
- 5-5.如果一个操作数是对象,则调用这个对象的 valueOf() 方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf() 方法,则调用 toString() 方法,并用得到的结果根据前面的规则执行比较。
- 5-6.如果一个操作数是布尔值,则先将其转换为数值,再执行比较。
- 5-7.在比较字符串时,实际比较的是两个字符串中对应位置的每个字符的字符编码值。如果要真正按字母表顺序比较字符串,就必须把两个操作数转换为相同的大小写形式(全部大写或全部小写),然后再执行比较。(一般就是第一个字母)。
6.相等操作符
- 6-1.相等和不相等(==、!=);全等和不全等(===、!==);
- 6-2.两个操作符都会先转换操作数(强制转型),然后再比较它们的相等性。
- 6-3.如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值,-false 转换为 0。而 true 转换为1。
- 6-4.如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值。
- 6-5.如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,用得到的基本类型值按照前面的规则进行比较,遵循下列规则:
- ①null和undefined是相等的。
- ②比较相等性之前,不能将null和undefined转换成其他任何值。
- 6-6.如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。重要提示:即使两个操作数都是NaN,相等操作符也返回false。
- 6-7.如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象。则相等操作符返回true;否则,返回false。
- 6-8.===:两个操作数未经转换就相等的情况下返回 true。严格相等。
- 6-9.!==:在两个操作数未经转换就不相等的情况下返回 true。
7.条件操作符:(三目运算符)
variable = boolean_expression ? true_value : false_value;
8.乘性操作符
- 8-1.乘法(*):
- ①如果操作数都是数值,执行常规的乘法计算。如果乘积超过了ECMAScript数值的表示范围,则返回Infinity或-Infinity。
- ②如果有一个操作数是NaN,则结果是NaN。
- ③如果是Infinity与0相乘,则结果是NaN。
- ④如果是Infinity与非0数值相乘,则结果是Infinity或-Infinity,取决于第二个操作数的符号数的符号。
- ⑤如果是Infinity与Infinity相乘,则结果是Infinity。
- ⑥如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。
- 8-2.除法(/):
- ①如果操作数都是数值,执行常规的乘法计算。如果商超过了ECMAScript数值的表示范围,则返回Infinity或-Infinity。
- ②如果有一个操作数是NaN,则结果是NaN。
- ③如果是Infinity被Infinity除,则结果是NaN。
- ④如果是零被零除,则结果是NaN。
- ⑤如果是非零的有限数被零除,则结果是Infinity或-Infinity,取决于第一个操作数的符号。
- ⑥如果是 Infinity 被任何数值除,则结果是Infinity或-Infinity,取决于第二个操作数的符号。
- ⑦如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则.。
- 8-3.求模(%):取余:
- ①如果操作数都是数值,执行常规的除法计算,返回除得的余数。
- ②如果被除数是无穷大值,除数是有限大的数值,则结果是NaN。
- ③如果被除数是有限大的数值,除数是零,则结果是NaN。
- ④如果是Infinity被Infinity除,则结果是NaN。
- ⑤如果被除数是有限大的数值,除数是无穷大的数值,则结果是被除数。
- ⑥如果被除数是零,除数不是零则结果是零。
- ⑦如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。
9.加性操作符
- 9-1.如果两个操作符都是数值:
- ①如果有一个操作数是NaN,则结果是NaN;
- ②如果是Infinity加Infinity,则结果是Infinity;
- ③如果是-Infinity加-Infinity,则结果是-Infinity;
- ④如果是Infinity加-Infinity,则结果是NaN;
- ⑤如果是+0加+0,则结果是+0;
- ⑥如果是-0加-0,则结果是-0;
- ⑦如果是-0加+0,则结果是+0;
- 9-2.如果有一个操作数是字符串:
- ①如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来。
- ②如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。
- ③如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于undefined和null,则分别调用String()函数并取得字符串"undefined"和"null"。
10.减法操作符
- 10-1.如果两个操作符都是数值,执行常规算术减法操作并返回结果。
- 10-2.如果有一个操作数是NaN,则结果是NaN。
- 10-3.如果是Infinity减Infinity,则结果是 NaN。
- 10-4.如果是-Infinity减-Infinity,则结果是 NaN。
- 10-5.如果是 Infinity减-Infinity,则结果是 Infinity。
- 10-6.如果是-Infinity减Infinity,则结果是-Infinity。
- 10-7.如果是+0减+0,则结果是+0。
- 10-8.如果是+0减-0,则结果是-0。
- 10-9.如果是0减0,则结果是+0。
- 10-10.如果有一个操作数是字符串、布尔值、null或undefined,则先在后台调用Number()函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是NaN,则结果为NaN。
- 10-11.如果有一个操作数是对象,则调用对象的valueOf()方法以取得表示该对象的数值。如果得到的值是NaN,则减法的结果就是NaN。如果对象没有valueOf()方法,则调用其toString()方法并将得到的字符串转换为数值。
11.布尔操作符
- 11-1.逻辑非(!):
- ①先会将它的操作数转换为一个布尔值,然后再对其求反。
- ②!!等于使用Boolean()转型函数。
- 11-2.逻辑与(&&):
- ①一假为假,两真为真。
- ②短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。
- ③有一个操作数不是布尔值的情况:
- α:如果第一个操作数是对象,则返回第二个操作数。
- β:如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象。
- γ:如果两个操作数都是对象,则返回第二个操作数。
- δ:如果有一个操作数是null,则返回null。
- ε:如果有一个操作数是NaN,则返回NaN。
- ζ:如果有一个操作数是undefined,则返回undefined。
- 11-3.逻辑或(||):
- ①一真为真,两假为假。
- ②短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。
- ③有一个操作数不是布尔值的情况:
- α:如果第一个操作数是对象,则返回第一个操作数。
- β:如果第一个操作数的求值结果为false,则返回第二个操作数。
- γ:如果两个操作数都是对象,则返回第一个操作数。
- δ:如果两个操作数都是null,则返回null。
- ε:如果两个操作数都是NaN,则返回NaN。
- ζ:如果两个操作数都是undefined,则返回undefined。
12.位操作符
- 12-1.位操作符并不直接操作64位的值。而是先将64位的值转换成32位的整数,然后执行操作,后再将结果转换回64位。
- 12-2.有符号整数使用32位的前31位表示整数值。第32位表示数值的符号,0表正,1表负,这一位称符号位。即左边第一位。
- ①正值以真正二进制格式存储,即31位中的每一位都代表2的幂。
- ②负数以二补数的二进制编码存储。
- α:求这个数值绝对值的二进制码。
- β:求二进制反码,即将0替换为1,将1替换为0。
- γ:得到的二进制反码加1。
- ③对特殊的NaN和Infinity值应用位操作时,这两个值都会被当成0来处理,如果对非数值应用位操作符,会先使用Number()函数将该值转换为一个数值(自动完成)然后再应用位操作。得到的结果将是一个数值。
- 12-3.按位非(~):执行按位非的结果就是返回数值的反码。底层执行操作,因此速度更快。
var num1 = 25; // 二进制 0000 0000 0000 0000 0000 0000 0001 1001
var num2 = ~num1; // 二进制 1111 1111 1111 1111 1111 1111 1110 0110
alert(num2); // -26 按位非操作的本质:操作数的负值减 1
- 12-4.按位与(&):按位与操作只在两个数值的对应位都是1时才返回1,任何一位是0,结果都是0。
let result = 25 & 3;
console.log(result)
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
END = 0000 0000 0000 0000 0000 0000 0000 0001
- 12-5.按位或(|):按位或操作在有一个位是1的情况下就返回1,而只有在两个位都是0的情况下才返回0。
- 12-6.按位异或(^):在两个数值对应位上只有一个1时才返回1,如果对应的两位都是1或都是0,则返回0。
- 12-7.左移(<<):操作符会将数值的所有位向左移动指定的位数,在向左移位后,原数值的右侧多出空位。左移操作会以0来填充这些空位,左移不会影响操作数的符号位。
var oldValue = 2; // 等于二进制的 10
var newValue = oldValue << 5; // 等于二进制的 1000000,十进制的 64
2 = 0000 0000 0000 0000 0000 0000 0000 0010
64 = 0000 0000 0000 0000 0000 0000 0100 0000
- 12-8.有符号的右移(>>):操作符会将数值向右移动,但保留符号位。与左移操作恰好相反。右移空位出现左侧,符号位的值来填充所有空位。
- 12-9.无符号的右移(>>>):
- ①所有位向右移动指定的位数并以0来填充空位。
- ②对正数来说,无符号右移的结果与有符号右移相同。
- ③无符号右移操作符会把负数的二进制码当成正数的二进制码。
var oldValue = -64; // 等于二进制的 11111111111111111111111111000000
var newValue = oldValue >>> 5; // 等于十进制的 134217726
-64 = 1111 1111 1111 1111 1111 1111 1100 0000
var iUnsigned64 = -64 >>> 0;
console.log(iUnsigned64.toString(2));
13.一元操作符
- 13-1.只能操作一个值的操作符叫做一元操作符。
- 13-2.递增和递减操作符。
- ①执行前置递增和递减操作时,变量的值都是在语句被求值以前改变的。
- ②执行后置递增和递减操作时,变量的值都是在语句被求值之后改变的。
var age =29;
console.log(age); // 29
console.log(++age); // 30 输出前执行++操作
console.log(age); // 30
console.log(--age); // 29 输出前执行--操作
console.log(age); // 29
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;
var num4 = num1 + num2;
console.log(num3, num4); // 22 21
- 13-3.一元加和减操作符:
- ①在对非数值应用一元加操作符时,该操作符会像 Number() 转型函数一样对这个值执行转换。
- ②将一元减操作符应用于数值时,该值会变成负数。非数值时,一元减操作符遵循与一元加操作符相同的规则,后再将得到的数值转换为负数。
14.空值合并运算符-(??)
- 14-1.空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
- ①以前的用法,当 || 左侧为 false 值时就赋给变量 || 后面的值。只要属性的值为 null 或 undefined,其余的 false,“”,0,NaN 也要赋值给变量的话,就无法实现。
const headerText = response.settings.headerText || 'Hello, world!';
function Component(props) {
const enable = props.enabled ?? true; // 使用??,可以确保只有 undefined 或者null 时才会使用默认值
// …
}
- 14-2.不能与 & 或 || 操作符共用:空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序 是未定义的。
null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError
(null || undefined ) ?? "foo"; // 返回 "foo"
- 14-4.??=:先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算。
let x = 0;
let y= 45;
x ??= y;
console.log(x); // 0
15.可选链操作符-(?.)
- 15-1.可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
- 15-2.(?.) 操作符的功能类似于.链式操作符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。
- 15-3.与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
- 15-4.用途:
- ①处理可选的回调函数或者事件处理器。
- ②可选链和表达式:当使用方括号与属性名的形式来访问属性时。连用可选链操作符。
- ③可选链不能用于赋值。
- ④可选链访问数组元素。