javascript 的数据类型、数据与变量与内存的定义、赋值与内存的关系、引用变量赋值、js如何调用函数传参、js引擎如何管理内存:
- Ⅰ、数据类型:
-
- [其一、typeof/instanceof/=== 的使用代码:](#其一、typeof/instanceof/=== 的使用代码:)
- 其二、结果为:
- 其三、变量类型与数据类型区分的代码:
- 其四、结果为:
- Ⅱ、数据与变量与内存:
- Ⅲ、小结:
Ⅰ、数据类型:
其一、typeof/instanceof/=== 的使用代码:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>01_数据类型</title>
</head>
<body>
<!--
1.分类:
* 基本类型(或值类型)
* String:任意字符串
* Number:任意数字
* boolean:true/false
* undefined:undefined
* null:null
* 对象类型(或引用类型)
* Object:任意对象都是 object 类型(注意:一般对象是用来存数据的,且一般对象的内部是无序的)
* Function(特殊的对象类型之一):一种特别的对象(特别之处:可以执行,内部是可运行的代码)
* Array(特殊的对象类型之二):一种特别的对象(特别之处:数字下标且内部数据是有序的,可以通过数字下标(属性)操作内部数据)
2.判断:
* typeof
* 可以判断:undefined 或 数值 或 字符串 或 布尔值 或 function
* 不能判断:null 与 object(因为:null 和 object 同属于 object 类型)、object 与 array(因为:object 和 array 同属于 object 类型)
* instanceof:判断对象的具体类型(如:function、array,注意 instanceof 判断的是对象类型而非基本类型)
* ===(全等)
* 可以判断:undefined 或 null(可以判断的原因:因为 undefined 或 null 只有一个值)
=== 与 == 的区别:=== 不会做数据转换,而 == 会做数据转换;
-->
<script type="text/javascript">
var obj = {
name: 'Tom',
age: 12
}
function test () {
var a = 3;
}
var arr = [3,'abc']
// 1. 基本类型:
// typeof 返回数据类型的字符串表达
var a
// 判断 a 是否是 undefined 类型的方式:
console.log(a, typeof a, typeof a === 'undefined', a === undefined);// undefined 'undefined' true true
console.log(undefined === 'undefined');// false
a = 3
console.log(typeof a === 'number');// true (注意:不能通过 a === Number 来判断,此方法是错的)
a = 'acbf'
console.log(typeof a === 'string');// true (注意:不能通过 a === String 来判断,此方法是错的)
a = true
console.log(typeof a === 'boolean');// true (注意:不能通过 a === Boolean 来判断,此方法是错的)
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 'xfzhang'
}
}
}
console.log(b1 instanceof Object, b1 instanceof Array);//true(判断 b1 是不是 Object 函数的实例),false(判断 b1 是不是 Array 函数的实例)
console.log(b1.b2 instanceof Array, b1.b2 instanceof Object);//true, true
console.log(b1.b3 instanceof Function, b1.b3 instanceof Object);//true, true
new Object()//说明 Object 是(内置)构造函数;
new Array()//说明 Array 是(内置)构造函数;
new Function()//说明 Function 是(内置)构造函数;
console.log(typeof b1.b3);// 'function'
console.log(typeof b1.b3 === 'function');// true
console.log(typeof b1.b2[2]);// 'function'
console.log(typeof b1.b2[2] === 'function');// true
//若已知一个表达式是一个函数(如:b1.b2[2]),则在后面加一个括号(即:())就可以执行该函数表达式;
b1.b2[2](4);// 4
console.log(b1.b3()());// b3, xfzhang
</script>
</body>
</html>
其二、结果为:
// 一进入页面后的控制台:

其三、变量类型与数据类型区分的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>02_数据类型2</title>
</head>
<body>
<!--
1. undefined 与 null 的区别?
* undefined 代表定义了但未赋值;
* null 代表定义了并赋值了,只是值为 null;
2. 什么时候给变量赋值为 null 呢?
* 初始赋值,表明将要某变量赋值为对象;
* 结束前赋值,让对象成为垃圾对象(被垃圾回收器回收)
3. 严格区分变量类型与数据类型?
* 数据的类型:
* 基本类型:
* 对象类型:
* 变量的类型(变量内存值的类型):
* 基本类型:保存的就是基本类型的数据;
* 引用类型:保存的是地址值;
-->
<script type="text/javascript">
// 实例:实例对象
// 类型:类型对象
function Person(name, age) {// 构造函数 类型(即:函数对象)
this.name = name
this.age = age
}
var p = new Person('tom', 12) // 根据类型创建的实例对象
// Person('jack', 12) // 这样可以用,但不建议,因为不符合使用习惯,且 Person 是作为构造函数(即:首字母大写)而设计的;
// 1. undefined 与 null 的区别?
var a
console.log(a)// undefined
a = null
console.log(a)// null
// 2. 什么时候给变量赋值为 null 呢?
// 起始
var b = null// 初始赋值为 null, 表明将要赋值 b 为对象;
// 确定对象就赋值;
b = ['acbd', 12]
// 最后
b = null// 让 b 指向的对象成为垃圾对象(被垃圾回收器(在浏览器内)回收)
// 3. 严格区分变量类型与数据类型?
var c = {}
var d = function() {// 此时的 d 就是变量类型中的引用变量(因为:它并不是直接保存的基本类型的数据);
}
// 按照存放关系讲:变量 d 中存放的是 function 的地址值,而非真的 function 值,而 typeof 是通过拿 d 的值去内存里找,才确定类型是 'function';
console.log(typeof d);// 'function'
</script>
</body>
</html>
其四、结果为:
// 一进入页面后的控制台:

Ⅱ、数据与变量与内存:
其一、数据与变量与内存定义的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03_数据_变量_内存1</title>
</head>
<body>
<!--
1. 什么是数据?
* 存储在内存中代表特定信息的'东东',本质上是 0101......
* 数据的特点:可传递、可运算、
* 一切皆数据(而非一切皆对象,因为数据类型分为基本数据类型、对象数据类型)
* 内存中所有操作的目标:数据
* 算数运算
* 逻辑运算
* 赋值运算
* 运行函数
2. 什么是内存?
* 内存条通电后产生的可存储数据的空间(临时的,因为要通电所以是临时的空间);
* 内存产生与死亡:内存条(电路板) ==> 通电 ==> 产生内存空间 ==> 存储数据 ==> 处理数据 ==> 断电 ==> 内存空间和数据都消失;
* 一块小内存的 2 个数据:
* 内部存储的数据
* 地址值
* 内存分类:
* 栈:全局变量 或 局部变量
* 堆:对象
3. 什么是变量?
* 可变化的量,由变量名和变量值组成;
* 每个变量都对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据;
4. 内存,数据,变量三者之间的关系?
* 内存是用来存储数据的(临时)空间(而硬盘是存储的固定空间);
* 变量是内存的标识;
-->
<script type="text/javascript">
// 1. 什么是数据?
var age = 18
console.log(age);// 18
var a = 3
var b = a//体现了数据的传递性;
var c = a + 2//体现了数据的可运算性;
// 2. 什么是内存?
var obj = {name: 'Tom'}// 一小块内存中有 2 个数据的解释:一个数据存放内存的内容,而另一个数据来存放该内容的地址值;
// 什么时候会有地址值的概念?答:将一个对象赋值给一个变量的时候,此时赋值的是地址值,否则就是将基本数据直接赋值了;
console.log(obj.name);// Tom, 此时的 obj 是内存的内容(但该内容就是该内存的地址值)
function fn() {// 函数名存放在栈里,因为其本质上是变量名,应该在栈里;
var obj2 = {name: 'Tom'}// 此时的 obj2 是局部变量放在栈里,而 {name: 'Tom'} 是对象放在堆里;
}
// 3. 什么是变量?
// 4. 内存,数据,变量三者之间的关系?
</script>
</body>
</html>
其二、结果为:
// 一进入页面后的控制台:

其三、赋值与内存关系的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>04_数据_变量_内存2</title>
</head>
<body>
<!--
关于赋值和内存的问题:
问题:var a = xxx,a 内存中到底保存的是什么?
* xxx 是基本数据,保存的就是这个数据;
* xxx 是对象,保存的是对象的地址值;
* xxx 是一个变量,保存的 xxx 的内存内容(可能是基本数据类型,也可能是地址值);
-->
<script type="text/javascript">
var a = 3// a 内存中保存的是数据;
var b = {}// b 内存中保存的是地址值;
var c = function() {// c 内存中保存的是地址值(因为函数也是对象);
}
var d = a// d 内存中保存的是数据;
var e = b// e 内存中保存的是地址值;
</script>
</body>
</html>
其四、结果为:
// 一进入页面后的控制台(不报错):

其五、关于引用变量赋值的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>05_数据_变量_内存3</title>
</head>
<body>
<!--
关于引用变量赋值问题:
* n 个引用变量指向同一个对象(即:该 n 个引用变量存的是同一个指向该对象的地址值),通过一个变量修改对象内部数据,其它所有变量看到的是修改之后的数据;
* 2 个引用变量指向同一个对象,让其中一个引用变量指向另一个对象,另一个引用变量依然指向前一个对象;
-->
<script type="text/javascript">
var obj1 = {name: 'Tom'}
var obj2 = obj1// 此时是将 obj1 的内存内容保存到 obj2 中,只不过此时的内存内容是地址值(但不能说是将 obj1 的地址值保存到 obj2);
obj1.name = 'Jack'
console.log(obj2.name);// 'Jack',
obj2.age = 12
console.log(obj1.age);// 12
function fn (obj) {
obj.name = 'Bob'
}
fn(obj1)
console.log(obj2.name);// 'Bob',此上代码中有 3 个引用变量指向同一个对象,分别为:obj1,obj2,obj;
var a = {age: 12}
var b = a
a = {name: 'BOB', age: 13}
console.log(b.age, a.name, a.age);// 12, 'BOB', 13
b.age = 14
console.log(b.age, a.name, a.age);// 14, 'BOB', 13
function fn2 (obj) {
obj = {age: 15}
}
fn2(a)// 函数执行结束后,函数内部的局部变量会被自动释放,内存会被回收(即:函数内的 obj 被释放后,此时的 {age: 15} 就是垃圾对象,就不存在);
console.log(a.age);// 13
// 此时的输出结果为啥不是 15 而是 13?
// 答:因为调用函数 fn2(a) 时,此时是将 a 内存中的内容(即:指向 {name: 'BOB', age: 13} 的地址值)给了 obj,然后在执行 obj = {age: 15} 语句是将 obj 指向了
// {age: 15} 对象,而此时的 a 内存中保存的内容依旧是指向 {name: 'BOB', age: 13},因此此时输出 a.age 的值依旧为 13;
</script>
</body>
</html>
其六、结果为:
// 一进入页面后的控制台:

其七、js调用函数传参的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>06_数据_变量_内存4</title>
</head>
<body>
<!--
问题:在 js 调用函数传递变量参数时,是值传递还是引用传递? 答:值传递;
* 理解1:都是值(基本/地址值)传递;
* 理解2:可能是值传递,也可能是引用传递(即:地址值)
-->
<script type="text/javascript">
var a = 3
function fn(a) {
a = a + 1
}
fn(a)
console.log(a)// 3,(因为:此时将 a 内存中的内容(即:值)传递给函数后,函数内部 a 值的操作与外面的 a 值没有关系)
function fn2(obj) {
console.log(obj.name)// 'Tom',(因为:此时将 obj 内存中的内容(即:地址值)传递给函数后,函数内部 obj 存放的也是指向 {name: 'Tom'} 对象的地址值)
}
var obj = {name: 'Tom'}
fn2(obj)
</script>
</body>
</html>
其八、结果为:
// 一进入页面后的控制台:

其九、js引擎管理内存的代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>07_数据_变量_内存5</title>
</head>
<body>
<!--
问题:JS 引擎如何管理内存?
1、内存生命周期:
* 分配小内存空间,得到它的使用权;
* 存储数据,可以反复进行操作;
* 释放小内存空间;
2、释放内存:
* 局部变量:函数执行完自动释放;
* 对象:成为垃圾对象 ===> 垃圾回收器回收;
-->
<script type="text/javascript">
var a = 3// 此时是占用一个小内存空间,a
var obj = {}// 此时是占用两个小内存空间,obj 和 {}
obj = null
function fn() {
var b = 4
}
fn()// b 是自动释放,b 所指向的对象是在后面的某个时刻由垃圾回收器回收;
</script>
</body>
</html>
其十、结果为:
// 一进入页面后的控制台(不报错):

其十一、变量与内存图解:

Ⅲ、小结:
其一、哪里有不对或不合适的地方,还请大佬们多多指点和交流!
其二、若有转发或引用本文章内容,请注明本博客地址(直接点击下面 url 跳转) https://blog.csdn.net/weixin_43405300,创作不易,且行且珍惜!
其三、有兴趣的话,可以多多关注这个专栏(Vue(Vue2+Vue3)面试必备专栏)(直接点击下面 url 跳转):https://blog.csdn.net/weixin_43405300/category_11525646.html?spm=1001.2014.3001.5482
其四、再有兴趣的话,也可以多多关注这个专栏(Java)(直接点击下面 url 跳转):https://blog.csdn.net/weixin_43405300/category_12654744.html?spm=1001.2014.3001.5482