关于javascript:JavaScript八种数据类型最全总结检测与转换

5次阅读

共计 7110 个字符,预计需要花费 18 分钟才能阅读完成。

数据类型

数据类型检测

typeof

可检测根本数据类型和 function,无奈检测援用数据类型

var arr = [
    null,      // object
    undefined, // undefined
    true,      // boolean
    12,        // number
    'haha',    // string
    Symbol(),  // symbol
    20n,       // bigint
    function(){}, // function
    {},        // object
    [],        // object]
for (let i = 0; i < arr.length; i++) {console.log(typeof arr[i])
}

instanceof

无奈检测根本数据类型,可检测 function、援用类型和继承关系

var arr = [// { 'value': null, 'type': null}, ----> error
    // {'value': undefined, 'type': undefined},   ----> error
    {'value': true, 'type': Boolean},      // false
    {'value': 12, 'type': Number},         // false
    {'value': 'haha', 'type': String},     // false
    {'value': Symbol(), 'type': Symbol},   // false
    {'value': 20n, 'type': BigInt},        // false
    {'value': function(){}, 'type': Function}, // true
    {'value': {}, 'type': Object},         // true
    {'value': [], 'type': Array},          // true
]
for (let i = 0; i < arr.length; i++) {console.log(arr[i].value instanceof arr[i].type)
}

instanceof 除了能够检测类型外,还能够在继承关系的检测中应用

function Aoo(){} 
function Foo(){} 
Foo.prototype = new Aoo(); // JavaScript 原型继承
 
var foo = new Foo(); 
console.log(foo instanceof Foo) // true 
console.log(foo instanceof Aoo) // true

constructor

提醒:虽可检测,但 prototype 可被改写,constructor 会扭转,不倡议应用该办法判断。

var arr = [// { 'value': null, 'type': Null}, ----> error
    // {'value': undefined, 'type': Undefined},   ----> error
    {'value': true, 'type': Boolean},     // true
    {'value': 12, 'type': Number},        // true
    {'value': 'haha', 'type': String},    // true
    {'value': Symbol(), 'type': Symbol},  // true
    {'value': 20n, 'type': BigInt},       // true
    {'value': function(){}, 'type': Function}, // true
    {'value': {}, 'type': Object},       // true
    {'value': [], 'type': Array},        // true
]
for (let i = 0; i < arr.length; i++) {console.log(arr[i].value.constructor == arr[i].type)
}

Object.prototype.toString.call()

个别类型都能检测,倡议应用。

var arr = [null,        // [object Null]
    undefined,   // [object Undefined]
    true,        // [object Boolean]
    12,          // [object Number]
    'haha',      // [object String]
    Symbol(),    // [object Symbol]
    20n,         // [object BigInt]
    function(){},// [object Function]
    {},          // [object Object]
    [],          // [object Array]
    new Date(),  // [object Date]
    new RegExp(),// [object RegExp]
    new Error(), // [object Error]
]
for (let i = 0; i < arr.length; i++) {console.log(Object.prototype.toString.call(arr[i]))
}

数据类型转换

将值从一种类型转换为另一种类型通常称为类型转换(type casting),这是显式的状况;隐式的状况称为强制类型转换(coercion)。

类型转换产生在动态类型语言的编译阶段,而强制类型转换则产生在动静类型语言的运行时(runtime)。

强制类型转换又分以下两种:

  • 显式强制类型转换(explicit coercion)
  • 隐式强制类型转换(implicit coercion)

形象操作

“形象操作”(即“仅供外部应用的操作”),是 js 的内置函数。

String()

解决非字符串到字符串的强制类型转换。对根本类型无效,对援用类型 (object) 有效。

String(12);           // "12"
String("haha");       // "haha"
String(null);         // "null"
String(undefined);    // "undefined"
String(true);         // "true"
String({a: '12'});    // [object Object]
value 值 原始类型 转换后
12 number “12”
haha string “haha”
null null “null”
undefined undefined “undefined”
true boolean “true”
{a: ’12’} object [object Object]

JSON.stringify(..)

JSON 字符串化和 toString() 的成果基本相同,只不过序列化的后果总是字符串。

1. 平安的 JSON 值转换

JSON.stringify(12);           // "12"
JSON.stringify("str");        // ""str""
JSON.stringify(null);         // "null"
JSON.stringify(true);         // "true"
JSON.stringify({a: '12'});    // "{"a":"12"}"
value 值 原始类型 转换后
12 number “number”
haha string “”haha””(含有双引号的字符串)
null null “null”
true boolean “true”
{a: ’12’} object “{“a”:”12″}”

2. 不平安的 JSON 值转换

JSON.stringify(..) 在对象中遇到 undefinedfunctionsymbol 会主动将其疏忽 ,在
数组中则会返回 null(以保障单元地位不变)。

JSON.stringify(undefined);    // undefined
JSON.stringify(function(){}); // undefined
JSON.stringify([ 1, undefined, function(){}, 4]
); // "[1, null, null, 4]"
JSON.stringify({ a:2, b:function(){}}
); // "{"a":2}

对蕴含循环援用的对象执行 JSON.stringify(..) 会出错

var o = { };
var a = { 
    b: 42,
    c: o, // 循环援用
    d: function(){}
};
// 在 a 中创立一个循环援用
o.e = a;
// 循环援用在这里会产生谬误
// JSON.stringify(a);
// JSON.stringify(o);

3. 自定义 JSON 序列化

var a = { 
    b: 42,
    c: 'haha',
    d: function(){}
};
// 自定义的 JSON 序列化
a.toJSON = function() {
    // 序列化仅蕴含 b
    return {b: this.b};
};

JSON.stringify(a); // "{"b":42}"

Number()

解决非数字值到数字的强制类型转换, 解决失败时返回 NaN。

Number("33");            // 33
Number(null);            // 0
Number(undefined);       // NaN
Number(true);            // 1
Number(false);           // 0
Number({a: '12'});       // NaN
Number(function(){});    // NaN
value 值 原始类型 转换后 value 值
“33” string 33
<span class=”red”>null</span> null <span class=”red”>0</span>
undefined undefined NaN
true boolean 1
false boolean 0
{a: ’12’} object NaN

八进制和十六进制

  • 如果前缀为 0,则 JavaScript 会把数值常量解释为八进制数
  • 如果前缀为 0 和 “x”,则解释为十六进制数
// 八进制的 377 ->  十进制 255
Number(0377); // 255
// 十六进制 -> 十进制的 255
Number(0xFF); // 255

对象和数组

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

为了将值转换为相应的根本类型值,形象操作会查看该值是否有 valueOf() 办法。如果有并且返回根本类型值,就应用该值进行强制类型转换。如果没有就应用 toString()
的返回值(如果存在)来进行强制类型转换。如果 valueOf() 和 toString() 均不返回根本类型值,会产生 TypeError 谬误。

从 ES5 开始,应用 Object.create(null) 创立的对象 [[Prototype]] 属性为 null,并且没有 valueOf() 和 toString() 办法,因而无奈进行强制类型转换。

var a = {valueOf: function(){return "42";}
};
var b = {toString: function(){return "42";}
};

var c = [4,2];
c.toString = function(){return this.join( ""); //"42"
};
Number(a); // 42
Number(b); // 42
Number(c); // 42
Number(""); // 0
Number([] ); // 0
Number([ "abc"] ); // NaN
Number(['1']);         // 1
Number(['1', '2']);    // NaN

Boolean()

除了假值和假值对象,其余的都能够看做是真值。

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

// 假值对象(浏览器本人创立的对象)Boolean(document.all) // false
...

// 真值
Boolean([]);             // true
Boolean({});             // true
Boolean(function(){});   // true
Boolean(1)               // true
...

显式强制类型转换

字符串与数字

1. String() 和 Number()
2. toString()

toString() 是显式的,不过其中波及隐式转换。因为 toString() 对 number 这样的根本类型值不实用,所以 JavaScript 引擎会主动为 number 类型创立一个封装对象,而后对该对象调用 toString()。这里显式转换中含有隐式转换。

var a = 42;
a.toString(); // "42"
3. 一元运算 +-

一元运算 + 被普遍认为是显式强制类型转换

var c = "3.14";
var d = +c;
var e = -c; // 会反转符号位
var f = - -c; // 两头要有空格

d; // 3.14
e; // -3.14
f; // 3.14

// 日期显式转换为数字
var d = new Date;
+d; // 工夫戳 1595836134918

// 更好的方法(倡议应用)
var timestamp = Date.now()
4. ~ 运算符(非)

~ 运算符(位非)用于对一个二进制操作数逐位进行取反操作。

  • 第 1 步:把运算数转换为 32 位的二进制整数。
  • 第 2 步:逐位进行取反操作。
  • 第 3 步:把二进制反码转换为十进制浮点数。
~12; // -13

~ 和 indexOf() 联合应用

var a = "Hello World";

if (~a.indexOf( "lo")) { // -4 -> 真值 -> true
 // 找到匹配!}

if (!~a.indexOf( "ol")) { // -4 -> 真值 -> true
 // 没有找到匹配!}

显式解析数字字符串

  • Number():将非数字值转换为数字,解决失败时返回 NaN
  • parseInt():仅针对字符串值,其余类型有效,返回一个整数
  • parseFloat():作用和 parseInt() 统一,但可返回浮点数
var a = "42";
var b = "42px";

Number(a); // 42
parseInt(a); // 42

Number(b); // NaN
parseInt(b); // 42

var c = '12.3333'
parseInt(c); // 12
parseFloat(c); // 12.3333

显式转换为布尔值

1. Boolean()
2. !!

一元运算符 ! 显式地将值强制类型转换为布尔值, 它同时还将真值反转为假值(或假值反转为真值)。

显式强制类型转换为布尔值最罕用的方强制类型转换办法是 !!,因为第二个 ! 会将后果反转回原值。

var a = "0";
var b = [];
var c = {};
var d = "";
var e = 0;
var f = null;
var g; // undefined

!!a; // true
!!b; // true
!!c; // true
!!d; // false
!!e; // false
!!f; // false
!!g; // false
value 值 Boolean()转换 !! 转换
“” false false
0 false false
null false false
undefined false false
<span class=”red”>”0″</span> <span class=”red”>true</span> <span class=”red”>true</span>
[] true true
{} true true

在 if(..).. 这样的布尔值上下文中,如果没有应用 Boolean(..) 和 !!,就会主动隐式地进行 ToBoolean 转换。

隐式强制类型转换

主动转换类型

当 JavaScript 尝试操作一个 “ 谬误 ” 的数据类型时,会主动转换为 “ 正确 ” 的数据类型。

5 + null    // 返回 5         null 转换为 0
"5" + null  // 返回 "5null"   null 转换为 "null"
"5" + 1     // 返回 "51"      1 转换为 "1" 
"5" - 1     // 返回 4         "5" 转换为 5
"5" * true  // 返回 5         "true" 转换为 1

主动转换为字符串

当你尝试输入一个对象或一个变量时 JavaScript 会主动调用变量的 toString() 办法:

document.getElementById("demo").innerHTML = myVar;

myVar = {name:"Fjohn"}  // toString 转换为 "[object Object]"
myVar = [1,2,3,4]       // toString 转换为 "1,2,3,4"
myVar = new Date()      // toString 转换为 "Fri Jul 18 2014 09:08:55 GMT+0200"

数字和布尔值也常常互相转换:

myVar = 123             // toString 转换为 "123"
myVar = true            // toString 转换为 "true"
myVar = false           // toString 转换为 "false"

类型转换小结

下表展现了应用不同的数值转换为数字(Number), 字符串(String), 布尔值(Boolean):

原始值 转换为数字 转换为字符串 转换为布尔值
false 0 “”false”” false
true 1 “true” true
0 0 “0” false
1 1 “1” true
“0” 0 “0” true
“000” 0 “000” true
“1” 1 “1” true
NaN NaN “NaN” false
“” 0 “” false
[] 0 “” true
function(){} NaN “function(){}” true
{} NaN “[object Object]” true
null 0 “null” false
undefined NaN “undefined” false
Infinity Infinity “Infinity” true
-Infinity -Infinity “-Infinity” true

经典面试题

1 + '1' 
true + 0
{}+[]
4 + {} 
4 + [1] 
'a' + + 'b'
console.log ([] == 0 )
console.log (! [] == 0 )
console.log ([] == ! [])
console.log ([] == [])
console.log({} == !{})
正文完
 0