首页 > 语言 > JavaScript > 正文

JS 作用域与作用域链详解

2024-05-06 14:43:24
字体:
来源:转载
供稿:网友

(1)作用域

一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。

1. 在JS中使用的是词法作用域(lexical scope)

不在任何函数内声明的变量(函数内省略var的也算全局)称作全局变量(global scope)

在函数内声明的变量具有函数作用域(function scope),属于局部变量

局部变量优先级高于全局变量

代码如下:
var name="one";
function test(){
  var name="two";
  console.log(name); //two
}
test();

函数内省略var的,会影响全局变量,因为它实际上已经被重写成了全局变量

代码如下:
var name="one";
function test(){
  name="two";
}
test();
console.log(name); //two

函数作用域,就是说函数是一个作用域的基本单位,js不像c/c++那样具有块级作用域 比如 if  for 等

代码如下:
function test(){
  for(var i=0;i<10;i++){
    if(i==5){
      var name = "one";
    }
  }
  console.log(name); //one
}
test();  //因为是函数级作用域,所以可以访问到name="one"

当然了,js里边还使用到了高阶函数,其实可以理解成嵌套函数

代码如下:
function test1(){
  var name = "one";
  return function (){
    console.log(name);
  }
}
test1()();

test1()之后将调用外层函数,返回了一个内层函数,再继续(),就相应调用执行了内层函数,所以就输出 ”one"

嵌套函数涉及到了闭包,后面再谈..这里内层函数可以访问到外层函数中声明的变量name,这就涉及到了作用域链机制

2. JS中的声明提前

js中的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。并且,变量在声明之前就可以使用了,这种情况就叫做声明提前(hoisting)

tip:声明提前是在js引擎预编译时就进行了,在代码被执行之前已经有声明提前的现象产生了

比如

代码如下:
var name="one";
function test(){
  console.log(name);  //undefined
  var name="two";
  console.log(name); //two
}
test();

上边就达到了下面的效果

代码如下:
var name="one";
function test(){
  var name;
  console.log(name);  //undefined
  name="two";
  console.log(name); //two
}
test();

再试试把var去掉?这是函数内的name已经变成了全局变量,所以不再是undefined

代码如下:
var name="one";
function test(){
  console.log(name);  //one
  name="two";
  console.log(name); //two

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选