felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

JavaScript 自由变量(free variable) #93

Open felix-cao opened 5 years ago

felix-cao commented 5 years ago

自由变量的定义

在函数内使用了某个变量,却没有在这个函数中声明(即在其他作用域中声明的),对于这个函数来说,这个变量就是一个自由变量。

自由变量(free variable) 与之相对应的是约束变(bound variable)

来看一段代码:

var x = 10;
function foo() {
  var y = 100
  console.log(x+y); // x 在这里就是一个自由变量
}

上面的代码中,在调用 foo() 函数时,函数体中第4行。取 y 的值就直接可以在 foo 作用域中取,因为 y 就是在这里定义的。而取 x 的值时,就需要到另一个作用域中取。到哪个作用域中取呢?要到创建这个函数的那个作用域中取值!

注意:是“创建”,而不是“调用”,其实这就是所谓的“词法作用域”。

var x = 10;
var foo = function() {
   console.log(x);
};

function fn(fun) {
  var x = 100;
  (function() {
     fun();
  })()
}

fn(foo)
chng3 commented 1 year ago

谢谢老师的文章,这里我想谈一下我对第二段代码的理解,不知正确与否,希望能得到老师的解答!

let x = 100;

let foo = function(){
  console.log(x);   // x 为自由变量
}

function fn(fun){
  let x = 10;
  (function(){
    fun();
  })()
}

fn(foo);

在这段代码中,当调用fn()函数并传入foo()函数的引用foo作为参数时,由于fn(fun)函数中嵌套了一个函数,并且这个函数是对foo函数进行调用;在foo函数体中,x为自由变量,当函数被调用时,会创建一个包含全局变量的 x=100 的环境,这就是所谓的词法作用域,所以函数foo被调用之后取x的值就在一个包含自由变量的环境中取,即 x = 100;

felix-cao commented 1 year ago

@dolphinchng 理解正确,重点是理解词法作用域: 代码写好后,还没运行,其变量作用域就已经确定好了的!