Javascript作用域和作用域链
程序员文章站
2024-02-17 16:35:52
...
作用域
作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。
全局作用域
- 最外层函数 和在最外层函数外面定义的变量拥有全局作用域
var outVariable = "我是最外层变量"; //最外层变量
function outFun() { //最外层函数
var inVariable = "内层变量"; //内层变量
function innerFun() { //内层函数
console.log(inVariable);
}
innerFun();
}
- 所有末定义直接赋值的变量自动声明为拥有全局作用域
function outFun2() {
variable = "未定义直接赋值的变量";
var inVariable2 = "内层变量2";
}
outFun2();
console.log(variable); //未定义直接赋值的变量
console.log(inVariable2); //inVariable2 is not defined
- 所有 window 对象的属性拥有全局作用域
函数作用域
是指声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部。
function doSomething(){
var blogName="浪里行舟";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错误
作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。
泡泡 1 是全局作用域,有标识符 foo;
泡泡 2 是作用域 foo,有标识符 a,bar,b;
泡泡 3 是作用域 bar,仅有标识符 c
作用域链
1. *变量
如下代码中,console.log(a)要得到 a 变量,但是在当前的作用域中没有定义 a(可对比一下 b)。当前作用域没有定义的变量,这成为 *变量 。*变量的值如何得到 —— 向父级作用域寻找
var a = 100
function fn() {
var b = 200
console.log(a) // 这里的a在这里就是一个*变量
console.log(b)
}
fn()
2.什么是作用域链
如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是 作用域链 。
var a = 100
function F1() {
var b = 200
function F2() {
var c = 300
console.log(a) // *变量,顺作用域链向父作用域找
console.log(b) // *变量,顺作用域链向父作用域找
console.log(c) // 本作用域的变量
}
F2()
}
F1()
3.*变量取值的歧义
var x = 10
function fn() {
console.log(x)
}
function show(f) {
var x = 20
(function() {
f() //10,而不是20
})()
}
show(fn)
在 fn 函数中,取*变量 x 的值时,要到哪个作用域中取?——要到创建 fn 函数的那个作用域中取,无论 fn 函数将在哪里调用。
下一篇: PHP 基础知识 [$_SERVER]