- 什么是数据?
- 在内存中可读的, 可传递的保存了特定信息的’东东’
- 一切皆数据, 函数也是数据
- 在内存中的所有操作的目标: 数据
- 什么是变量?
- 在程序运行过程中它的值是允许改变的量
- 一个变量对应一块小内存, 它的值保存在此内存中
- 什么是内存?
- 内存条通电后产生的存储空间(临时的)
- 一块内存包含2个方面的数据
- 内部存储的数据
- 地址值数据
- 内存空间的分类
- 栈空间: 全局变量和局部变量
- 堆空间: 对象
内存,数据, 变量三者之间的关系
内存条通电后产生的存储空间(临时的)
- 一块内存包含2个方面的数据
- 内部存储的数据
- 地址值数据
- 内存空间的分类
- 栈空间: 全局变量和局部变量(空间较小)
- 堆空间: 对象 (空间较大)
数据类型?
- 基本(值)类型
- Number: 任意数值
- String: 任意文本
- Boolean: true/false
- undefined: undefined
- null: null
- 对象(引用)类型
//问题: 在js调用函数时传递变量参数时, 是值传递还是引用传递//只有值传递, 没有引用传递, 传递的都是变量的值, 只是这个值可能是基本数据, 也可能是地址(引用)数据//如果后一种看成是引用传递, 那就值传递和引用传递都可以有function f(a) {console.log(a)}var n = 4f(n) //传递的是n的值 --->值传递function f2(a) {a.name = 'atguigu'}n = {}f2(n) // 传递的是n指向的对象 ---> 引用传递console.log(n.name) //atguigu
对象被调用修改时 内存分配情况
//1. 2个引用变量指向同一个对象, 通过一个引用变量修改对象内部数据, 另一个引用变量也看得见
var obj1 = {}
var obj2 = obj1 //obj2指向obj1的内存中地址
obj2.name = 'Tom'
console.log(obj1.name) //Tom -由于指向同个地址,修改了同个地址执行内存中的内容
function f1(obj) { //obj指向obj2的内存中地址
obj.age = 12
}
f1(obj2)
console.log(obj1.age) //12 同理
//2. 2个引用变量指向同一个对象,让一个引用变量指向另一个对象, 另一个引用变量还是指向原来的对象
var obj3 = {name: 'Tom'}
var obj4 = obj3 //obj4指向obj3的内存中地址
obj3 = {name: 'JACK'} //obj3被重新赋值有了新地址,指向obj4地址被破坏
console.log(obj4.name) //Tom -不同地址不被修改
function f2(obj) { //obj指向obj4的内存中地址 结果于上边一样
obj = {name: 'Bob'}
}
f2(obj4)
console.log(obj4.name) //Tom
JS引擎如何管理内存
- 内存生命周期
- 分配需要的内存
- 使用分配到的内存
- 不需要时将其释放/归还
- 释放内存
- 为执行函数分配的栈空间内存: 函数执行完自动释放
- 存储对象的堆空间内存: 当内存没有引用指向时, 对象成为垃圾对象, 垃圾回收器后面就会回收释放此内存
var obj = {}
obj = null // 垃圾对象, 垃圾回收器后面就会回收释放此内存
function fn () {
var a = 3
var b = {}
}
fn() // 函数执行完自动释放
内存溢出&内存泄漏
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时(一般都是栈), 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包 ```javascript // 1. 内存溢出 /var obj = {} for (var i = 0; i < 100000; i++) { obj[i] = new Array(10000000) } console.log(‘———‘)/
// 2. 内存泄露 // 意外的全局变量 function fn () { a = [] //不小心没有var定义 } fn() // 没有及时清理的计时器 setInterval(function () { console.log(‘——‘) }, 1000)
```
