javascript中的隐式转换

121 篇文章 3 订阅
  • 前言

javascript是一门残疾的垃圾语言,有很多莫名其妙的隐式转换,产生一些正常人难以理解的结果。

参考:https://www.cnblogs.com/chenmeng0818/p/5954215.html

  • 基本类型

基本类型  number、string、boolean、null、undefined、object、symbol

  • 运算符的隐式转换

*, /,和%等算术运算符都会把操作数转换成数字的,但是“+”号很特殊,有些情况下,它是算术加号,有些情况下,是字符串连接符号,具体的要看它的操作数

  1. 例子1:
const log = console.log;
//基本类型  number、string、boolean、null、undefined、object、symbol
log("'3' * 5 = ", ('3' * 5));//'3' * 5 =  15
log("3+ true = ", (3 + true));//3+ true =  4
log("3 + false = ", (3 + false));//3 + false =  3
log("8 + null = ", (8 + null));//8 + null =  8
log("8 + undefined = ", (8 + undefined));//8 + undefined =  NaN   
log("1+2+'3' = ", (1 + 2 + '3'));//1+2+'3' =  33
log("'3' + 2 = ", ('3' + 2));//'3' + 2 =  32   字符串与数字相加,把数字转成字符串
log("'3' + true = ", ('3' + true));//'3' + true =  3true
log("'7' + null = ", ('7' + null));//'7' + null =  7null
log("'7' + undefined = ", ('7' + undefined));//'7' + undefined =  7undefined
log("'7'*undefined = ",('7'*undefined));
log("'7'*null = ",('7'*null));
log("'7'*true = ",('7'*true));
log("'7'*false = ",('7'*false));
log("'7'*2 = ",('7'*2));
log("6*undefined = ",(6*undefined));
log("6*null = ",(6*null));
log("6*true = ",(6*true));
log("6*false = ",(6*false));
log("6*2 = ",(6*2));

log("end")

 结果:

'3' * 5 =  15 
3+ true =  4  
3 + false =  3
8 + null =  8       
8 + undefined =  NaN
1+2+'3' =  33       
'3' + 2 =  32       
'3' + true =  3true
'7' + null =  7null
'7' + undefined =  7undefined
'7'*undefined =  NaN
'7'*null =  0
'7'*true =  7
'7'*false =  0
'7'*2 =  14
6*undefined =  NaN
6*null =  0
6*true =  6
6*false =  0
6*2 =  12
end
  • 几个undefined、null、[]的隐式转换

 代码:

const log = console.log;
let a = 7.38923;
log("null == undefined : ", (null == undefined));
log("null == 0 : ", (null == 0));
log("0 == undefined : ", (0 == undefined));
log("'' == null : ", ('' == null));
log("'' == undefined : ", ('' == undefined));
log("[] == null : ", ([] == null));
log("[] == undefined : ", ([] == undefined));
log("[] == '' : ", ([] == ''));
log("Number('null') : ", Number('null'));
log("Number('undefined') : ", Number('undefined'));
log("Number(NaN) : ", Number(NaN));
log("Number([]) : ", Number([]));
log("Number('') : ", Number(''));
log("Number('0') : ", Number('0'));
log("Number('  ') : ", Number('  '));
log("NaN == NaN : ", (NaN == NaN))
log("Number.NaN == NaN : ", (Number.NaN == NaN))
log("typeof(null)  : ", typeof (null))
log("typeof(undefined) : ", typeof (undefined))
log("typeof(NaN) : ", typeof (NaN))
log("end")


结果:

PS E:\study\js\two\src> node .\testjs.js
null == undefined :  true
null == 0 :  false
0 == undefined :  false
'' == null :  false
'' == undefined :  false
[] == null :  false
[] == undefined :  false
[] == '' :  true
Number('null') :  NaN
Number('undefined') :  NaN
Number(NaN) :  NaN
Number([]) :  0
Number('') :  0
Number('0') :  0
Number('  ') :  0
NaN == NaN :  false
Number.NaN == NaN :  false
typeof(null)  :  object
typeof(undefined) :  undefined
typeof(NaN) :  number
end

 

  • 对象的隐式转换

所有对象继承了Object.prototype的两个转换方法:

第一个是toString(),它的作用是返回一个反映这个对象的字符串;

第二个是valueOf(),它的作用是返回它相应的原始值;

但一些内置对象重写了这两个方法,下面展示了一些内置对象调用这两个方法的返回情况。

类型toStringvalueOf
Object返回"[object ObjectName]",其中 ObjectName 是对象类型的名称。对象本身。这是默认情况。
String返回 String 对象的值字符串值。
Number返回数值的字符串表示。还可返回以指定进制表示的字符串,请参考Number.toString()数字值。
Boolean如果布尔值是true,则返回"true"。否则返回"false"。Boolean 值。

Array

将 Array 的每个元素转换为字符串,并将它们依次连接起来,两个元素之间用英文逗号作为分隔符进行拼接。数组本身

Date

返回日期的文本表示。存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC
Function返回如下格式的字符串,其中 functionname 是一个函数的名称,此函数的 toString 方法被调用: "function functionname() { [native code] }"函数本身。

 

那么toString和valueOf分别什么时候调用呢?

原始类型(primitive value)包括以下几类:null,undefined,string,number,boolean。

如果valueOftoString返回非primitive value,它们将被忽略。如果都不存在或都不返回primitive value,则抛出TypeError: Cannot convert object to primitive value。

例子2:

const log = console.log;
function Dog(name, age) {
    this.name = name;
    this.age = age;
}

Dog.prototype.toString = function () {
    return "dog tostr " + this.name + "  " + this.age;
}
let dog1 = new Dog('aname', 8);
let dog2 = new Dog('bname', 7);

log("'a'+ dog1 = ", ('a' + dog1));
log("'a'+dog2 = ", ('a' + dog2));
log("dog1.toString() = ", dog1.toString());
log("dog2.toString() = ", dog2.toString());
log('dog1 = ', dog1, ",    valueOf = ", dog1.valueOf());
log('dog2 = ', dog2, ",   valueOf = ", dog2.valueOf());

log("'a1.toString() = ", 'a1'.toString(), ",   'a1'.valueOf = ", 'a1'.valueOf());
let num = 32;
log("typeof(num.toString()) = ", typeof (num.toString()), ",  typeof(num.valueOf()) = ", typeof (num.valueOf()));

let bl = true;
log("typeof(bl.toString()) = ", typeof (bl.toString()), ",  typeof(bl.valueOf()) = ", typeof (bl.valueOf()));


log("function Dog = ", Dog, ",  typeof(Dog) = ", typeof (Dog));
log("function Dog.toString() = ", Dog.toString(), ",  typeof(Dog.toString()) = ", typeof (Dog.toString()));
log("function Dog.valueOf() = ", Dog.valueOf(), ",  typeof(Dog.valueOf() = ", Dog.valueOf());
log("end")

结果:

'a'+ dog1 =  adog tostr aname  8
'a'+dog2 =  adog tostr bname  7
dog2.toString() =  dog tostr bname  7
dog1 =  Dog { name: 'aname', age: 8 } ,    valueOf =  Dog { name: 'aname', age: 8 }
dog2 =  Dog { name: 'bname', age: 7 } ,   valueOf =  Dog { name: 'bname', age: 7 }
'a1.toString() =  a1 ,   'a1'.valueOf =  a1
typeof(num.toString()) =  string ,  typeof(num.valueOf()) =  number
function Dog =  [Function: Dog] ,  typeof(Dog) =  function
function Dog.toString() =  function Dog(name, age) {
    this.name = name;
    this.age = age;
} ,  typeof(Dog.toString()) =  string
function Dog.valueOf() =  [Function: Dog] ,  typeof(Dog.valueOf() =  [Function: Dog]
end
PS E:\study\js\two\src> node .\testjs.js
'a'+ dog1 =  adog tostr aname  8
'a'+dog2 =  adog tostr bname  7
dog1.toString() =  dog tostr aname  8
dog2.toString() =  dog tostr bname  7
dog1 =  Dog { name: 'aname', age: 8 } ,    valueOf =  Dog { name: 'aname', age: 8 }
dog2 =  Dog { name: 'bname', age: 7 } ,   valueOf =  Dog { name: 'bname', age: 7 }
'a1.toString() =  a1 ,   'a1'.valueOf =  a1
typeof(num.toString()) =  string ,  typeof(num.valueOf()) =  number
typeof(bl.toString()) =  string ,  typeof(bl.valueOf()) =  boolean
function Dog =  [Function: Dog] ,  typeof(Dog) =  function
function Dog.toString() =  function Dog(name, age) {
    this.name = name;
    this.age = age;
} ,  typeof(Dog.toString()) =  string
function Dog.valueOf() =  [Function: Dog] ,  typeof(Dog.valueOf() =  [Function: Dog]
end
  • 其它隐式转换

  •  对象和布尔值比较

对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字

例子:

const log = console.log;
log("[] == false ", ([] == false), ",  [] === false ", ([] === false));
log("'' == false ", ('' == false), ",  '' === false ", ([] === false));
log("end")

结果:

[] == false  true ,  [] === false  false
'' == false  true ,  '' === false  false
end
  • 对象和字符串比较

对象和字符串进行比较时,对象转换为字符串,然后两者进行比较。

[1,2,3] == '1,2,3' // true  [1,2,3]转化为'1,2,3',然后和'1,2,3', so结果为true;
  • 对象和数字比较

对象和数字进行比较时,对象先转换为字符串,然后转换为数字,再和数字进行比较。

[1] == 1;  // true  `对象先转换为字符串再转换为数字,二者再比较 [1] => '1' => 1 所以结果为true
  • 字符串和数字比较

字符串和数字进行比较时,字符串转换成数字,二者再比较。

'1' == 1 // true
  • 字符串和布尔值比较

字符串和布尔值进行比较时,二者全部转换成数值再比较。

'1' == true; // true 
  • 布尔值和数字比较

布尔值和数字进行比较时,布尔转换为数字,二者比较。

true == 1 // true

 

许多刚接触js的童鞋看到这么多的转换规则就懵圈了,其实规律很简单,大家可以记下边这个图

如图,任意两种类型比较时,如果不是同一个类型比较的话,则按如图方式进行相应类型转换,如对象和布尔比较的话,对象 => 字符串 => 数值 布尔值 => 数值。

  • 另外,我们来看下一些需要"特别照顾"的。

来看一个有趣的题

例子:

const log = console.log;
log("[] == false ",([] == false));
log("![] == false ",(![] == false));
log("end")

结果:

[] == false  true
![] == false  true
end

这两个的结果都是true,第一个是,对象 => 字符串 => 数值0 false转换为数字0,这个是true应该没问题,
第二个前边多了个!,则直接转换为布尔值再取反,转换为布尔值时,空字符串(''),NaN,0,null,undefined这几个外返回的都是true, 所以! []这个[] => true 取反为false,所以![] == false为true。

还有一些需要记住的,像:

undefined == null //true undefined和null 比较返回true,二者和其他值比较返回false
Number(null) //0

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值