JS的数据类型

432 阅读5分钟

一、有哪些数据类型?

JavaScript的数据类型分为两大类,分别为基本数据类型和引用数据类型。

基本类型又叫值类型或者简单类型,包括nullundefinedbooleanstringnumbersymbol。 引用类型又叫复杂类型或者对象类型,包括ObjectArrayDateFunctionMapSet等。

不同的是基本类型的值存储在栈内存中,按值访问。引用类型存储在堆内存中,按引用(地址、指针)访问。

举个例子:

// 基本类型
var a = 5;
var b = a;
b = 8;
console.log(a,b); // 5 8
// 引用类型
var c = { text: 'Hello World!' };
var d = c;
d.text = 'Hi!';
console.log(c.text, d.text); // Hi! Hi!

二、如何判断数据类型?

1、typeof

typeof可以用来检测给定变量的数据类型,它会返回一个表示数据类型的字符串,可能返回7种结果:numberstringbooleanundefinedsymbolobjectfunction

typeof 123; // number
typeof '123'; // string
typeof true; // boolean
typeof undefined; // undefined
typeof Symbol(); // symbol
typeof null; // object
typeof {}; // object
typeof function () {} // function

typeof对于基本类型来说,除了null都可以显示正确的类型。对于引用类型来说,除了函数都会显示object。所以说可以用typeof来判断基本数据类型,但是要注意null的情况。

null返回object是原因是这样的:JavaScript中不同的值在底层都表示为二进制,object在二进制中前三位对应的值是000。而null在二进制中32位都是0,自然前三位也是0。所以typeof null会返回object

2、instanceof

typeof可以用来检测基本类型,但是检测引用类型时并不能返回具体的数据类型,这个时候可以用instanceofinstanceof是通过原型链去判断的,通过测试左边对象的原型链上是否有右边这个对象构造函数的prototype属性来判断的。表达式为:A instanceof B,即判断A是否为B的实例,是则返回true,否则返回false

[] instanceof Array; // true
{} instanceof Object; // true
new Function() instanceof Function; // true
new Date() instanceof Date; // true
new Map() instanceof Map; // true
new Set() instanceof Set; // true
// 数组还可以用ES6新增的Array.isArray()来判断
Array.isArray([]); // true
// instanceof 还可以测试自定义类型
function Person(){};
new Person() instanceof Person; // true
new Person() instanceof Object; // true

值得注意的是所有引用类型用instanceof检测Object都会返回true,这是因为引用数据类型的原型链上都存在有Object属性。即所有引用类型的数据都是Object的实例。

另外,基本数据类型不能通过instanceof来判断。

下面来简单实现一下instanceof

function myInstanceof(A, B) {
    var A = A.__proto__;
    var B = B.prototype;
    while (1) {
        if (A === null) return false;
        else if (A === B) return true;
        A = A.__proto__;
    }
}

3、constructor

constructor即构造函数,作用和instanceof非常相似。它的作用是,可以检测实例对象是由哪一个构造函数产生的。它也可以检测基本数据类型。但是如果重写prototypeconstructor可以会被改变。

function F(){};
var f = new F();
f.constructor === F; // true
// 重写prototype
F.prototype = { a: '' };
var f1 = new F();
f1.constructor === F; // false
// 重写原型时可以给constructor赋值,这样就不会被改变
F.prototype = {
    constructor: F, 
   a: '',
};
var f2 = new F();
f2.constructor === F; // true 
// 基本类型
var num = 1;
num.constructor === Number; // true
'1'.constructor === String; // true
true.constructor === Boolean; // true
Symbol().constructor === Symbol; // true
// 对于特殊的null和undefined,浏览器并不允许在外面访问使用,所以不能用constructor来判断

4、Object.prototype.toString.call()

这个是检测数据类型最推荐最常用的方法,可以更加准确地判断任何数据类型。toStringObject原型对象上的一个方法,这个方法默认返回其调用者的具体类型,用call改变方法中的this关键字的指向,然后返回当前方法的执行主体(方法中this)所属类的详细信息,返回格式为[object String]

toString.call(''); // [object String]
toString.call(1); // [object Number]
toString.call(null); // [object Null]
toString.call(undefined); // [object Undefined]
toString.call(true); // [object Boolean]
toString.call(Symbol()); // [object Symbol]
toString.call({}); // [object Object]
toString.call([]); // [object Array]
toString.call(new Function()); // [object Function]
toString.call(new Date()); // [object Date]
toString.call(new Map()); // [object Map]
toString.call(new Set()); // [object Set]
toString.call(new Error()); // [object Error]

三、数据类型的转换

JavaScript是一种弱类型的语言,也可以说是动态类型的语言。动态类型,就是一个变量可以被赋予不同的数据类型,可以根据使用场景来变化,在计算时可以隐式转换它的类型。

与之不同的是强类型语言(强制数据类型定义的语言),也就是说,如果一个变量被指定了某一个数据类型,那它就一直是这个数据类型。举个例子:如果变量a被指定为整形,那么它就不能作为字符串来使用。如JavaPython就是强类型定义语言。

var num = 1;
console.log(typeof num); // number
num = '1';
console.log(typeof num); // string
num = true;
console.log(typeof num); // boolean
num = new Date();
console.log(typeof num); // object
console.log(1 + '1'); // 11
console.log(1 + true); // 2

数据转换的三种情况

1、转换为布尔值

布尔表示一种逻辑实体,可以有两个值:truefalse。在条件判断时,false''nullundefinedNaN0-0这些值为false,其他都为true

2、转换为字符串 X.toString()、String()、+''

// (1)数字
(11).toString(10); // '11' // 对应的字符串
(12).toString(2); // '1100' // 可以转换为不同的进制
// (2)数组
[1, 2].toString(); // '1,2'
// (3)对象
({}).toString(); // [object Object] // 都会转换为[object Object] 
// (4)其他
true.toString(); // 'true' // 对应的字符串

3、转换为数字 Number()、parseInt()、parseFloat()

// (1)字符串
Number('1'); // 1
Number('a'); // NaN
// (2)boolean
Number(true); // 1 // true转1,false转0
// (3)null
Number(null); // 0
// (4)undefined
Number(undefined); // NaN
// (5)symbol
Number(Symbol()) // 报错
// (6)数组
Number([]); // 0 // 空数组转为0
Number([1]); // 1 // 存在一个元素则将这个元素转为数字
Number([1, 2]); // NaN //存在多个元素则转换为NaN
// (7)除了数组的引用类型
Number({}); // NaN 

小结

1、JavaScript的数据类型分为两大类:基本类型和引用类型。

2、判断数据类型的四种方法:typeofinstanceofconstructorObject.prototype.toSting.call()

3JavaScript数据转换的三种情况:转换为布尔值、字符串或者数字。