多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 数据类型分类 > JS中的数据类型 > - 基本数据类型(值类型) > + number(NaN) > + string > + boolean > + null > + undefined 其中,null、undefined也可被分为特殊数据类型 > - 引用数据类型 > + 对象 > + {} 普通对象 > + [] 数组 > + /^$/ 正则 > + Math等系统对象 > + ... > + 函数 > + function 普通函数 > + 类->class > + ... ## 数据类型操作原理 JS代码运行在浏览器中,是因为浏览器给我们提供了一个供js代码执行的环境,我们把这个环境称之为**全局作用域**(window/global) ![](https://box.kancloud.cn/07d9adf7fc5bade279e86ccedfc86e46_249x350.png) ### 值类型是按照值来操作 ``` //会把12这个原值直接赋给变量a(a变量直接和12这个值建立了链接) var a = 12; var b = a; //->b=12 b=13; console.log(a); ``` ``` <<< 12 ``` ### 引用数据类型是按照地址来操作 因为对象类型不再是一个简单的值,而会是很多值的集合,so需要开辟一个空间(相当于一个箱子)用来存放它。 操作步骤: 1. 遇到对象类型的数据,会先开辟一个新的内存空间,浏览器会分配给它一个16进制的地址(方便别人找到它)。 2. 按照一定的顺序,分别的把对象键值对存储到新开辟的内存空间当中。 3. 把开辟内存的地址赋值给变量(或则其它的东西,比如说当前元素的某个事件),以后变量就可以通过地址找到内存空间,然后进行一些操作。 >**注意:** 相关的,`const`常量之所以无法改变,就是因为定死了地址(地址对应的空间内的内容不是定死的),故它叫“常”而不叫“变”,这个“量”你可以认为它就是地址,不变的地址,可变的地址。 ```javascript var o = {name='ahhh'}; //o = aaafff111 var p = o; //p = aaafff111 p.name = 'ahhh2'; //p通过地址找到对应的内存空间,再把里面的name改成ahhh2 console.log(o.name); ``` ``` <<< ahh2 ``` ```javascript var m = {name:'ahhh'}; //m = aaafff111 var n = m; n = {name:'ahhh2'}; //n = aaafff222 ,这里开辟了另外一个新的空间,并且把这个新空间的地址给了n console.log(m.name); ``` ``` <<< ahhh ``` ### 函数的操作原理 > 创建函数 > 1、 先开一个新的内存空间(浏览器为其分配一个十六进制的地址)(和给普通对象开辟的空间一样) > 2、把函数体中编写的js代码当做`字符串`存储到空间中 > (函数只创建不执行没有意义)(和普通对象相比,普通对象存储的是有意义的键值对(能通过.x找到对应的键值),函数存储的是无意义的字符串) > 3、 把分配的地址赋值给声明的函数名 >[warning]**注意:** function fn 和 var fn 操作原理其实相同,都是在当前作用域中声明了一个名字,此处两个名字是重复的,不会报错,后者会覆盖前者 > 执行函数 > 目的:执行函数体中的代码 > 1、 函数执行的时候(**每一次执行**),浏览器会形成一个新的私有作用域(只能执行函数体中的代码),供函数体中的代码执行。 > 2、执行代码之前,先把创建函数存储的那些字符串变为真正的js表达式,按照从上到下顺序在私有作用域中执行 >[danger] **注意:** 函数每次执行都会形成一个**新的**私有作用域,每次都是把存在内存中的函数体字符串copy一部分出来执行。两次之间没有直接关系但可能存在间接关系(比如说在全局下有个变量,你在函数内用到了)。 >[danger] **注意:** 形成的私有作用域会把函数体中的私有变量都包裹起来(保护起来),在私有作用域中操作私有变量和外界没关系,外界也无法直接的操作私有变量,我们把函数自执行形成的这种保护机制叫做**闭包**。 ``` function fn(){ var ary = Array.prototype.slice.call(arguments) return eval(ary.join('+')); } fn(12,23,34,45,56); ``` ## 栈内存与堆内存 ### 栈内存 也叫作用域(全局作用域、私有作用域),它有两个作用: - 为JS代码提供执行的环境(执行js代码的地方) - 基本数据的值是直接存放在栈内存中的 ### 堆内存 存储引用数据类型值的(相当于一个存储的仓库) - 对象存储的是键值对 - 函数存储的是代码字符串 ### 回收 在项目中,我们的内存越少性能越好,我们需要把一些没用的内存处理掉 #### 堆内存的释放 ```javascript //当前对象对应的堆内存被变量o占用着,此时堆内存是无法销毁的 var o = {}; //--- --- --- o = null; //null叫空对象指针,不指向任何的堆内存,此时上一次的堆内存就没有被占用了,可以释放了, ``` 谷歌浏览器会在空闲时间把没有被占用的堆内存自动释放(销毁/回收)。 IE浏览器有计数器,没有被占用时,计数器就会置为0,就会触发回收。 #### 栈内存的释放 一般情况,函数执行形成栈内存,函数执行完,浏览器会把形成的栈内存自动释放。 但有时候执行完成,栈内存不能被释放 ### 全局作用域的执行以及释放 全局作用域在加载页面时执行 在关掉页面时销毁 ![](https://box.kancloud.cn/769224b2490431db5d046507e12b6083_1578x727.png) ## FAQ ![](https://box.kancloud.cn/7b02fe2944ff7a98159d0953a9062584_662x475.png)