引言:这里主要研究变量,刚学完js中的对象和属性,不要弄混,这里主要说的是栈内存的,而对象和对象的属性在堆内存中。
变量提升
变量提升是指:通过var 定义的变量。在变量定义语句之前可以访问到,只不过访问到的是undefined,
在全局作用域中用var关键字定义的变量会在所有代码执行之前,首先声明变量。
<script>
console.log(a)//这里输出a的值为undefined
console.log(b)//会报错
var a = 3
b = 6
</script>
其实上面这段代码,在运行时会变成如下
<script>
var a
console.log(a)//这里输出a的值为undefined
console.log(b)//会报错
a = 3
b = 6
</script>
用var 声明的变量会到程序最开始声明
在函数作用域中变量提升同样存在
<script>
function fn(){
console.log(a)//这里输出a的值为undefined
var a = 3
}
</script>
上面的代码类似于
<script>
function fn(){
var a
console.log(a)//这里输出a的值为undefined
a = 3
}
</script>
从上面的例子可以看出变量在全局作用域和函数作用域都有变量提升的特性,同样的方法也有这种特性,只不过js中要求只有声明式方法有函数提升的特性,如:function fn (){}就是声明式函数。对于用var fn = function(){}的函数,它用的是变量提升特性
函数提升
<script>
fn()//控制台会输出 你好
function fn(){
console.log("你好")
}
fn2()//控制台输出 undefined
var fn2 = function(){
console.log("fn2")
}
</script>
因为函数fn在调用之前就已经产生了。而对于fn2它依照变量提升的特性,只是提前声明了,没有定义变量值,所以输出undefined。同时在函数作用域依然支持函数提升。上面代码类似于如下:
<script>
var fn2//变量提升
//函数提升
function fn(){
console.log("你好")
}
fn()//控制台会输出 你好
fn2()//控制台输出 undefined
fn2 = function(){
console.log("fn2")
}
</script>
作用域问题
作用域分为全局作用域和局部作用域。
全局作用域和局部作用域的概念就不说了。这里主要说一下js中的特殊之处
1.全局作用域打开浏览器产生,关闭浏览器销毁
2.局部作用域方法执行产生,方法执行完成后销毁
3.在js的全局作用域中有一个全局作用域对象window,该对象会把全局作用域中的变量和函数作为它本身的属性保存。
变量分为全局变量和局部变量。
由上面的全局变量用var定义时会变量提升,所以window对象中在程序开始执行前就存在了var定义的全局变量和声明式定义的函数。
全局执行上下文(window)
全局执行上下文:window对象,相当于一个容器,用来存放全局的变量等等
全局作用域执行的步骤
1.在执行全局代码前先把window对象确定为上下文
2.对全局变量进行预处理,
把var定义的全局变量定义未undefined(由于变量提升),然后添加到window对象的属性中
把function声明的全局函数,赋值,添加为window的方法
把this,赋值为window对象
3.开始执行全局代码
函数执行上下文