【前端面试必会】---- 类型转换 &隐式提升

类型转换 & 隐式提升

最新的ECMScript定义了7种数据类型

原始类型

Booolean Null Undefined Number String Symbol

对象

Object

参考文档

JS类型转换(强制和自动的规则)

类型装换

1、显示类型装换

1.1、Number函数

数值: 数值转换后还是原来的值

字符串:如果可以转换为数值,则转换为响应的数值,否则得到NaN。空字符串转为0

布尔值: true转成1,false转成0.

undefined:转成NaN

null : 转成0

console.log(Number(123))//123

console.log(Number('123'))//123

console.log(Number(false))//0

console.log(Number(true))//1

console.log(Number(undefined))//NaN

console.log(Number(null))//0

对象类型转换:

先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再进行后续步骤。

如果valueOf方法返回复合类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤。

如果toString方法返回的是复合类型的值,则报错。

let a = {b:1}
console.log(a.valueOf())//{ b: 1 }
console.log(a.toString()) //[object Object]
console.log('a', Number(a)) //a NaN

补充说明:

每个对象都有一个toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。

默认情况下,toString()方法被每个Object对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 “[object type]”,其中type是对象的类型。

1.2、 String函数

原始类型转换:

数值:转为响应的字符串

字符串:转换后还是原来的值

布尔值:true转为“true” , false 转为 “false”

undefined: 转为“undefined”

null: 转为"null"

对象类型转换

先调用toString,如果toString方法返回的是原始类型的值,则对该值使用STring方法,不再进行以下步骤。

如果toString方法返回的是符合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

如果valueOf方法返回的是符合类型的值,则报错。

对象操作
Array将 Array 的元素转换为字符串。结果字符串由逗号分隔,且连接起来。
Boolean如果 Boolean 值是 true,则返回 “true”。否则,返回 “false”。
Date返回日期的文字表示法。
Error返回一个包含相关错误信息的字符串。
Function返回如下格式的字符串,其中 functionname 是被调用 toString 方法函数的名称:function functionname( ) { [native code] }
Number返回数字的文字表示。
String返回 String 对象的值。
默认返回 “[object objectname]”,其中 objectname 是对象类型的名称。
let b = {
  b: 1
}
console.log(b.valueOf()) //{ b: 1 }
console.log(b.toString()) //[object Object]
console.log('b', String(b)) //b [object Object]

valueOf返回原始类型

let b = {
  b: 1,
  toString:function (params) {
      console.log(123)
      return {c:123};
  },
  valueOf:function (params) {
      console.log(456)
      return 'b'
  }
}

控制台输出
{ c: 123 }
123
456
b b

valueOf返回对象,报错

let b = {
  b: 1,
  toString:function (params) {
      console.log(123)
      return {c:123};
  },
  valueOf:function (params) {
      console.log(456)
      return {d:123}
  }
}

控制台输出:

{ c: 123 }
123
456
e:\icework\test\a.js:45
console.log('b', String(b)) //b [object Object]
                 ^

TypeError: Cannot convert object to primitive value

下表列出了对象的valueOf()的返回值:

对象返回值
Array数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。
BooleanBoolean 值。
Date存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function函数本身。
Number数字值。
Object对象本身。这是默认情况。
String字符串值。

1.3、Boolean函数

原始类型转换

undefined、null、-0、+0、NaN、’’,这些都会转为false。其他的都转为true.

console.log(Boolean(123)) //true

console.log(Boolean('123')) //true

console.log(Boolean(false)) //false

console.log(Boolean(true)) //true

console.log(Boolean(undefined)) //false

console.log(Boolean(null)) //false

2、隐式类型转换

四则运算:加减乘除

判断语句:三目运算符

Native调用:比如调用console.log、alert,会调用string方法

常见问题:
[] + []

[] + {}

{} + [] //不同浏览器解释不同

{} + {} //[object Object]

true + true //2

1 + {a:1}

关于运算符的那些隐式类型转换

这部分一直是让我琢磨不透的,但是他的确应该有迹可循。

3、 加法运算操作符 加号运算操作符在Javascript也用于字符串连接符,所以加号操作符的规则分两种情况:

如果两个操作值都是数值,其规则为:

(1)如果一个操作数为NaN,则结果为NaN

(2)如果是Infinity+Infinity,结果是Infinity

(3)如果是-Infinity+(-Infinity),结果是-Infinity

(4)如果是Infinity+(-Infinity),结果是NaN

(5)如果是+0+(+0),结果为+0

(6)如果是(-0)+(-0),结果为-0

(7)如果是(+0)+(-0),结果为+0

如果有一个操作值为字符串,则:

如果两个操作值都是字符串,则将它们拼接起来

如果只有一个操作值为字符串,则将另外操作值转换为字符串,然后拼接起来

如果一个操作数是对象、数值或者布尔值,则调用toString()方法取得字符串值,然后再应用前面的字符串规则。

对于undefined和null,分别调用String()显式转换为字符串。

可以看出,加法运算中,如果有一个操作值为字符串类型,则将另一个操作值转换为字符串,最后连接起来


4、 乘除、减号运算符、取模运算符

这些操作符针对的是运算,所以他们具有共同性:如果操作值之一不是数值,则被隐式调用Number()函数进行转换。具体每一种运算的详细规则请参考ECMAScript中的定义。


5、 逻辑操作符(!、&&、||)

5.1、逻辑非(!)操作符首先通过Boolean()函数将它的操作值转换为布尔值,然后求反。

5.2、逻辑与(&&)操作符,如果一个操作值不是布尔值时,遵循以下规则进行转换:

(1)如果第一个操作数经Boolean()转换后为true,则返回第二个操作值,否则返回第一个值(不是Boolean()转换后的值)

(2)如果有一个操作值为null,返回null

(3)如果有一个操作值为NaN,返回NaN

(4)如果有一个操作值为undefined,返回undefined

5.3、逻辑或(||)操作符,如果一个操作值不是布尔值,遵循以下规则:

(1)如果第一个操作值经Boolean()转换后为false,则返回第二个操作值,否则返回第一个操作值(不是Boolean()转换后的值)

(2)对于undefined、null和NaN的处理规则与逻辑与(&&)相同


6、 关系操作符(<, >, <=, >=) 与上述操作符一样,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:

(1)如果两个操作值都是数值,则进行数值比较

(2)如果两个操作值都是字符串,则比较字符串对应的字符编码值

(3)如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较

(4)如果一个操作数是对象,则调用valueOf()方法(如果对象没有valueOf()方法则调用toString()方法),得到的结果按照前面的规则执行比较

(5)如果一个操作值是布尔值,则将其转换为数值,再进行比较

注:NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。


7、 相等操作符(==) 相等操作符会对操作值进行隐式转换后进行比较:

(1)如果一个操作值为布尔值,则在比较之前先将其转换为数值

(2)如果一个操作值为字符串,另一个操作值为数值,则通过Number()函数将字符串转换为数值

(3)如果一个操作值是对象,另一个不是,则调用对象的valueOf()方法,得到的结果按照前面的规则进行比较

(4)null与undefined是相等的

(5)如果一个操作值为NaN,则相等比较返回false

(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象

例题解析

原题:+new Array(017),请问输出是什么?

let a = new Array(017)
console.log(a);
a.valueOf = function () {
  console.log("valueOf被调用了!");
  return a;
};

/*a.toString = function () {
  console.log("toString被调用了!");
}*/


console.log(+a);

console.log(a,a.toString());

console.log(Number(a.toString())

[ <15 empty items> ]
valueOf被调用了!
NaN
[ <15 empty items>, valueOf: [Function] ] ',,,,,,,,,,,,,,'

NaN
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值