一、!!
!!常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
判断变量a为非空,未定义或者非空串才能执行方法体的内容。
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执行的代码
}
实际上我们只需要写一个判断表达:
if(!!a){
//a有内容才执行的代码...
}
第一个"!"是转为布尔数据类型,第二个自己猜猜就知道是什么意思了
可以总结出来,“!”是逻辑与运算,并且可以与任何变量进行逻辑与将其转化为布尔值,“!!”则是逻辑与的取反运算,尤其后者在判断类型时代码简洁高效,省去了多次判断null、undefined和空字符串的冗余代码。
二、可选链(?.)
let a;
let b;
if(!!a){
b = a.name;
}else{
b = undefined;
}
只有当a存在的时候,我才会去访问a的name属性,如果你想再进一步处理,还可以继续判断以下a的数据类型.可是这不是我们今天的重点,就不多讲了.我们可以看到,这样一个简单的逻辑,我们就要写这么多的东西,那么有没有简单的写法呢?看下面的例子
let a;
let b = a?.name;
我们终于看到.?这个东西了,其实这个就叫做可选链,表达的意思,就和刚才if else的例子是一个意思,只有当a存在,同时a具有name属性的时候,才会把值赋给b,否则就会将undefined赋值给b.重要的是,不管a存在与否,这么做都不会报错.
当然我们还可以这么干!!!
let a;
let b;
b = a?.name?.age?.haha?.就是不报错
a?.b?.c(“还是不报错”)
我们看到,你后面可以无限接龙下去,不论有多少属性,只要有最后可以访问到属性,访问到最终的结果,就会赋值给b,否则,就把undefined赋值给b.(这样才有资格叫链式结构嘛)
三、空值合并运算符(??)
有了上面的例子,接下来我们简单一点,直接上举例
let b;
let a = 0;
let c = { name:'buzhimingqianduan' }
if(!!a || a === 0 ){
b = a;
}else{
b = c;
}
对就是上面那个例子,当我们想判断一个值存在,但是它等于0的时候,我们也需要当作它存在,于是就有了上面那样的例子,其实我们还可以这样做
let b;
let a = 0;
let c = { name:'buzhimingqianduan' }
b = a ?? c;
上面的例子,当a除了undefined、或者null之外的任何值,b都会等于a,否则就等于c.
四、空值赋值运算符(??=)
和上面的例子类似
let b = '你好';
let a = 0
let c = null;
let d = ’123‘
b ??= a; // b = “你好”
c ??= d // c = '123'
当??=左侧的值为null、undefined的时候,才会将右侧变量的值赋值给左侧变量.其他所有值都不会进行赋值.同样在一些场景下,可以省略很多代码.
五、“<<”运算符
“<<”运算符执行左移位运算。在移位运算过程中,符号位始终保持不变。如果右侧空出位置,则自动填充为 0;超出 32 位的值,则自动丢弃。
把数字 5 向左移动 2 位,则返回值为 20。
console.log(5 << 2); //返回值20
用算式进行演示,如图所示。
六、“>>”运算符
“>>”运算符执行有符号右移位运算。与左移运算操作相反,它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。移动过程中超出的值将被丢弃。
把数值 1000 向右移 8 位,则返回值为 3。
console.log(1000 >> 8); //返回值3
用算式进行演示,如图所示。当符号位值为 1 时,则有效位左侧的空位全部使用 1 进行填充。
七、“>>>”运算符
“>>>”运算符执行无符号右移位运算。它把无符号的 32 位整数所有数位整体右移。对于无符号数或正数右移运算,无符号右移与有符号右移运算的结果是相同的。
下面两行表达式的返回值是相同的。
console.log(1000 >> 8); //返回值3
console.log(1000 >> 8); //返回值3
对于负数来说,无符号右移将使用 0 来填充所有的空位,同时会把负数作为正数来处理,所得结果会非常大所以,使用无符号右移运算符时要特别小心,避免意外错误。
console.log(-1000 >> 8); //返回值 -4
console.log(-1000 >>> 8); //返回值 16777212
用算式进行演示,如图所示。左侧空位不再用符号位的值来填充,而是用 0 来填充。
八、& (与运算符)
1.特点:二元操作符,操作两个二进制数据;两个二进制数最低位对齐,只有当两个对位数都是1时才为1,否则为0
2.案例:
console.log(3 & 2)//结果为 2
3.分析:
3的二进制补码表示为:
00000000 00000000 00000000 00000011
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:3 & 2
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000010
-------------------------------------------
00000000 00000000 00000000 00000010 二进制是2
九、| (或运算符)
1.特点:二元操作符,操作两个二进制数据;两个二进制数最低位对齐,当两个对位数只要有一个是1则为1,否则为0
2.案例:
console.log(3 | 2); //结果为 3
3.分析:
3的二进制补码表示为:
00000000 00000000 00000000 00000011
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:3 | 2
00000000 00000000 00000000 00000011
| 00000000 00000000 00000000 00000010
-------------------------------------------
00000000 00000000 00000000 00000011 该补码对应十进制为3
十、|= 运算符
或等符号
例如a |= 5
等价于 a = a|5
或运算(位运算)的方法:
1|1=1
1|0=1
0|1=1
0|0=0
十一、^ (异或运算符)
1.特点:二元操作符,操作两个二进制数据;两个二进制数最低位对齐,只有当两个对位数字不同时为1,相同为0
2.案例:
console.log(3 ^ 2); //结果为 1
3.分析:
3的二进制补码表示为:
00000000 00000000 00000000 00000011
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:3 ^ 2
00000000 00000000 00000000 00000011
^ 00000000 00000000 00000000 00000010
-------------------------------------------
00000000 00000000 00000000 00000001 该补码对应十进制为1
十二、~ (非运算符)
1.特点:一元操作符,
2.规则:生成与输入位相反的值–若出入0,则输出1;若输入1,则输入0
3.案例:
console.log(~ 2); // -3
4.分析:
2的二进制补码表示为:
00000000 00000000 00000000 00000010
运算:
~ 00000000 00000000 00000000 00000010
------------------------------------------
11111111 11111111 11111111 11111101 //该补码对应十进制为:-3
十三、规范注释
@param @argument 指定参数名和说明来描述一个函数参数
@returns 描述函数的返回值
@author 指示代码的作者
@deprecated 指示一个函数已经废弃,而且在将来的代码版本中将彻底删除。要避免使用这段代码
@see 创建一个HTML链接,指向指定类的描述
@version 指定发布版本
@requires 创建一个HTML链接,指向这个类所需的指定类
@throws @exception 描述函数可能抛出的异常的类型
{@link} 创建一个HTML链接,指向指定的类。这与@see很类似,但{@link}能嵌在注释文本中
@fileoverview 这是一个特殊的标记。如果在文件的第一个文档块中使用这个标记,则指定该文档块的余下部分将用来提供这个文件的概述
@class 提供类的有关信息,用在构造函数的文档中
@constructor 明确一个函数是某个类的构造函数
@type 指定函数的返回类型
@extends 指示一个类派生了另一个类。JSDoc通常自己就可以检测出这种信息,不过,在某些情况下则必须使用这个标记
@private 指示一个类或函数是私有的。私有类和函数不会出现在HTML文档中,除非运行JSDoc时提供了–private命令行选项
@final 指示一个值是常量值。要记住JavaScript无法真正保证一个值是常量
@ignore JSDoc忽略有这个标记的函数
/**
* @description 加法运算
* @param {Num} num1 加数
* @param {Num} num2 被加数
* @return {Num} result 结果
*/
...
十四、typescript 命名空间namespace
作用:代表内部模块,将项目模块化,减少全局变量,避免污染全局,提供逻辑分组和避免命名冲突
namespace xx{
内容...
需要暴露的内容
export ...
}
命名空间在js文件中会被转换成
var xx;
(function(){
多个类会被分别放进自启动函数中
var 类名=(function(){
内容1...
})
var 类名=(function(){
内容2...
})
其他内容会不变
暴露的内容:
xx.名称=变量名
})(xx || xx={})