JavaScript强制类型转换

类型

在说JavaScript的强制类型转换之前,我们先了解下JavaScript中的数据类型有哪些。JavaScript中类型分为以下两种:

  • 原始数据类型:null、undefined、bool、string、number、boolean以及symbol(es6提出)
  • 对象数据类型:Object(function、date 等属于Object的子类型)

那么这两种数据类型有什么区别呢?

原始数据类型在内存中的存放地点是存放在栈中,所以在传递的过程中,是值传递。

而对象数据类型的存放方式是:真实数据存放在堆中,而在栈中存放的是指向实际数据存储的地方,即堆的指针。

这也就是值传递和引用传递。

字符串、数字和布尔类型之间的转换

ToString

它负责处理非字符串到字符串的转换。

基本类型值的转换规则是:null转换为”null”,undefined转换为”undefined”,布尔转换成对应的数字:true转换为1,false转换为0。数字直接转换为对应的字符串。

对应对象,除非对象内部定义了tostring方法,否则toString()(Object.prototype.toString())返回其内部属性[[class]]的值。如果内部自定义了toString方法,则调用该内部方法并使用其返回值。

对象的强制类型转换为string是通过Toprimitive抽象操作来完成的。

ToPrimitive(input,PreferredType?):其中PreferredType为number或者string。

如果input是原始值,则返回该原始值对应的字符串。

如果input不是原始值,则调用valueOf()方法,如果该方法返回原始值,则使用该方法返回值。

如果valueOf()返回的不是原始值,则调用toString()方法,如果该方法返回原始值,则使用该方法返回的原始值。

否则,报错TypeError

JSON字符串化

工具函数JSON.stringify可以将JSON对象序列化为字符串,内部也是调用了ToString。

JSON.stringify使用规则:对于基本数据类型的值,使用JSON.stringify和使用toString返回结果一样。对于所有安全的JSON值,都可以使用JSON.stringify方法,所谓的JSON安全值是指:除了undefined、symbol、function以及包含循环引用的对象。

JSON.stringify接收第二个参数:可以为字符串数组或者函数。如果是一个字符串数组,则根据数组内的元素,返回指定的对象属性和属性值。如果为函数,则为过滤函数,接收两个参数,key、value,我们可以根据自己的需要自行设定返回值。如果不需要某个属性,返回undefined即可过滤。

JSON.stringify接收第三个参数:用于指定输出字符串的输出格式。

如果对象内部有自定义的toJSON方法,则使用该方法。

var obj = {
  a:10,
  b:0,
  // toJSON:function(){
  //     return 0
  // }
};
let str = JSON.stringify(obj,function(key,value){//过滤函数
  if(key === 'a'){
    return 100
  }else{
    return value
  }
});
let o = JSON.parse(str,function(key,value){//还原函数
  if(key === 'a'){
    return 1
  }else{
    return value
  }
})
console.log(o);

ToNumber

用来将非数字处理成数字。转换方式遵循ToPrimitive,

ToBoolean

JavaScript中的值大概可以分为两类:

  • 可以被强制转换为false的值,如:undefined、null、false、+0、-0、NaN和””
  • 其他可以被转换为true的值

假值对象:封装了假值的对象。

var a = new Boolean( false );//true
var b = new Number( 0 );//true
var c = new String( "" );//true

它们的值为true,但是如果对其进行强制类型转换,则结果为false。

强制类型转换

隐式强制类型转换

字符串和数字的隐式强制转换

运算符:

var a = "42";
var b = "0";
var c = 42;
var d = 0;
a + b; // "420"
c + d; // 42

var a = [1,2];
var b = [3,4];
a + b; // "1,23,4"

根据 ES5 规范 11.6.1 节,如果某个操作数是字符串或者能够通过以下步骤转换为字符串 的话,+ 将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用 ToPrimitive 抽象操作(规范 9.1 节),该抽象操作再调用 [[DefaultValue]](规范 8.12.8 节),以数字作为上下文。

宽松相等和严格相等

宽松相等(loose equals)== 和严格相等(strict equals)=== 都用来判断两个值是否“相等”,但是它们之间有一个很重要的区别,特别是在判断条件上。

  • == 在相等比较中,允许进行类型转换
  • === 不允许类型转换
抽象相等
  • 如果表达式两端都是null、undefined,则为true。
  • 如果NaN在其中一端,则返回false。
  • 如果是string、number、boolean并且类型不一致,则先使用ToNumber转换为number在比较。
  • 如果是对象,则使用ToPrimitive,获取原始值再比较。

显示类型转换

字符串和数字的显示强制转换
var a = 42;
var b = String( a );
var c = "3.14";
var d = Number( c );
b; // "42"
d; // 3.14

String(..) 遵循前面讲过的 ToString 规则,将值转换为字符串基本类型。Number(..) 遵循 前面讲过的 ToNumber 规则,将值转换为数字基本类型。

运算符

字位运算符只适用于 32 位整数,运算符会强制操作数使用 32 位 格式。这是通过抽象操作 ToInt32 来实现的

ToInt32:先试用ToNumber转换为数字,再执行ToInt32。

~~:~~ 中的第一个 ~ 执行 ToInt32 并反转字位。然后第二个 ~ 再进行一次字位反转,即将所有 字位反转回原值

parseInt:只支持字符串解析成数字。

~~和parseInt的区别:

1、解析成数字允许字符串中有非数字字符,从左到右依次解析,遇到非数字字符停止解析

2、强制转换成数字,不允许存在非数字字符,否则转换失败NaN

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!