js之词法作用域及闭包

一、作用域

我们平常用的作用域叫做词法作用域,词法作用域的内涵是,作用域在词法分析阶段就被确定了(写代码的时候就确定了),也就是说,变量在代码中所处的位置 (而不是运行时所处的位置),决定了作用域。下面介绍作用域分【全局作用域】、【函数作用域】、【块级作用域】、【作用域链】、【闭包】。

看张全景图:

ä½ç¨å

二、全局作用域

全局变量有 全局作用域: 网页中所有脚本和函数均可使用。 

var carName = " Volvo";
 
// 此处可调用 carName 变量
function myFunction() {
    // 函数内可调用 carName 变量
}

上述代码中变量 myFunction 就是在函数外定义的,它是拥有全局作用域的。 

// 此处可调用 carName 变量
 
function myFunction() {
    carName = "Volvo";
    // 此处可调用 carName 变量
}

上述代码:carName它将作为 global 或者 window 的属性存在,在函数或者代码块{}未定义的变量也是拥有全局作用域的,换句话说没有使用 var 定义的变量虽然拥有全局作用域,但是它是可以被 delete 的,而全局变量不可以(这种方式是不推荐)

三、函数作用域

在函数内部定义的变量,就是局部作用域。函数作用域内,对外是封闭的,从外层的作用域无法直接访问函数内部的作用域!

function bar() {
  var testValue = 'inner';
}

console.log(testValue);		// 报错:ReferenceError: testValue is not defined

如果想读取函数内的变量,必须借助 return 或者闭包。如下:

// return方式
function bar(value) {
  var testValue = 'inner';

  return testValue + value;
}

console.log(bar('fun'));// "innerfun"

// 闭包方式
function bar(value) {
  var testValue = 'inner';

  var rusult = testValue + value;

  function innser() {
     return rusult;
  };

  return innser();
}

console.log(bar('fun'));// "innerfun"

四、块级作用域

在 ES6 中,块状作用域得到普及,我们知道"{ }"就够了。

if(true){
  let a = 1
  console.log(a)
}

切记,块级作用域需要{}和let、const合并使用才会生成。

五、作用域链

通俗地讲,当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。

1.当执行函数时,总是先从函数内部找寻局部变量

2.如果内部找不到(函数的局部作用域没有),则会向创建函数的作用域(声明函数的作用域)寻找,依次向上。

上面renturn a+a1+a2+a3,其中a往全局作用域中找,a1往fn1()作用域中找,a2往fn2()作用域中找。

六、闭包

闭包:A函数里面嵌套B函数,B函数使用A函数的变量,那么B函数就是一个闭包。

使用方法:

1.函数里面嵌套函数。

2.函数作为返回值返回。

看例子:

let getPerson;
{
  const id = 1;
  getPerson = () => {
    return getPersonById(id)
   }
  }

document.addEventListener('click', getPerson)

如果没有闭包,当 click 事件发生时,getPerson 就会调用失败。因为变量 id 被定义在块级作用域中, getPerson 在运行时是不可能拿到它的。记住:闭包和函数的第一公民。

发布了70 篇原创文章 · 获赞 13 · 访问量 9733

猜你喜欢

转载自blog.csdn.net/qq_38588845/article/details/105007784