js中!和!!的区别及用法,??和?.区别及用法

695 阅读4分钟

JavaScript类型转化

我们知道JavaScript是一门弱类型的语言,但是,在使用中有时需要强制转化为相应的类型。 这里提到类型转换不得不提两个概念:显式转换和隐式转换。

显式转换(强制)

人为的转换,可以更加直观的阅读代码。

显式转化:

  • 转换为字符串:toString() 或 String()
  • 转换为数值:Number()、parseInt()、parseFloat()
  • 转换为布尔值:Boolean()
  • 转换为对象:Object()
const a = parseInt('11'); // 11 字符串转数值
const b = false.toString(); // 'false' 布尔值转字符串 
//注意:toString不可以转null和underfined,String都可以转
const c = Boolean([]); // true 对象类型转换为布尔值
const d = Object(123); // new Number(123) 原始值通过Number()构造函数转换为基本包装类型

隐式转换

当运算符在运算时,两边类型不统一,JavaScript 解释器会在运算之前将它们的类型进行转换再进行运算。

JavaScript 中,表达式中包含以下运算符时,会发生隐式类型转换:

  1. 算术运算符:加(+)、减(-)、乘(*)、除(/)、取模(%);
  2. 逻辑运算符:逻辑与(&&)、逻辑或(||)、逻辑非(!);
  3. 字符串运算符:+、+=。
  4. 逻辑语句的类型转换:当使用if、while、for 时,隐式转换为布尔值;
const a = '111'+0; //a的结果为数值型;
const b = 111+''; //b的结果为字符串类型;
  • string + number字符串加数字,数字会转换为字符串;

  • string + Object字符串加引用类型,对象转为字符串时, 由于对象的toString() 方法没有正确解析对象为字符串,就会转换为[object Object];需要JSON.stringfy()将对象转化为json字符串;

    let o = { nama: 'xxx' };
    console.log("o:"+o); //o:[object Object]
    console.log("o:"+JSON.stringify(o)); //o:{"nama":"xxx"}
    
  • number - string数字减字符串,字符串会转换为数字,如果字符串无法转换为数字(例如"abc"、“JavaScript”),则会转换为 NaN;

  • string - number字符串减数字,字符串会转换为数字,如果字符串无法转换为数字,则会转换为 NaN;即优先向数字转换。

  • 乘、除运算时,也会先将字符串转换为数字。

    可以巧妙地记一下,当字符串和数字同时存在时,除了加号运算符转化为字符串,其他减、乘和除都优先转化为数字。

JavaScript类型转换表,参自《JavaScript权威指南》

20201224162417396.png

js中!和!!的区别及用法

js中 ! 的用法是比较灵活的,它除了做逻辑运算常常会用!做类型判断,可以用 ! 与上对象来求得一个布尔值

  1. ! 可将变量转换成boolean类型,null、undefined和空字符串取反都为true,其余都为false。
!null=true
 
!undefined=true
 
!''=true
 
!100=false
 
!'abc'=false
  1. !! 常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算。 判断变量a为非空,未定义或者非空串才能执行方法体的内容。
let a; // null、undefined、''、0
if (a !== null && typeof a !== 'undefined' 
    && a !== undefined && a !== '' && a !== 0) {
    //a为true时才执行,或者说a为真值时才执行
}

我们只需要写一个判断表达:

let a;
if (!!a) {
    //a为true时才执行,或者说a为真值时才执行
}
if(!!item.value){
    //value有真值时才执行
}

这样省很多代码。

js ??和?.区别及用法

空值合并操作符( ?? )

空值合并操作符( ?? )是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。 空值合并操作符( ?? )与逻辑或操作符( || )不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。

const a = null || undefined;
const b = a ?? 1; // 1
const c = '';
const d = c ?? 1; //''
​
// ||
function(obj){
    let a = obj || {}
}
// 等价于
function(obj){
    let a;
    if(obj === 0 || obj === "" || obj === false 
        || obj === null || obj === undefined){
    a = {}
    } else {
    a = obj;
    }
}
​
//  ??
 
function(obj){
    let a = obj ?? {}
}
 
 // 等价于
function(obj){
    let a;
    if( obj === null || obj === undefined){
    a = {}
     } else {
    a = obj;
    }
}
可选链操作符( ?. )

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。( ?. ) 操作符的功能类似于( . )链式操作符,不同之处在于,在引用为空(null 或者 undefined ) 的情况下不会引起错误,该表达式短路返回值是 undefined 。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

const have = {
  name: '蜡笔小新',
  dog: {
    name: '小白'
  }
const x = have.cat?.name; 
console.log(x); // undefined
console.log(have.childMethod?.()); // undefined
​
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()

ES2022 又加了 ??= 空赋值运算符

逻辑空赋值运算符 (a ??= b)仅在 a 是 null 或 undefined 时对其赋值。

let a = 0;
a ??= 1;
console.log(a); // 0
 
let b = null;
b ??= 1;
console.log(b); // 1

参考:

[显式转换和隐式转换]  blog.csdn.net/Dreamy_LIN/… 

ES6中js的运算符(?.、?:、? ?、? ?=、)