您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

作用域

作用域即片段的有效范围,这里的片段可以是、变量等。

在 JavaScript 中,通常被拿来讨论的是 全局作用域作用域

在全局环境下定义的变量、,都属于全局作用域的范围,也就是这些变量、在任何地方都能被访问。

var number = ;

var fn = function() {
  console.log('我是全局下的');
  console.log('访问全局下的 number: ', number);
};

fn();

全局的作用域很好理解,即全局下的变量、在任何地方都能被访问到。

在 ES6 的模块化规范中,模块就是 js ,所以如果在 ES6 的模块的最顶层声明变量和,是不属于全局的。

拥有自己的作用域,也就是说内声明的变量和,只在内有效。

var fn = function() {
  var innerFn = function() {
    console.log('我是内的');
  };

  var str = '我是内的变量';

  innerFn();
  console.log(str);
};

fn();

console.log(str); // :ReferenceError: str is not defined

内的变量 str 在外部无法访问到,因为其所在的作用域是 fn 的作用域,所以只在 fn 内能被访问。

eval 根据的方式,其作用域也会发生变化。

如果直接 eval 则其作用域就是当前上下文中的作用域。如果间接性质的,比如通过 eval 的引用来,那作用域就是全局的。

var storeEval = eval;

(function() {
  storeEval('var number1 = 1;');
  eval('var number2 = 2');

  console.log('自执行匿名内:', number2);
})();

console.log(number1); // :1
console.log(number2); // :ReferenceError: number2 is not defined

本身 eval 用到的情况就少,所以这种情况下做个了解即可。

理解了作用域,作用域链就很好理解了。

通常情况下,内层作用域拥有访问上层作用域的能力,而外层无法访问到内层的作用域。

var number = ;

var fn = function() {
  console.log(number);

  var str = '字符串';
};

fn();

console.log(str); // :ReferenceError: str is not defined

由此可见作用域从内往外的。

var number1 = ;
var fn1 = function() {
  var number2 = ;

  var fn2 = function() {
    var number3 = ;

    var fn3 = function() {
      console.log('fn3 内的:');
      console.log(number1);
      console.log(number2);
      console.log(number3);
    }

    fn3();
  };

  fn2();
}

fn1();

例子中的 fn3 就具有访问 fn2作用域fn1作用域全局作用域的能力。

这样从内往外就形成了一条作用域链。

作用域最常用的场景之一就是隔离作用域。

因为有自己的作用域,所以很多库、框架在实现的时候都会把写在中。

(function() {
  var con = {};

  var fn = function() {
    // ...
  };

  window.$ = fn;
  window.jQuery = fn;
})();

这样就不会污染到全局,只想要暴露的部分。

有关作用域有更深入的,本篇探讨的是最容易理解的部分。

理解作用域可以更好的组织结构,减少各个上下文的污染。

在 ES6 中引入了块及作用域的概念,这是在之前都没有的,可以查阅 ES6 中对应的进行了解。


联系我
置顶