1、JS中的内存空间分为两种:栈内存、堆内存
栈内存:提供JS代码执行的环境;
存储基本数据类型的值;
全局作用域或私有作用域都是栈内存。
堆内存:存储引用数据类型的值 ------ 对象是把属性名和属性值存储进去;
函数是把函数体中的代码当做字符串存储进去。
2、当浏览器加载HTML页面的时候,首先会提供一个供JS代码执行的环境:全局作用域(global scope)。
3、在JS代码执行之前,浏览器还需要自己做一些事情,即把所有带 var / function 关键字的进行提前的声明或定义:“预解释”(变量提升)
声明(declare):告诉浏览器我有这样一个东西,例如 var abc ; function fn;
定义( defined ): 给我们声明的变量或者函数赋值, 例如 abc = 12; fn = function(){...}
注意:变量只声明没有定义,默认的值是undefined(未定义)
4、var 和 function 在预解释阶段处理是不一样的
var:在预解释的时候只是提前的声明了这个变量,只有当代码执行的时候才会完成赋值操作 【声明时不赋值】
function:在预解释的时候会提前的把声明加定义都完成了(在代码执行的时候遇到定义的代码直接的跳过) 【声明时赋值】
5、全局变量和私有变量
在全局作用域下声明的变量是全局变量
在私有作用域中声明的变量是私有变量;
函数的形参也是私有的变量。
如何分辨函数中出现的变量是私有的还是全局的?
首先看是否为形参,然后看是否在私有作用域中声明过(有没有var过),两者有其一就是私有的变量。那么在当前函数中不管什么位置出现都是私有的,和全局的没有半毛钱关系;如果两者都没有,说明不是私有的,则往其上一级作用域进行查找....
6、函数执行的时候会形成一个新的私有作用域(栈内存),供函数体中的代码执行;
1)给形参赋值
2)私有作用域下的预解释
3)私有作用域下的代码执行
形成的新的私有作用域还保护了里面的私有变量不受外界的影响,我们把函数的这种保护机制称为“闭包”。
区别:带var的可以在代码执行前进行声明,而不带var的不能提前的声明
1、不管条件是否成立都要进行预解释(undefined)
2、预解释只发生在“=”的左边,只把左边的进行预解释,右边的是值是不进行预解释的
匿名函数之函数表达式:把函数定义的部分当做值赋值给一个变量或者元素的事件。
函数表达式的预解释默认是undefined。
3、函数体中return下面的代码都不在执行了,但是下面的代码需要参加预解释。
4、匿名函数的function在全局作用域下是不进行预解释的
匿名函数之自执行函数:定义和执行一起完成了 , 如 (function(num){....})(100);
5、在预解释的时候,如果遇到名字重复了,只声明一次,不重复的声明,但是赋值还是要重复的进行的。
在JS中变量的名字和函数的名字如果一样算作重复的。