JavaScript 隐式类型转换规则详解

目录
  • 前言
  • 数学运算符中的类型转换
    • 减、乘、除
  • 逻辑语句中的类型转换
    • 单个变量
    • 使用 == 比较
    • ToPrimitive

前言

在 JavaScript 中,在进行运算操作时,如果两边数据不统一,这时我们编译器会自动将运算符两边的数据做一个数据类型转换再进行计算。这种由编译器进行自动转换的方式被称为隐式转换。

数学运算符中的类型转换

减、乘、除

在对非 Number 类型运用数学运算符(-*/)时,会先将非 Number 类型转换为 Number 类型再进行计算。示例如下:

2 - true  // 结果为 1,首先把 true 转换为数字 1,然后执行 2 - 1
2 - null  // 结果为 0,首先把 null 转换为数字 0,然后执行 2 - 0
2 - undefined  // 结果为 NaN,因为 undefined 被转换为 NaN,然后执行 2 - NaN
2 * '5'  // 结果为 10,'5' 首先会变成数字 5, 然后执行 2 * 5

注意:在算术运算中,如果操作数中有 undefined,其运算结果是就是 NaNnull 在算术运算中则是隐式转换为数值 0 来参与运算。

为什么加法要区别对待?因为 js 中 + 还可以用来拼接字符串。

加法运算遵守以下 3 条规则,优先级从高到低

当一侧为 String 类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。

当一侧为 Number 类型,另一侧为原始类型,则将原始类型转换为 Number 类型。

当一侧为 Number 类型,另一侧为引用类型,将引用类型和 Number 类型转换成字符串后拼接。

示例如下:

123 + '123'  // 246 (规则1)
123 + null  // 123 (规则2)
123 + true  // 124 (规则2)
123 + undefined  // NaN (规则2)
123 + {}  // 123[object Object] (规则3)

逻辑语句中的类型转换

单个变量

如果只有单个变量,会先将变量转换为 Boolean 值。只有 nullundefined''NaN0false 这几个会被转换为 false,其他的情况都是 true,比如 {} , [] 等。示例如下:

if (null) {
  console.log('111')
} else {
  console.log('222')
}
// 输出 222

使用 == 比较

使用 == 比较,比较规则如下:

NaN 和其他任何类型比较永远返回 false(包括和它自己)。

Boolean 和其他任何类型比较,Boolean 首先被转换为 Number 类型。

StringNumber 比较,先将 String 类型转换为 Number 类型。

null == undefined 比较结果是 true,除此之外,nullundefined 和其他任何类型的比较都为 false

原始类型引用类型 比较时,引用类型会依照 ToPrimitive 规则转换为原始类型。(ToPrimitive 在下面有解释)

示例如下:

NaN == NaN  // false (规则1)

// (规则2)
true == 1  // true
true == '1'  // true
true == '2'  // false
true == ['1']  // true, 先把 true 变成 1, ['1'] 拆箱成 '1', 再参考(规则3)
true == ['2']  // false, 同上

// (规则3)
123 == '123'  // true
'' == 0  // true

// (规则4)
null == undefined  // true
null == ''  // false
null == 0  // false
null == false  // false
undefined == ''  // false
undefined == 0  // false
undefined == false  // false

// (规则5)
'[object Object]' == {}  // true, 字符串和对象比较,对象通过 toString 得到一个基本类型值
'1,2,3' == [1,2,3]  // true, 同上,[1,2,3] 通过 toString 得到一个基本类型值

ToPrimitive

ToPrimitive 规则会尝试调用对象的 valueOftoString 方法,将参数转换为原始类型。

当对象类型需要转为原始类型时,它会先查找对象的 valueOf 方法,如果 valueOf 方法返回原始类型的值,则 ToPrimitive 的结果就是这个值,如果 valueOf 不存在或者 valueOf 方法返回的不是原始类型的值,就会尝试调用对象的 toString 方法,也就是会遵循对象的 ToString 规则,然后使用toString 的返回值作为 ToPrimitive 的结果。

示例如下:

let str = new String(1)  // 通过 new String 创建了一个对象
console.log(typeof str)  // object
console.log(str.valueOf())  // "1"
console.log(typeof str.valueOf())  // string

const obj = {
  valueOf() {
    return 1
  },
  toString() {
    return 2
  }
}
console.log(Number(obj))  // 1

注意:如果 valueOftoString 都没有返回原始类型的值,则会抛出异常。

示例如下:

const obj = {
  valueOf() {
    return []
  },
  toString() {
    return {}
  }
}
console.log(Number(obj))  // TypeError: Cannot convert object to primitive value

特殊:

String({})  // [object Object]
Number([])  // 0

String({}) 空对象会先调用 valueOf,但返回的是对象本身 {},不是原始类型,所以会继续调用toString,得到 [object Object]String([object Object]),所以转换后的结果为 [object Object]

Number([]) 空数组会先调用 valueOf,但返回的是数组本身 [],不是原始类型,所以会继续调用toString,得到 '',相当于 Number(''),所以转换后的结果为 0

以上就是JavaScript 隐式类型转换规则详解的详细内容,更多关于JavaScript 隐式类型转换的资料请关注我们其它相关文章!

(0)

相关推荐

  • JS面试题大坑之隐式类型转换实例代码

    1.1-隐式转换介绍 在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算 这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换 例如1 > "0"这行代码在js中并不会报错,编译器在运算符时会先把右边的"0"转成数字0`然后在比较大小 1.2-隐式转换规则 转成string类型: +(字符串连接符) 2..转成number类型:++/--(自增自减运算符

  • JavaScript隐式类型转换代码实例

    值类型之间的数据类型转换: (1)数字和字符串使用+运算符: 数字和字符串如果使用+运算符进行操作,那么会将数字先转换为字符串,然后进行字符串连接操作: var str = "string text "; var num = 10; console.log(str + num) // "string text 10" (2)布尔值参与的+运算符操作: 如果有布尔型参与,那么首先会将布尔值转换为对应的数字或者字符串,然后再进行相应的字符串连接或者算数运算. var n

  • 有趣的JavaScript隐式类型转换操作实例分析

    本文实例讲述了JavaScript隐式类型转换操作.分享给大家供大家参考,具体如下: JavaScript的数据类型是非常弱的(不然不会叫它做弱类型语言了)!在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加.之所以不同的数据类型之间可以做运算,是因为JavaScript引擎在运算之前会悄悄的把他们进行了隐式类型转换的,如下是数值类型和布尔类型的相加: 3 + true; // 4 结果是一个数值型!如果是在C或者Java环境的话,上面的运算肯定会因为运算符两边

  • JavaScript强制类型转换和隐式类型转换操作示例

    本文实例讲述了JavaScript强制类型转换和隐式类型转换.分享给大家供大家参考,具体如下: 在JavaScript中声明变量不需指定类型, 对变量赋值也没有类型检查,同时JavaScript允许隐式类型转换.这些特征说明JavaScript属于弱类型的语言. (1).转换为字符串 转换为字符串是应用程序中的常见操作,javascript提供了toString方法.多数的JavaScript宿主环境(比如Node.js和Chrome)都提供了全局函数toString: 与此同时Object.p

  • JavaScript中运算符规则和隐式类型转换示例详解

    前言 本文主要给大家介绍了关于JavaScript运算符规则和隐式类型转换的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 隐式类型转换 在 JavaScript 中,当我们进行比较操作或者加减乘除四则运算操作时,常常会触发 JavaScript 的隐式类型转换机制:而这部分也往往是令人迷惑的地方.譬如浏览器中的 console.log 操作常常会将任何值都转化为字符串然后展示,而数学运算则会首先将值转化为数值类型(除了 Date 类型对象)然后进行操作. 我们首先来

  • JavaScript显式数据类型转换详解

    基本概念 将值从一种类型转换为另一种类型称为类型转换,类型转换总是返回基本类型值,如字符串.数字和布尔值,不会返回引用类型值. 类型转换分为"显式"和"隐式":"显式"转换发生在静态类型语言的编译阶段,而"隐式"转换则发生在动态类型语言的运行时. 显式类型转换 非字符串到字符串的类型转换 toString() 方法 数字.布尔值.字符串和对象都有 toString() 方法,但 null 和 undefined 没有. 例子:

  • 直观详细的typescript隐式类型转换图文详解

    正文 1.unknown是所有类型的父类型,其他类型都可以赋值给 unknown let a: undefined = undefined; let b: null = null; let x2: unknown; x2 = a; //正确 x2 = b; //正确 2.never 是任何类型的子类型,可以赋给任何类型 let a: undefined = undefined; let b: null = null; function err(): never { // OK throw new

  • Javascript Object对象类型使用详解

    目录 1. 生成方法 2. 操作属性 2.1 读取 2.2 赋值 2.3 删除 2.4 遍历 2.5 判断属性是否存在 3. with 语句 总结 1. 生成方法 对象是javaScript中的一种数据类型,它是key-value的合集,是无序的 const obj = { name: 'ian',age: 21}; //key使用变量 const gender = 'gender'; const obj = { [gender]: 'male'}; 对象的key必须符合标识符的规则,写的时候k

  • 通过字节码看java中this的隐式传参详解

    前言 从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在! static与非static方法都是存储java的方法区.在static 方法中,没有this引用,因此无法使用当前类中所定义的变量,而非static方法则会默认传入this. 概述 this关键字,是一个隐式参数,另外一个隐式参数是super. this用于方法里面,用于方法外面无意义. this关键字一般用

  • JavaScript 链式结构序列化详解

    一.概述 在JavaScript中,链式模式代码,太多太多,如下: if_else: if(...){ //TODO }else if(...){ //TODO }else{ //TODO } switch: switch(name){ case ...:{ //TODO break; } case ...:{ //TODO break; } default:{ //TODO } } 疑问:诸如上述这些链式代码,倘若,我们想将其扁平化链式处理呢?如下: //fn1,f2,f3为处理函数 _if(

  • ts 类型体操 Chainable Options 可链式选项示例详解

    目录 问题 答案 传参 option部分 get 问题 在JavaScript我们通常会使用到可串联(Chainable/Pipline)的函数构造一个对象,但是在Typescript中,你能合理地给它赋上类型吗? 题目是: 可以使用任何你喜欢的方式实现这个类型 - interface, type, 或者 class 都行.你需要提供两个函数option(key, value) 和 get() 在 option 中你需要使用提供的key和value来扩展当前的对象类型,通过 get()获取最终结

  • 关于JavaScript和jQuery的类型判断详解

    对于类型的判断,JavaScript用typeof来进行. 栗子: console.log(typeof null); //object console.log(typeof []); //object console.log(typeof {}); //object console.log(typeof new Date()); //object console.log(typeof new Object); //object console.log(typeof function(){});

  • 基于javascript中的typeof和类型判断(详解)

    typeof ECMAScript 有 5 种原始类型(primitive type),即 Undefined.Null.Boolean.Number 和 String.我们都知道可以使用typeof运算符求得一个变量的类型,但是对引用类型变量却只会返回object,也就是说typeof只能正确识别基本类型值变量. var a = "abc"; console.log(typeof a); // "string" var b = 123; console.log(t

  • JavaScript隐式类型转换

    JavaScript的数据类型是非常弱的(不然不会叫它做弱类型语言了)!在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加.之所以不同的数据类型之间可以做运算,是因为JavaScript引擎在运算之前会悄悄的把他们进行了隐式类型转换的,如下是数值类型和布尔类型的相加: 复制代码 代码如下: 3 + true; // 4 结果是一个数值型!如果是在C或者Java环境的话,上面的运算肯定会因为运算符两边的数据类型不一致而导致报错的!但是,在JavaScript中,只

随机推荐

其他