一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
简单与复杂数据类型
分类
数据类型分为基本类型和对象类型两种,合计6种(ES6出了第七种——Symbol数据类型)
基本类型(值类型)
(String、Number、boolean、undefined、null)
基本数据类型在存储时变量中存储的是值本身,因此又叫做值类型,比如string、number、boolean、undefined、null。其中null返回的是空对象为Object类型
对象类型(引用类型)
(Object、Function、Array)
引用类型:在存储时变量中存储的仅仅是地址,因此叫做引用类型,是通过new关键字创建对象(系统对象、自定义对象),如Object、Array、Date等
判断方式
typeof:
可以判断undefined、数值、字符串、布尔值
不能区分对象、数组、正则,对他们操作返回"object"
instanceof:
判断对象的具体类型
(翻译过来是实例的意思,比如A instanceof B 就是判断A是不是B的实例)
===:
全等,可以判断undefined,null
// 1.值类型: 👉typeof返回数据类型的字符串表达👈
var a;
console.log(a, typeof a, typeof a === 'undefined', a === undefined);
// undefined 'undefined' true true
console.log(undefined === 'undefined'); //false
a = 4;
console.log(typeof a === 'number'); //true
a = 'ABC';
console.log(typeof a === 'string'); //true
a = true;
console.log(typeof a === 'boolean'); //true
a = null;
console.log(typeof a, a === null); //object true
console.log('_____________________');
// 2.对象
var b1 = {
b2: [1, 'abc', console.log],
b3: function () {
console.log('b3');
return function () {
return 'hello world';
}
}
}
console.log(b1 instanceof Object, b1 instanceof Array); //true false
console.log(b1.b2 instanceof Array, b1.b2 instanceof Object); //true true
console.log(b1.b3 instanceof Function, b1.b3 instanceof Object); // true true
console.log('---', typeof b1.b2); //object
console.log(typeof b1.b3 === 'function'); //true
console.log(typeof b1.b2[2] === 'function'); //true
b1.b2[2](4); //b1.b2[2]选中的是console.log,再加一个括号就是console.log(4)
console.log(b1.b3()()); // b3 hello world
相关问题
1.undefined与null的区别?
undefined代表了定义了未赋值
null定义了并赋值了,只是赋值为null
2.什么时候给变量赋值为null呢?
初始赋值,表明将要赋值为对象
结束前,让对象成为垃圾对象(被垃圾回收器回收)
3.严格区别变量类型与数据类型?
数据的类型:
- 基本类型
- 对象类型
变量的类型:
(又叫变量内存值的类型,因为js是弱类型语言,声明的变量本身没有类型,判断变量的类型实际上是判断变量内存值的类型): - 基本类型:保存基本类型数据
- 引用类型:保存的是地址值
4.JS引擎如何管理内存?
1) 内存的生命周期:
- 分配一个内存空间,得到它的使用权
- 存储数据,可以反复操作
- 释放这个内存空间
2) 释放内存: - 全局变量:当时pink说是页面关闭时才释放
- 局部变量:函数执行完就自动释放
- 对象:先成为垃圾对象 ==> 被垃圾回收器回收
内存分配图解
如上图,值类型的数据直接放在变量(栈空间)中
引用类型变量(在栈空间中)里存放的是地址,真正的对象实例存放在堆空间中
两种数据类型的传参
简单数据类型传参
函数的形参可以看做是一个变量,当我们把一个值类型变量做为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量
复杂数据类型传参
复杂数据类型在传参时,是把自己在栈空间保存的地址值传给了形参,这时候形参也指向了保存在堆中的对象,函数内部对形参进行操作会影响到外面的引用类型的变量,因为它们指向的都是同一个对象。
例题
function Person(name){
this.name = name;
}
function fun(x){
console.log(x.name); // 2.这个输出什么?
x.name = "张学友";
console.log(x.name); // 3.这个输出什么?
}
var p = new Person('刘德华');
console.log(p.name); // 1.这个输出什么?
fun(p);
console.log(p.name) // 4.这个输出什么
解析:
因为p中存储的是复杂数据类型,所以var p会先在栈中开辟一块空间用于存放值的地址,指向堆。
第一问输出'刘德华'
然后fun(p),将p的值传递给了形参x
做了以下操作
先在栈中开辟了一块空间,让x指向这个空间,这个空间存放的是p传过来的值,而这个传过来的值又是地址,p的值与x的值一样都是地址,同样的地址指向同一个对象,所以当我们在函数中对x进行操作时,会修改堆中的对象,同时也会影响到外面的变量p。
第二问也是'刘德华',后面两问都是‘张学友’
例题总结:
函数的形参也可以看作是一个变量,当我们把引用类型变量传递给形参时,其实是把变量在栈空间里面保存的堆地址复制给了形参,形参和实参其实保存的是同一个地址,所以操作了同一个对象