js函数3-作用域与作用域链
Posted _oldzhang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js函数3-作用域与作用域链相关的知识,希望对你有一定的参考价值。
作用域就是指定义的变量与函数能被访问到的区域。作用域链就是指一段代码中多个作用域嵌套在一起形成的一个链条。可以把这个链条想象成多个对象组成的链表,其中每个作用域是一个对象。全局的作用域位于链表的最末端。
JS中只有函数能创建作用域,创建的作用域就能和全局作用域形成至少两个对象的作用域链,如果函数又有嵌套函数,就会形成至少三个对象的作用域链。JS定义一个全局变量时实际上是定义了全局对象的一个属性(这是ECMAScript规范),声明局部变量实际上也是声明某个对象上的一个属性,只不过这个对象我们无法引用到,这个对象应该就是在ECMAScript规范中定义的VO(变量对象),VO用于存储执行上下文中的变量 、函数声明 、函数参数,函数每次执行都会实例化一个VO对象。也正是这个VO对象形成了作用域链。JS可以使用this,window来引用全局的VO,而没有关键字来引用到函数的VO。
下面是JS作用域的几点特殊之处:
1,JS只有全局与函数两种作用域,没有块级作用域
2,函数声明会被提前到其所在作用域的顶部,变量声明也会提前,只不过声明为undefined,并未赋值
var scope = "global";
functioin f()
console.log(scope); //undefined
var scope="local";
console.log(scope); //local
3,通过var声明的全局变量无法通过delete运算符删除,不通过var声明的js会自动创建为一个全局变量,这种通过delete是可删除的(也许不通过var声明的会放在全局VO的原型对象上,所以delete无法操作,待求证)。
作用域链:
作用域链是在函数定义时就形成了的。当定义一个函数时,它实际上保存一个作用域链,当调用这个函数时,它创建一个新的VO对象来存储它的局部变量,并将这个对象添加到保存的那个作用域链上。对于嵌套函数,每次调用外部函数时,内部函数又会重新定义一次,因此每次调用时作用域链都是不同的。
理解作用域链对with语句和闭包的理解非常重要。
比如:
with(obj)
语句;
其实就是将obj加入到当前作用域的顶端,语句中就可以直接使用obj中的属性了,而不需要obj.属性来引用。
以上是关于js函数3-作用域与作用域链的主要内容,如果未能解决你的问题,请参考以下文章