函数做用域

在es5的语法糖里,只有函数做用域和全局做用域。 所谓函数做用域就是:属于这个函数里的所有变量均可以在整个函数的范围内使用以及复用。举个例子:浏览器

function example(){
  var k = 2
  function insert() {
      console.log(k, 'in example')
  }
  insert()
}
function anotherExample () {
  console.log(k, 'in anotherExample')
}
example() //这里会打印 :2 "in example"
anotherExample() // 这一步浏览器引擎就会报错:Uncaught ReferenceError: k is not defined
复制代码

就像刚才我说的:函数里的变量只能在函数范围内使用,函数之外的范围是不能够访问到的。bash

变量a是在example函数里被定义的。 因为insert函数是在example函数做用范围内,因此它在打印变量k的时候,会先在它本身的函数做用域里找,而后找不到再往它的上一级做用域也就是example函数做用域里去找(这种查找方式也成为做用域链查找),找到了就打印了。函数

可是anotherExample函数在函数example做用范围以外,因此在执行函数的时候,先在本身的做用域找变量k,找不到以后它直接往他的上一级做用域也就是全局做用域上去找,也找不到,因而就会报错了。es5

函数做用域的做用

接下来咱们能够谈一谈函数做用域的用处: 咱们可使用函数做用域把一些变量和函数“隐藏起来”。spa

为何咱们要这样作?设计

一是为了软件设计中提倡一种原则:应该最小限度地暴露出必要内容,而将其余内容都隐藏起来,将变量私有化。code

二是为了规避冲突,避免同名标识符之间的冲突。 例如:作用域

function foo () {
    function bar (a) {
        i = 3
        console.log(i)
    }
    for (var i = 0; i < 10; i++ ){
        bar (i * 2)
    }
}
foo()
复制代码

咱们运行一下以上代码就会发现,进入了无限循坏。 由于在走for循环的时候在里面调用了bar这个函数,bar这个函数又将同名变量i给赋值3,致使循环条件一直是被知足小于10的条件。string

并且若是在咱们的程序中使用第三方库,他们没有很好的将他们的内部变量或者函数私有化,那么可能会和咱们本身命名的变量冲突。it

因此咱们能够是使用函数做用域来规避这些问题。 可是因为函数名自己就污染了他本身所在的做用域,并且要显式地去调用函数才能执行其中代码,因此通常咱们都使用当即执行函数(既能够是匿名又能够在声明的结束以后当即调用)来作变量或者函数的私有化。

例如:

var k = 1;
(function () {
    var k =2 
    console.log(k, 'iife') // 2, iife
}());

console.log(k, 'window') // 1,window
复制代码
相关文章
相关标签/搜索