JS中的数据类型可以这样分类:
原始数据类型: number, string ,boolean, undefined, null, symbol
基本类型(简单类型):
值类型: number((整数/小数/NaN));string,boolean空类型:null,undefined还有 symbol (ES6)
复杂类型(引用类型):object
基本数据类型
JavaScript 中共有 6 种基本数据类型:undefined、null、boolean、number、string、symbol (new in ES 6) 。
访问基本数据类型是按值访问的。 基本类型的值不可变
var str = "123HelloWorld321";str.toUpperCase();console.log(str.toUpperCase()); // 123HELLOWORLD321console.log(str);// 123HelloWorld321
基本类型的比较是它们的值的比较
var a = 1;var b = '1';console.log(a == b); // trueconsole.log(a === b); // false
上面 a 和 b 的数据类型不同,但是也可以进行值的比较,这是因为在比较之前,自动进行了数据类型的 隐式转换。 基本类型的变量存放在栈内存里
var a = 10;var b = a;b = 20;console.log(a);console.log(b);
b获取的是a值的一个副本,虽然两个变量的值相等,但是两个变量保存了两个不同的基本数据类型值。所以b值的改变不会影响a的值。
值类型作为函数的参数,传递的是值
function f1(x) {x=100;}var num1=10;f1(num1); //num1的值复制了一份给了x,然后 x被重新赋值为100, x的值变了,但是num1的值没有变,console.log(num1); // num1的值还是 10
引用数据类型
Object 类型,细分的话有:Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型等。
引用类型的值是按引用来访问的。
引用类型的值是可变的。
var obj = {name:"lmg"}; // 创建一个对象obj.name = "xiaoming"; // 改变 name 属性的值obj.age = 18; // 添加 age 属性obj.sayHi = function(){return this.name + " : " + this.age;}; // 添加 sayHi 方法obj.sayHi();
引用类型的比较是引用的比较
var obj1 = {}; // 新建一个空对象 obj1var obj2 = {}; // 新建一个空对象 obj2console.log(obj1 == obj2); // falseconsole.log(obj1 === obj2); // false
obj1 和 obj2 分别引用的是存放在堆内存中的2个不同的对象,故变量 obj1 和 obj2 的值(引用地址)也是不一样的。
引用类型的值是保存在堆内存中的对象
var a = {name:"percy"};var b;b = a;a.name = "zyj";console.log(b.name); // zyjb.age = 22;console.log(a.age);// 22var c = {name: "zyj",age: 22};
图解:
注:栈内存中保存了变量标识符和指向堆内存中该对象的指针。堆内存中保存了对象的内容。
引用类型作为函数的参数,传递的是引用(地址)
var obj={name:'xiaoming'};function f2(obj2) {obj2.name='xiaohong';}console.log(obj.name); //xiaomingf2(obj); //obj的地址复制一份给了obj2,地址相同,指向同一对象, 调用时name改成了xiaohong,xiaoming就被替换掉了,console.log(obj.name); // xiaohong
案例分析:
//案例1分析: 会画缓存图var n1=10;var n2=n1;n1=20;console.log(n1); //20console.log(n2); //10
//案例2:var n3=50;function ff(n3) {// 这里的n3是形参, 实参与形参即使名字相同。也不是同一个变量n3=60;console.log(n3); //60}ff(n3); //注意:这里的n3是实参console.log(n3); //这里是函数外的n3,为50, 函数里面的n3是没有关系的
//案例3:var n4=55;var n5=66;function f_(n,n4) {//n,n4在函数内部是局部变量n=100; //局部变量,它的传进来的值对应外面的n4, 55n4=100; //局部变量,它的传进来的值对应外面的n5, 66n5=100; //注意:!!隐式全局变量!!console.log(n); // 100console.log(n4); // 100console.log(n5); // 100}f_(n4,n5);console.log(n4); // 55, 这个是全局变量n4console.log(n5);// 100,这个是函数中的隐式全局变量console.log(n); // ReferenceError: n is not defined报错:这个是函数中的局部变量,访问不到
//案例4:function Person(name,age,salary) {//自定义构造函数this.name=name;this.age=age;this.salary=salary;}function fff(person) {//创建了普通的函数person.name='ls'; //name修改了, 变成了lsperson=new Person('aa',18,10); //新创建的一个对象,person指向了这个对象, person 和p指向的对象不同了}var p = new Person('zs',18,1000);console.log(p.name); //zsfff(p); //函数调用,对象p的地址复制一份给person,所以他们指向同一个对象console.log(p.name); //ls
数据类型的检测方法:typeof 与 instanceof
typeof: 主要用来检测一个变量是不是一个基本的数据类型,返回的是具体的数据类型。
var a;console.log(typeof a); //undefined 输出的这些类型都是小写的字符串var b = null;console.log(typeof b); // object 注意var c = 123;console.log(typeof c); // numbervar d = '123';console.log(typeof d); // stringvar e = true;console.log(typeof e); // booleanvar f = Symbol();console.log(typeof f); // symbolvar g = function () {console.log(g);};console.log(typeof g); // functionvar h = [];console.log(typeof h); // objectvar i = {};console.log(typeof i); // objectvar j = /123/g;console.log(typeof j); // object
instanceof:判断一个引用类型的变量具体是不是某种类型的对象,返回的是布尔值。
console.log(g instanceof Function); // trueconsole.log(h instanceof Array); // trueconsole.log(i instanceof Object); // trueconsole.log(j instanceof RegExp); // true
参考:
JavaScript 深入了解基本类型和引用类型的值
JavaScript中基本数据类型和引用数据类型的区别