您的位置:首页 > Web前端 > JavaScript

JavaScript的变量作用域

2016-04-18 17:06 423 查看
全局变量拥有全局作用域,在JavaScript代码中任何地方都是有定义的。然而在函数内声明的变量只在函数体内有定义。函数参数也是局部变量,他们只在函数体内有定义。

在函数体内,局部变量的优先级高于同名的全局变量。



如果在函数内声明的一个局部变量或者函数参数中带有的变量与全局变量重名,那么全局变量就会被局部变量所遮盖。

在声明全局作用域编写代码时可以不写var语句,但声明局部变量时则必须使用var语句。否则全局变量将被更改。

JavaScript函数作用域和声明提前

JavaScript使用了函数作用域(function scope):变量在声明它们的函数体以及这个函数体内嵌套的任意函数体内都是有定义的。

JavaScript的函数作用域是指在函数内声明的所有变量在函数体内是始终可见的。JavaScript的这个特性被非正式的称为声明提前(hoisting),及所有JavaScript的函数声明的所有变量(不涉及赋值)都被提前至函数体的顶部。



由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量。可以这样认为将函数体的声明提前至开头,仅仅在用的时候才会赋值。

当声明一个JavaScript全局变量是,实际上定义了全局对象的一个属性。当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过delete运算符删除。



JavaScript全局变量是全局对象的属性。JavaScript可以允许使用this来引用全局对象,却没有方法引用局部变量中存放的对象。

JavaScript是基于词法作用域的语言:通过阅读包含变量定义在内的数行源码就能知道变量的作用域。全局变量在程序中始终都是有定义的。局部变量在声明他的函数体内以及其所嵌套的函数内始终是有定义。

每一段JavaScript代码(全局代码或函数)都有一个与之关联的作用域链(scope chain)。这个作用域是一个对象列表或链表,这组对象定义了这段代码“作用域中”的变量。当JavaScript需要查找变量时,就会从第一个对象开始寻找,如果存在一个x的属性,则会直接使用这个属性的值,如果第一个对象不存在该属性,则寻找第二个,若不存在则会继续寻找下一个对象,以此类推。如果作用域链上没有任何一个对象含有x属性,那么就会认为x不存在,最终抛出一个引用错误的异常(Reference Error)。

在JavaScript最顶层的代码中(也就是不包含任何函数内定义的代码),作用域链有一个全局对象组成。在不包含嵌套的函数体内,作用域上有两个对象:第一个是定义函数和局部变量的对象,第二个是全局对象。

在嵌套函数中起码有三个对象,当定义一个函数时,它实际上保存一个作用链域。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的那个作用域链上,同时创建一个新的更长的表示函数调用作用域的链。

对于嵌套函数,每次调用外部函数时,内部函数又会重新定义一遍。每次调用外部函数的时候,作用域都是不同的——在每次调用外部函数时,内部函数的代码都是相同的,而关联这段代码的作用域链是不同的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: