动态类型
JavaScript是一种弱类型或者说动态语言。它不像C语言或者Java当中需要在定义的时候声明类型,而是会随着数据的类型变化而自动确定,这就意味着同一个变量可能会有不同的数据类型:
var foo = 10; // foo现在是Number类型
foo = "bar"; // foo现在是String类型
foo = true; // foo现在是Boolean类型
类型划分
按照数据的类型来划分,数据应为以下几类:
字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol、对象(Object)、数组(Array)、函数(Function)。
注:Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。
按照数据在内存中存放的位置来划分,数据可以分为两类:
基本类型:也可称为简单类型,它存储在内存栈中,一个内存块存放一个固定的值。
其中包括的类型有: 字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol
引用类型:也可称为复杂类型,存储在内存堆里面,变量内存储的只是一个指向该堆内存的地址。
其中包括的类型有: 对象(Object)、数组(Array)、函数(Function)。
使用区别
因为存储方式的不同,故而在使用时,这两种数据类型也会产生不同的变化。
比如在进行变量的赋值时,基本数据类型的赋值会直接将值复制一份给另一个变量,相互之间不会影响。
var a = 10;
var b = a;
a = 100;
console.log(a, b); // 100 10
而引用类型在进行赋值操作时,会将它指向的内存地址复制一份给另一个变量,两个变量之间的操作会相互影响。
var c = ["hello", "world"];
var d = c;
c[1] = "gril";
console.log(c); //["hello", "gril"]
console.log(d); //["hello", "gril"]
在传递参数的过程当中,基本数据类型在传入函数后,都变成了一个局部对象,所有对局部对象的修改,对原始值都没有影响,而这个局部变量也会在函数执行完毕后立即被销毁。
var str = "bar";
function foo(nStr) {
nStr = "world";
}
foo();
console.log(str); //bar
而如果是引用类型,因为传入函数局部对象的只是存储真正数据的一个引用地址,故而函数内所有的修改都是对引用对象的修改。
var arr = ["hello", "world"];
function foo(nArr) {
nArr[1] = "gril";
}
foo();
console.log(arr); //["hello", "gril"]
一切皆对象
基本类型也可以使用对象上的方法。
var a = 'This is a String';
console.log(a.length); //16
定义两种类型的值方式大体类似。
引用类型可以动态添加、操作其属性。但是基本类型不行。
var obj = {};
obj.name = "obj";
var str = "";
str.name = "str";
console.log(obj.name); //obj
console.log(str.name); //undefined
由此可见,引用类型可以添加属性,并且这个属性可用;基本类型的数据是一个对象,也可以添加属性(因为添加时并未报错),但是属性不可用。
检测变量类型
1、typeof
检测变量自身的类型,也就是检测自己是什么类型。
var str = "bar";
console.log(typeof str); //string
2、instanceof
检测变量属于哪种类型,也就是检测变量的父亲是谁。
var arr = [];
console.log(arr instanceof Array); // true