首页 > 语言 > JavaScript > 正文

js作用域及作用域链概念理解及使用

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

(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}test();

3. 值得注意的是,上面提到的都没有传参数,如果test有参数,又如何呢?

function test(name){ console.log(name); //one name="two"; console.log(name); //two}var name = "one";test(name);console.log(name); // one

之前说过,基本类型是按值传递的,所以传进test里面的name实际上只是一个副本,函数返回之后这个副本就被清除了。

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

图片精选