是否缺少强制转换_JavaScript类型转换(一)

ed30f092f6956352aefd5dc88c53afb6.png

对语言引擎和开发人员来说,类型是值的内部特征,它定义了值的行为,以使其区别于其他值。

JavaScript中的变量是没有类型的, 只有值才有。 变量可以随时持有任何类型的值 。

在对变量执行typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类型。

1. 内置类型

JavaScript有七种内置类型:

null、undefined、boolean、number、string、object、symbol (ES6中新增):

typeof undefined === “undefined";
typeof true === “boolean";
typeof 10 === “number";
typeof ”10" === "string";
typeof {foo: 10} === “object";
typeof Symbol() === “symbol";

null比较特殊:

typeof null === “object";

一般这样检查null:

var foo = null;
!foo && typeof foo ==="object";

也可以利用Object.prototype.toString去检查:

Object.prototype.toString.call(null); //"[object Null]”

还有一种情况:

typeof function foo(){} === “function";

function实际上是object的一个“子类型”。具体来说,函数是“可调用对象”,它有一个内部属性[[Call]],该属性使其可以被调用。


2. 强制类型转换规则

将值从一种类型转换为另一种类型通常称为类型转换。在JavaScript中一般都称之为强制类型转换。

JavaScript中的强制类型转换总是返回标量基本类型值(字符串、数字和布尔值),不会返回对象和函数。

2.1 ToPrimitive

为了将对象转换为相应的基本类型值,JavaScript转换规则中定义了抽象操作 ToPrimitive:

如果目标类型是Number:

  1. 首先检查该值是否有 valueOf 方法。 如果有并且返回基本类型值,就使用该值进行强制类型转换
  2. 否则,就使用 toString的返回值来进行强制类型转换
  3. 如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误

如果目标类型是String:

  1. 首先检查该值是否有 toString 方法。 如果有并且返回基本类型值,就使用该值进行强制类型转换
  2. 否则,就使用 valueOf的返回值来进行强制类型转换
  3. 如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误

下面看几个示例:

根据目标类型不同,调用不同的方法:

var foo = {
  valueOf: function(){
    return '10';
  },
  toString: function(){
    return '50';
  }
};

Number(foo); //10
String(foo); //'50'

目标类型是Number,但是valueOf返回值不为基本类型,使用toString的返回值:

var foo = {
  valueOf: function(){
    return {};
  },
  toString: function(){
    return '20';
  }
};
Number(foo); //20

目标类型是String,但是toString返回值不为基本类型,使用valueOf的返回值:

var foo = {
  valueOf: function(){
    return 10;
  },
  toString: function(){
    return {};
  }
};
String(foo); // '10'

valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误

var foo = {
  valueOf: function(){
    return {};
  },
  toString: function(){
    return {};
  }
};
Number(foo); //TypeError: Cannot convert object to primitive value
String(foo); //TypeError: Cannot convert object to primitive value

2.2 ToString

基本类型值的字符串化规则:

  • null 转换为 "null”
  • undefined 转换为 "undefined”
  • true 转换为 "true”
  • 数字的字符串化则遵循通用规则,极小和极大的数字使用指数形式
var foo = 10;
String(foo); //'10'

var bar = 1 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
bar.toString(); // “1e+21"

引用类型的字符串化规则遵循ToPrimitive规则。

对普通对象来说,除非自行定义,否则 toString (Object.prototype.toString)返回内部属性 [[Class]] 的值:

var foo = {};
foo.toString();// '[object Object]'

数组的默认toString方法经过了重新定义,将所有单元字符串化以后再用 "," 连接起来:

var foo = [1,2,3];
foo.toString(); // '1,2,3'

toString可以被显式调用,或者在需要字符串化时自动调用。

2.3 ToNumber

有时我们需要将非数字值当作数字来使用,比如数学运算。这时候我们就需要用到ToNumber。

基本类型值的数字化规则:

  • true转换为 1
  • false转换为 0
  • undefined转换为 NaN
  • null转换为 0

ToNumber对字符串的处理基本遵循数字常量的相关规则,处理失败时返回NaN:

var foo = '10';
Number(foo); //10
foo = 'a11';
Number(foo); //NaN

对象(和数组)的数字化遵循ToPrimitive的规则。会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

2.3 ToBoolean

JavaScript中有两个关键词true和false,分别代表布尔类型中的真和假 。

  1. 假值(falsy value) :
  • undefined
  • null
  • false
  • 0 (+0 和 -0)
  • NaN
  • ""

假值的布尔强制类型转换结果为false:

Boolean(undefined); //false
Boolean(null); //false
Boolean(false); //false
Boolean(0); //false
Boolean(-0); //false
Boolean(NaN); //false
Boolean(""); //false

2. 假值对象:

浏览器在某些特定情况下,在常规JavaScript语法基础上自己创建了一些外来值,这些就是假值对象

假值对象看起来和普通对象并无二致(都有属性),但将它们强制类型转换为布尔值时结果为false,比如:

Boolean(document.all); //false

3. 真值(truthy value):

假值列表以外的值都是真值。

  • 除“”之外的字符串都是真值
  • []、{} 和 function(){} 都是真值
Boolean(" "); //true
Boolean([]); //true
Boolean({}); //true
Boolean(function (){}); //true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值