全局作用域:
window
global
变量和常量能存任何数据类型
js的数据类型
基础数据类型(值类型)
number
string
boolean
null
undefined
symbol
引用数据类型
对象
- {}
普通对象
(json) - []
数组
/^$/
正则
Math 对象
数据类型
函数
function
普通函数class
类
操作规律
值类型(基本数据类型):
var a=12;
- 1)首先在
当前作用域中声明一个变量
a,没有赋值是undefined
- 2)在当
前作用域
中开辟一个位置存储
12 - 3)让声明的变量和存储的12
进行关联
直接按值操作:把原有的值复制一份,放在新的空间位置上,和原来的值没有关系。 变量间相互不影响
一个变量只能存一个值
对象数据类型:(按内存空间操作)
- 1、先
创建一个变量
(声明一个函数名和声明一个变量一样 ,如果两个变量名重复 是会冲突的); - 2、浏览器为其
开辟一个新的内存空间
,为了方便别的地方找到这个空间 会给空间分配一个16进制的地址
(16进制:0-9 a-f) - 3、
按照一定顺序,把对象中的键值对存到内存空间
- 4、把开辟内存的地址赋值给变量(或者其他的东西比如事件),以后变量就可以通过地址找到内存空间然后进行操作
操作的是空间的引用地址
:把原来空间地址赋值给新变量,但是空间没有被克隆,还是一个空间,这样就会出现多个变量关联的是相同的空间
,相互之间就会存在影响
var a={name:'哈哈'}
1、声明变量a
2、 开辟空间 111fff000
3、111fff000空间内 存储键值对 name:'哈哈'
4、把111fff000赋值给a
复制代码
函数的操作:
创建函数:
- 1、先开一个
新的内存空间
(为其分配了一个16进制的地址
) - 2、把函数体中编写的
js代码当做 “字符串”
存储到空间当中(所以函数只创建不执行没有意义
) - 3、把分配的
地址赋值给
声明的函数名
(function fn(){}
和var fn=function(){}
两种声明的方式 操作原理相同,都是在当前作用域中声明了一个名字,此处两个都写的话名字是重复的)
执行函数-目的:执行函数体中的代码
- 1、函数执行的时候 浏览器会
形成一个新的**私有作用域**
(只能执行函数体中的代码),供函数体中的代码执行,每次执行函数都会形成新的私有作用域 - 2、执行代码之前先
把创建函数的字符串 复制过来 变为真正的js表达式
,按照从上到下的顺序在私有作用域中执行。
一个函数可以被执行N次,每次执行相互之间互不干扰,因为每次执行函数都会执行上边的步骤 重新创建私有作用域。
示例
var a=10;
var b=a;
b=14;
console.log(a) => 10
//改变了同一空间地址内的键值
var c={name:'haha'}
var d=c;
d.name='quququ';
console.log(c) => {name: "quququ"}
//从新定义了地址 不改变原有空间
var m={name:'aaa'}
var n=m;
n={name:'bbb'}
console.log(m.name) => aaa
复制代码
“闭包”:
执行函数时形成的私有作用域把函数体中的私有变量都包裹起来(保护起来),在私有作用域中操作私有变量和外界没有关系,外界也无法直接的操作私有变量,我们把函数执行的这种机制叫做闭包(
函数执行,形成一个私有作用域,保护里面的私有变量不受外界的干扰,这种保护机制就叫**闭包**
)但是现在也有很多人认为,函数执行,形成一个不销毁的私有作用域,除了保护私有变量以外,还可以存储一些内容,这样的模式才叫闭包
JS中的堆栈内存:
栈内存:俗称作用域(全局作用域/私有作用域)
为js代码提供执行的环境(
js代码都是在栈内存中执行的
)
基本数据类型值是直接存放在栈内存中的
(因为基本数据类型值比较简单,他们直接在栈内存中开辟一个位置把值存进去)当栈内存被销毁时,存储的那些基本数据类型值也都跟着销毁了
堆内存:
存储引用数据类型值的(相当于一个存储的仓库)
对象存储的是键值对
函数存储的是代码字符串
内存处理:
堆内存处理:
var o={} 当前对象对应的内存被变量O占用着,堆内存是无法销毁的;
销毁方法 o=null;null空对象指针(不指向任何的堆内存),这时候原来的堆内存就没被占用了,
谷歌浏览器会在空闲时间把没有被占用堆内存自动释放
栈内存处理:
一般情况下
函数执行形成栈内存
,函数执行完浏览器会把形成的栈内存自动释放,特殊情况下,函数执行完成后栈内存不能被释放(返回引用数据类型被别处引用)。
全局作用域在加载页面时执行,在关掉页面时销毁。