关于js中类型转换的问题

先来看一个栗子:

if('0.00'){
  console.log('0.00')
}
var obj = {
    valueOf: function(){ return {} }, 
    toString: function(){ return {} }
}
console.log(obj == 0)

知道上面的栗子输出上面吗?

首先,JavaScript的内置类型有:nullundefinednumberstringbooleanobjectsymbol(ES6)。除去object,其他算是基本类型(primitives)。把一个值从一个类型转换成其他的类型的做法叫做类型转换。可以是显示的,也可以是隐式的

抽象值操作

类型的转换涉及到了转换的基本规则,这里介绍ToStringToNumberToBooleanToPrimitive

ToString

参数结果
undefined"undefined"
null"null"
Boolean"false" or "true"
Number将数字转化成字符串,如"1.1"
String不变
Object ToPrimitiveToString

ToNumber

参数结果
undefinedNaN
null+0
Booleanfalse->0, true->1
Number不变
String转换规则间下面*
Object ToPrimitiveToNumber

String 的ToNumber规则。字符串和数字的字面量差不多(其他情况转化为NaN),即:

  1. 允许字符串前后有空白符

  2. 允许前面是0而不会被转化为8进制

  3. 允许用+/-代表符号位

  4. 只有空白符的情况下,转化为0

ToBoolean

参数结果
undefinedfalse
nullfalse
Boolean不变
Number0,NaN->false; other->true
Stringlength等于0->false; other->true
Objecttrue

ToPrimitive

参数结果
undefined不变
null不变
Boolean不变
Number不变
String不变
Object转化规则见下面*

这里涉及到了ToPrimitive ( input [, PreferredType] )input为输入的值, PreferredType为可选项(默认情况下是Number。另一个是String,作用和Number相反,先执行toString(),在执行valueOf())。

默认情况下(PreferredType为Number),内部先执行valueOf()得到的值如为primitive(基本类型)则输出结果,否则再执行toString()得到的值如为primitive则输出结果,否则报错。

两种转换

理解了上面的抽象值操作,就可以来看一下下面两种不同的转换。

显式转换

String():满足ToString转换规则

String(null) //"null"

Number():满足ToNumber转换规则

Number(' 010 ') //10

Boolean:满足ToBoolean转换规则

Boolean([1, 2, 3]) //true

parseInt(string, radix):满足ToString转换规则

var a = {
  //先执行toString
  toString: function () {
    return {}
  },
  //再执行valueOf
  valueOf: function () {
    return 0x10
  }
}
parseInt(a) //16

需要注意的是,由于a是对象,需要通过ToPrimitive得到Primitive(此时ToPrimitive ( input [, PreferredType] )PreferredTypeString),再将ToString(Primitive)得到"0x10"

隐式转换

一元操作符+:满足ToNumber转换规则

var a = "6";
+a + 6 //12

二元操作符 +

  1. 分别计算左右操作数,得到lval,rval。(有步骤合并省略)

  2. lprim = ToPrimitive(lval)。

  3. rprim = ToPrimitive(rval)。

  4. 如果lprim或rprim是字符串,都转换为字符串然后相加返回。

  5. 都转换为数字相加后返回。

[1, 2] + 1 //"1,21"

二元操作符 -

  1. 分别计算左右操作数,得到lval,rval。(有步骤合并省略)

  2. lnum = ToNumber(lval)。

  3. rnum = ToNumber(rval)。

  4. 相减后返回。

[1, 2] - 1 //NaN

条件 if(express)(||、&&、三元...):满足ToBoolean转换规则

if (' ') {
  console.log('blank')
} 
//blank

==运算

Type(x)Type(y)Result
两者类型相同遵循===运算
nullUndefinedtrue
Undefinednulltrue
NumberStringx == toNumber(y)
StringNumbertoNumber(x) == y
Boolean(any)toNumber(x) == y
(any)Booleanx == toNumber(y)
String or NumberObjectx == toPrimitive(y)
ObjectString or NumbertoPrimitive(x) == y
otherwise… false
var a = {
  toString () {
    console.log('toString');
    return '1'
  },
  valueOf () {
    console.log('valueOf');
    return 1
  }
}
console.log('1' == a) // true

===运算

Type(x)ValuesResult
两者类型不一样 false
Undefined or Null true
Number两者数值一样(非NaN)true
String两者完全一样true
Boolean两者一样true
Object两者指向同一个对象true
otherwise… false

关系比较(如<)

主要步骤:首先都转换为基础类型,如果都是字符串,按字符串比较;否则都转数字比较。

下面借用网上的图

==运算
==

===运算
===

参考

Truth, Equality and JavaScript
You-Dont-Know-JS笔记之类型和语法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值